< Summary

Class:DCL.Components.DCLAnimator
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Animator/DCLAnimator.cs
Covered lines:77
Uncovered lines:19
Coverable lines:96
Total lines:224
Line coverage:80.2% (77 of 96)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
DCLAnimationState()0%110100%
Clone()0%2100%
GetDataFromJSON(...)0%110100%
DCLAnimator()0%110100%
Awake()0%110100%
OnDestroy()0%2.032080%
ApplyChanges(...)0%220100%
GetModel()0%2100%
IsEntityShapeLoaded()0%220100%
OnEntityShapeLoaded(...)0%6.65060%
OnShapeLoaded(...)0%2100%
Initialize()0%7.017095.24%
UpdateAnimationState()0%13.0813092.31%
ResetAnimation(...)0%3.333066.67%
GetStateByString(...)0%3.033085.71%
GetClassId()0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Animator/DCLAnimator.cs

#LineLine coverage
 1using DCL.Models;
 2using System.Collections;
 3using System.Collections.Generic;
 4using DCL.Helpers;
 5using UnityEngine;
 6using DCL.Controllers;
 7
 8namespace DCL.Components
 9{
 10    public class DCLAnimator : BaseComponent
 11    {
 12        [System.Serializable]
 13        public class Model : BaseModel
 14        {
 15            [System.Serializable]
 16            public class DCLAnimationState
 17            {
 18                public string name;
 19                public string clip;
 20                public AnimationClip clipReference;
 21                public bool playing;
 22
 23                [Range(0, 1)]
 2024                public float weight = 1f;
 25
 2026                public float speed = 1f;
 2027                public bool looping = true;
 28                public bool shouldReset = false;
 29
 030                public DCLAnimationState Clone() { return (DCLAnimationState) this.MemberwiseClone(); }
 31            }
 32
 33            public DCLAnimationState[] states;
 34
 1135            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 36        }
 37
 38        [System.NonSerialized]
 39        public Animation animComponent = null;
 40
 41        private string lastLoadedModelSrc;
 42
 743        Dictionary<string, AnimationClip> clipNameToClip = new Dictionary<string, AnimationClip>();
 744        Dictionary<AnimationClip, AnimationState> clipToState = new Dictionary<AnimationClip, AnimationState>();
 45
 1246        private void Awake() { model = new Model(); }
 47
 48        private void OnDestroy()
 49        {
 650            entity.OnShapeLoaded -= OnEntityShapeLoaded;
 51
 652            var animationShape = entity.GetSharedComponent(typeof(BaseShape)) as LoadableShape;
 53
 654            if (animationShape != null)
 055                animationShape.OnLoaded -= OnShapeLoaded;
 656        }
 57
 58        public override IEnumerator ApplyChanges(BaseModel model)
 59        {
 1160            entity.OnShapeLoaded -= OnEntityShapeLoaded;
 1161            entity.OnShapeLoaded += OnEntityShapeLoaded;
 62
 63            //Note: If the entity is still loading the Shape, We wait until it is fully loaded to init it
 64            //      If we don't wait, this can cause an issue with the asset bundles not loadings animations
 65
 1166            if (IsEntityShapeLoaded())
 467                UpdateAnimationState();
 68
 1169            return null;
 70        }
 71
 072        new public Model GetModel() { return (Model) model; }
 73
 74        private bool IsEntityShapeLoaded()
 75        {
 1176            var animationShape = entity.GetSharedComponent(typeof(BaseShape)) as LoadableShape;
 77
 1178            if (animationShape == null)
 279                return false;
 80
 981            return animationShape.isLoaded;
 82        }
 83
 84        private void OnEntityShapeLoaded(IDCLEntity shapeEntity)
 85        {
 586            var animationShape = shapeEntity.GetSharedComponent(typeof(BaseShape)) as LoadableShape;
 87
 588            if (animationShape == null)
 089                return;
 90
 591            var shapeModel = animationShape.GetModel() as LoadableShape.Model;
 92
 593            if (shapeModel == null)
 094                return;
 95
 596            if ( shapeModel.src == lastLoadedModelSrc )
 097                return;
 98
 599            lastLoadedModelSrc = shapeModel.src;
 100
 5101            if ( animationShape.isLoaded )
 102            {
 5103                UpdateAnimationState();
 5104            }
 105            else
 106            {
 0107                animationShape.OnLoaded -= OnShapeLoaded;
 0108                animationShape.OnLoaded += OnShapeLoaded;
 109            }
 0110        }
 111
 112        private void OnShapeLoaded(LoadableShape shape)
 113        {
 0114            shape.OnLoaded -= OnShapeLoaded;
 0115            UpdateAnimationState();
 0116        }
 117
 118        private void Initialize()
 119        {
 9120            if (entity == null || animComponent != null)
 4121                return;
 122
 123            //NOTE(Brian): fetch all the AnimationClips in Animation component.
 5124            animComponent = transform.parent.GetComponentInChildren<Animation>(true);
 125
 5126            if (animComponent == null)
 0127                return;
 128
 5129            clipNameToClip.Clear();
 5130            clipToState.Clear();
 5131            int layerIndex = 0;
 132
 5133            animComponent.playAutomatically = true;
 5134            animComponent.enabled = true;
 5135            animComponent.Stop(); //NOTE(Brian): When the GLTF is created by GLTFSceneImporter a frame may be elapsed,
 136            //putting the component in play state if playAutomatically was true at that point.
 5137            animComponent.clip?.SampleAnimation(animComponent.gameObject, 0);
 138
 24139            foreach (AnimationState unityState in animComponent)
 140            {
 7141                clipNameToClip[unityState.clip.name] = unityState.clip;
 142
 7143                unityState.clip.wrapMode = WrapMode.Loop;
 7144                unityState.layer = layerIndex;
 7145                unityState.blendMode = AnimationBlendMode.Blend;
 7146                layerIndex++;
 147            }
 5148        }
 149
 150        void UpdateAnimationState()
 151        {
 9152            Initialize();
 153
 9154            if (clipNameToClip.Count == 0 || animComponent == null)
 0155                return;
 156
 9157            Model model = (Model) this.model;
 158
 9159            if (model.states == null || model.states.Length == 0)
 0160                return;
 161
 44162            for (int i = 0; i < model.states.Length; i++)
 163            {
 13164                Model.DCLAnimationState state = model.states[i];
 165
 13166                if (clipNameToClip.ContainsKey(state.clip))
 167                {
 13168                    AnimationState unityState = animComponent[state.clip];
 13169                    unityState.weight = state.weight;
 13170                    unityState.wrapMode = state.looping ? WrapMode.Loop : WrapMode.Default;
 13171                    unityState.clip.wrapMode = unityState.wrapMode;
 13172                    unityState.speed = state.speed;
 173
 13174                    state.clipReference = unityState.clip;
 175
 13176                    if (state.shouldReset)
 3177                        ResetAnimation(state);
 178
 13179                    if (state.playing)
 180                    {
 11181                        if (!animComponent.IsPlaying(state.clip))
 10182                            animComponent.Play(state.clip);
 10183                    }
 184                    else
 185                    {
 2186                        if (animComponent.IsPlaying(state.clip))
 1187                            animComponent.Stop(state.clip);
 188                    }
 189                }
 190            }
 9191        }
 192
 193        public void ResetAnimation(Model.DCLAnimationState state)
 194        {
 4195            if (state == null || state.clipReference == null)
 196            {
 0197                Debug.LogError("Clip not found");
 0198                return;
 199            }
 200
 4201            animComponent.Stop(state.clip);
 202
 203            //Manually sample the animation. If the reset is not played again the frame 0 wont be applied
 4204            state.clipReference.SampleAnimation(animComponent.gameObject, 0);
 4205        }
 206
 207        public Model.DCLAnimationState GetStateByString(string stateName)
 208        {
 4209            Model model = (Model) this.model;
 210
 14211            for (var i = 0; i < model.states.Length; i++)
 212            {
 7213                if (model.states[i].name == stateName)
 214                {
 4215                    return model.states[i];
 216                }
 217            }
 218
 0219            return null;
 220        }
 221
 0222        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.ANIMATOR; }
 223    }
 224}