< Summary

Class:DCL.Components.DCLAnimator
Assembly:DCL.Components.Animation
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Animator/DCLAnimator.cs
Covered lines:76
Uncovered lines:17
Coverable lines:93
Total lines:223
Line coverage:81.7% (76 of 93)
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%110100%
IsEntityShapeLoaded()0%220100%
OnEntityShapeLoaded(...)0%6.975057.14%
OnShapeLoaded(...)0%2100%
Initialize()0%7.017095.24%
UpdateAnimationState()0%12.0912091.3%
ResetAnimation(...)0%3.333066.67%
GetStateByString(...)0%3.033085.71%
GetClassId()0%110100%

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)]
 2224                public float weight = 1f;
 25
 2226                public float speed = 1f;
 2227                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
 1335            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
 1143        Dictionary<string, AnimationClip> clipNameToClip = new Dictionary<string, AnimationClip>();
 1144        Dictionary<AnimationClip, AnimationState> clipToState = new Dictionary<AnimationClip, AnimationState>();
 45
 546        public override string componentName => "animator";
 47
 1648        private void Awake() { model = new Model(); }
 49
 50        private void OnDestroy()
 51        {
 852            entity.OnShapeLoaded -= OnEntityShapeLoaded;
 53
 854            var animationShape = scene.componentsManagerLegacy.GetSharedComponent(entity, (typeof(BaseShape))) as Loadab
 55
 856            if (animationShape != null)
 057                animationShape.OnLoaded -= OnShapeLoaded;
 858        }
 59
 60        public override IEnumerator ApplyChanges(BaseModel model)
 61        {
 1362            entity.OnShapeLoaded -= OnEntityShapeLoaded;
 1363            entity.OnShapeLoaded += OnEntityShapeLoaded;
 64
 65            //Note: If the entity is still loading the Shape, We wait until it is fully loaded to init it
 66            //      If we don't wait, this can cause an issue with the asset bundles not loadings animations
 67
 1368            if (IsEntityShapeLoaded())
 569                UpdateAnimationState();
 70
 1371            return null;
 72        }
 73
 174        new public Model GetModel() { return (Model) model; }
 75
 76        private bool IsEntityShapeLoaded()
 77        {
 1378            var animationShape = scene.componentsManagerLegacy.GetSharedComponent(entity, (typeof(BaseShape))) as Loadab
 79
 1380            if (animationShape == null)
 381                return false;
 82
 1083            return animationShape.isLoaded;
 84        }
 85
 86        private void OnEntityShapeLoaded(IDCLEntity shapeEntity)
 87        {
 588            var animationShape = scene.componentsManagerLegacy.GetSharedComponent(entity, (typeof(BaseShape))) as Loadab
 89
 590            if (animationShape == null)
 091                return;
 92
 593            var shapeModel = animationShape.GetModel() as LoadableShape.Model;
 94
 595            if (shapeModel == null)
 096                return;
 97
 598            if ( shapeModel.src == lastLoadedModelSrc )
 099                return;
 100
 5101            lastLoadedModelSrc = shapeModel.src;
 102
 5103            if ( animationShape.isLoaded )
 104            {
 5105                UpdateAnimationState();
 106            }
 107            else
 108            {
 0109                animationShape.OnLoaded -= OnShapeLoaded;
 0110                animationShape.OnLoaded += OnShapeLoaded;
 111            }
 0112        }
 113
 114        private void OnShapeLoaded(LoadableShape shape)
 115        {
 0116            shape.OnLoaded -= OnShapeLoaded;
 0117            UpdateAnimationState();
 0118        }
 119
 120        private void Initialize()
 121        {
 10122            if (entity == null || animComponent != null)
 4123                return;
 124
 125            //NOTE(Brian): fetch all the AnimationClips in Animation component.
 6126            animComponent = transform.parent.GetComponentInChildren<Animation>(true);
 127
 6128            if (animComponent == null)
 0129                return;
 130
 6131            clipNameToClip.Clear();
 6132            clipToState.Clear();
 6133            int layerIndex = 0;
 134
 6135            animComponent.playAutomatically = true;
 6136            animComponent.enabled = true;
 6137            animComponent.Stop(); //NOTE(Brian): When the GLTF is created by GLTFSceneImporter a frame may be elapsed,
 138            //putting the component in play state if playAutomatically was true at that point.
 6139            animComponent.clip?.SampleAnimation(animComponent.gameObject, 0);
 140
 28141            foreach (AnimationState unityState in animComponent)
 142            {
 8143                clipNameToClip[unityState.clip.name] = unityState.clip;
 144
 8145                unityState.clip.wrapMode = WrapMode.Loop;
 8146                unityState.layer = layerIndex;
 8147                unityState.blendMode = AnimationBlendMode.Blend;
 8148                layerIndex++;
 149            }
 6150        }
 151
 152        void UpdateAnimationState()
 153        {
 10154            Initialize();
 155
 10156            if (clipNameToClip.Count == 0 || animComponent == null)
 0157                return;
 158
 10159            Model model = (Model) this.model;
 160
 10161            if (model.states == null || model.states.Length == 0)
 0162                return;
 163
 48164            for (int i = 0; i < model.states.Length; i++)
 165            {
 14166                Model.DCLAnimationState state = model.states[i];
 167
 14168                if (clipNameToClip.ContainsKey(state.clip))
 169                {
 14170                    AnimationState unityState = animComponent[state.clip];
 14171                    unityState.weight = state.weight;
 14172                    unityState.wrapMode = state.looping ? WrapMode.Loop : WrapMode.Default;
 14173                    unityState.clip.wrapMode = unityState.wrapMode;
 14174                    unityState.speed = state.speed;
 175
 14176                    state.clipReference = unityState.clip;
 177
 14178                    unityState.enabled = state.playing;
 179
 14180                    if (state.shouldReset)
 3181                        ResetAnimation(state);
 182
 183
 14184                    if (state.playing && !animComponent.IsPlaying(state.clip))
 185                    {
 3186                        animComponent.Play(state.clip);
 187                    }
 188                }
 189            }
 10190        }
 191
 192        public void ResetAnimation(Model.DCLAnimationState state)
 193        {
 4194            if (state == null || state.clipReference == null)
 195            {
 0196                Debug.LogError("Clip not found");
 0197                return;
 198            }
 199
 4200            animComponent.Stop(state.clip);
 201
 202            //Manually sample the animation. If the reset is not played again the frame 0 wont be applied
 4203            state.clipReference.SampleAnimation(animComponent.gameObject, 0);
 4204        }
 205
 206        public Model.DCLAnimationState GetStateByString(string stateName)
 207        {
 4208            Model model = (Model) this.model;
 209
 14210            for (var i = 0; i < model.states.Length; i++)
 211            {
 7212                if (model.states[i].name == stateName)
 213                {
 4214                    return model.states[i];
 215                }
 216            }
 217
 0218            return null;
 219        }
 220
 1221        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.ANIMATOR; }
 222    }
 223}