public void ChangeAnimation(string animationName) { var clip = Clips.FirstOrDefault(c => c.AnimationName == animationName); if (clip == null) { throw new NullReferenceException($"Could not find animation '{animationName}'. Found animations: '{string.Join("', '", Clips.Select(c => c.AnimationName).ToArray())}'."); } var targetAnim = _unityAnimation[animationName]; var time = Time; if (_isPlaying) { if (HasAnimatableControllers()) { targetAnim.time = 0f; targetAnim.enabled = true; targetAnim.weight = 0f; _unityAnimation.Blend(Current.AnimationName, 0f, Current.BlendDuration); _unityAnimation.Blend(animationName, 1f, Current.BlendDuration); } if (Current.AnimationPattern != null) { // Let the loop finish during the transition Current.AnimationPattern.SetBoolParamValue("loopOnce", true); } _previousClip = Current; _blendingTimeLeft = _blendingDuration = Current.BlendDuration; } var previous = Current; Current = clip; _animState = targetAnim; if (_isPlaying) { DetermineNextAnimation(_playTime); if (Current.AnimationPattern != null) { Current.AnimationPattern.SetBoolParamValue("loopOnce", false); Current.AnimationPattern.ResetAndPlay(); } } else { Time = 0f; Sample(); CurrentAnimationChanged.Invoke(new CurrentAnimationChangedEventArgs { Before = previous, After = Current }); } }
public void RebuildAnimation() { if (Current == null) { throw new NullReferenceException("No current animation set"); } var time = Time.Snap(); var sw = Stopwatch.StartNew(); foreach (var clip in Clips) { clip.Validate(); PrepareClipCurves(clip); if (clip.Transition) { var previous = Clips.FirstOrDefault(c => c.NextAnimationName == clip.AnimationName); if (previous != null && (previous.IsDirty() || clip.IsDirty())) { clip.Paste(0f, previous.Copy(previous.animationLength, true), false); } var next = Clips.FirstOrDefault(c => c.AnimationName == clip.NextAnimationName); if (next != null && (next.IsDirty() || clip.IsDirty())) { clip.Paste(clip.animationLength, next.Copy(0f, true), false); } } ReapplyClipCurve(clip); _unityAnimation.AddClip(clip.Clip, clip.AnimationName); var animState = _unityAnimation[clip.AnimationName]; if (animState != null) { animState.layer = _layer; animState.weight = 1; animState.wrapMode = clip.loop ? WrapMode.Loop : WrapMode.Once; animState.speed = _speed; } } if (HasAnimatableControllers()) { // This is a ugly hack, otherwise the scrubber won't work after modifying a frame _unityAnimation.Play(Current.AnimationName); if (!_isPlaying) { _unityAnimation.Stop(Current.AnimationName); } _animState = _unityAnimation[Current.AnimationName]; if (_animState != null) { _animState.time = time; } else { SuperController.LogError($"VamTimeline.{nameof(RebuildAnimation)}: Could not find animation {Current.AnimationName}"); } } else { _animState = null; } if (sw.ElapsedMilliseconds > 1000) { SuperController.LogError($"VamTimeline.{nameof(RebuildAnimation)}: Suspciously long animation rebuild ({sw.Elapsed})"); } }