Browse Source

Merge pull request #4342 from RaananW/animationGroup-stuff

Animation group fixes
David Catuhe 7 năm trước cách đây
mục cha
commit
4f08f0b020

+ 1 - 0
dist/preview release/what's new.md

@@ -19,6 +19,7 @@
 - Added webVR constructor options: disable laser pointer toggle, teleportation floor meshes ([TrevorDev](https://github.com/TrevorDev))
 - Get a root mesh from an asset container, load a mesh from a file with a single string url ([TrevorDev](https://github.com/TrevorDev))
 - UtilityLayer class to render another scene as a layer on top of an existing scene ([TrevorDev](https://github.com/TrevorDev))
+- AnimationGroup has now onAnimationGroupEnd observable ([RaananW](https://github.com/RaananW))
 
 ### glTF Loader
 

+ 1 - 3
src/Animations/babylon.animatable.ts

@@ -195,7 +195,7 @@
             this._paused = false;
         }
 
-        private _raiseOnAnimationEnd() {            
+        private _raiseOnAnimationEnd() {
             if (this.onAnimationEnd) {
                 this.onAnimationEnd();
             }
@@ -299,9 +299,7 @@
                 for (index = 0; index < runtimeAnimations.length; index++) {
                     runtimeAnimations[index].dispose();
                 }
-            }
 
-            if (!running) {
                 this._raiseOnAnimationEnd();
                 this.onAnimationEnd = null
                 this.onAnimationEndObservable.clear();

+ 28 - 4
src/Animations/babylon.animationGroup.ts

@@ -23,12 +23,17 @@ module BABYLON {
         public onAnimationEndObservable = new Observable<TargetedAnimation>();
 
         /**
+         * This observable will notify when all animations have ended.
+         */
+        public onAnimationGroupEndObservable = new Observable<AnimationGroup>();
+
+        /**
          * Gets the first frame
          */
         public get from(): number {
             return this._from;
         }
-        
+
         /**
          * Gets the last frame
          */
@@ -171,9 +176,12 @@ module BABYLON {
             }
 
             for (const targetedAnimation of this._targetedAnimations) {
-                this._animatables.push(this._scene.beginDirectAnimation(targetedAnimation.target, [targetedAnimation.animation], from !== undefined ? from : this._from, to !== undefined ? to : this._to, loop, speedRatio, () => {
+                let animatable = this._scene.beginDirectAnimation(targetedAnimation.target, [targetedAnimation.animation], from !== undefined ? from : this._from, to !== undefined ? to : this._to, loop, speedRatio);
+                animatable.onAnimationEnd = () => {
                     this.onAnimationEndObservable.notifyObservers(targetedAnimation);
-                }));
+                    this._checkAnimationGroupEnded(animatable);
+                }
+                this._animatables.push(animatable);
             }
 
             this._speedRatio = speedRatio;
@@ -205,7 +213,8 @@ module BABYLON {
          * @param loop defines if animations must loop
          */
         public play(loop?: boolean): AnimationGroup {
-            if (this.isStarted) {
+            // only if all animatables are ready and exist
+            if (this.isStarted && this._animatables.length === this._targetedAnimations.length) {
                 if (loop !== undefined) {
                     for (var index = 0; index < this._animatables.length; index++) {
                         let animatable = this._animatables[index];
@@ -214,6 +223,7 @@ module BABYLON {
                 }
                 this.restart();
             } else {
+                this.stop();
                 this.start(loop, this._speedRatio);
             }
 
@@ -331,5 +341,19 @@ module BABYLON {
                 this._scene.animationGroups.splice(index, 1);
             }
         }
+
+        private _checkAnimationGroupEnded(animatable: Animatable) {
+            // animatable should be taken out of the array
+            let idx = this._animatables.indexOf(animatable);
+            if (idx > -1) {
+                this._animatables.splice(idx, 1);
+            }
+
+            // all animatables were removed? animation group ended!
+            if (this._animatables.length === 0) {
+                this._isStarted = false;
+                this.onAnimationGroupEndObservable.notifyObservers(this);
+            }
+        }
     }
 }