< 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:75
Uncovered lines:18
Coverable lines:93
Total lines:221
Line coverage:80.6% (75 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%220100%
ApplyChanges(...)0%220100%
GetModel()0%2100%
IsEntityShapeLoaded()0%220100%
OnEntityShapeLoaded(...)0%6.65060%
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%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)
 555                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                    unityState.enabled = state.playing;
 177
 13178                    if (state.shouldReset)
 3179                        ResetAnimation(state);
 180
 181
 13182                    if (state.playing && !animComponent.IsPlaying(state.clip))
 183                    {
 3184                        animComponent.Play(state.clip);
 185                    }
 186                }
 187            }
 9188        }
 189
 190        public void ResetAnimation(Model.DCLAnimationState state)
 191        {
 4192            if (state == null || state.clipReference == null)
 193            {
 0194                Debug.LogError("Clip not found");
 0195                return;
 196            }
 197
 4198            animComponent.Stop(state.clip);
 199
 200            //Manually sample the animation. If the reset is not played again the frame 0 wont be applied
 4201            state.clipReference.SampleAnimation(animComponent.gameObject, 0);
 4202        }
 203
 204        public Model.DCLAnimationState GetStateByString(string stateName)
 205        {
 4206            Model model = (Model) this.model;
 207
 14208            for (var i = 0; i < model.states.Length; i++)
 209            {
 7210                if (model.states[i].name == stateName)
 211                {
 4212                    return model.states[i];
 213                }
 214            }
 215
 0216            return null;
 217        }
 218
 0219        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.ANIMATOR; }
 220    }
 221}