VirtualFramework/Assets/Scripts/Actions/AnimationAction.cs

237 lines
6.4 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using DG.Tweening;
using System.Collections.Generic;
using System;
using UnityEngine;
using QFramework;
namespace QFramework
{
internal class AnimationAction : IAction
{
public System.Action OnFinished
{
get; set;
}
private AnimationAction()
{
}
private static readonly SimpleObjectPool<AnimationAction> mPool =
new SimpleObjectPool<AnimationAction>(() => new AnimationAction(), null, 10);
string path;
string animName;
Animation anim;
string frame;
string speed;
string deviceName;
float totalTime;
GameObject obj;
public static AnimationAction Allocate(string path, Dictionary<string, string> datas, System.Action OnFinished = null)
{
var retNode = mPool.Allocate();
retNode.ActionID = ActionKit.ID_GENERATOR++;
retNode.Deinited = false;
retNode.Reset();
retNode.path = path;
retNode.animName = datas.ContainsKey("animName") ? datas["animName"] : "";
retNode.frame = datas.ContainsKey("frame") ? datas["frame"] : "";
retNode.speed = datas.ContainsKey("speed") ? datas["speed"] : "";
retNode.deviceName = datas.ContainsKey("deviceName") ? datas["deviceName"] : "";
retNode.OnFinished = OnFinished;
return retNode;
}
public ulong ActionID
{
get; set;
}
public ActionStatus Status
{
get; set;
}
TweenerCore<float, float, FloatOptions> animDot;
public void OnStart()
{
if (string.IsNullOrEmpty(deviceName))
{
obj = Utility.FindObj(path);
}
else
{
obj = DeviceController.Instance.GetDeviceObj(deviceName);
}
if (obj != null)
{
if (obj.activeSelf == false)
{
Debug.LogError(obj.name + "µ±Ç°ÊÇÒþ²Ø×´Ì¬");
this.Finish();
}
else
{
try
{
anim = obj.GetComponent<Animation>();
if (string.IsNullOrEmpty(frame) == false && frame != "-1")
{
int curFrame = 0;
int.TryParse(frame, out curFrame);
anim.clip = anim[animName].clip;
anim[animName].time = curFrame / anim.clip.frameRate;
anim.Play(animName);
anim[animName].speed = 0;
anim.Sample();
this.Finish();
}
else
{
float curSpeed = 1;
if (string.IsNullOrEmpty(speed) == false)
{
float.TryParse(speed, out curSpeed);
}
if (curSpeed < 0)
{
anim.Play(animName);
anim[animName].normalizedTime = 1; // ´Ó¶¯»­Ä©Î²¿ªÊ¼
// ¼ÆËãµ¹²¥ËùÐèʱ¼ä
float duration = anim[animName].length / Math.Abs(curSpeed);
animDot = DOTween.To(
() => anim[animName].normalizedTime,
v => anim[animName].normalizedTime = v,
0, // µ¹²¥µ½¶¯»­¿ªÊ¼
duration
);
animDot.onComplete = () =>
{
anim.Stop();
this.Finish(); // ¹Ø¼üÐ޸ģºÌí¼ÓÍê³Éµ÷ÓÃ
};
totalTime = duration; // ÉèÖÃ×Üʱ¼äΪ¶¯»­²¥·Åʱ³¤
}
else
{
anim[animName].speed = curSpeed;
anim.Play(animName);
totalTime = Math.Abs(anim[animName].length / curSpeed);
// ´¦ÀíÑ­»·¶¯»­
if (anim[animName].wrapMode == WrapMode.Loop)
{
// ʾÀý£ºÑ­»·²¥·Å10Ãëºó½áÊø
totalTime = 10f;
}
}
}
}
catch (Exception)
{
anim = obj.GetComponent<Animation>();
Debug.LogError($"{path} ²¥·Å¶¯»­ {animName} ³ö´í");
this.Finish();
}
}
}
else
{
Debug.LogError("δÕÒµ½Â·¾¶£º" + path);
this.Finish();
}
}
public void OnExecute(float dt)
{
//if (Status != ActionStatus.NotStart) return;
totalTime -= dt;
// ÐÂÔö£º´¦Àíµ¹²¥¶¯»­µÄÍê³É¼ì²â
if (anim != null && animDot != null && !animDot.IsPlaying())
{
this.Finish();
return;
}
if (anim != null)
{
// ·ÇÑ­»·¶¯»­ÅжÏ
if (anim[animName].wrapMode != WrapMode.Loop)
{
if (!anim.isPlaying || totalTime <= 0)
{
this.Finish();
}
}
// Ñ­»·¶¯»­Åжϣ¨»ùÓÚ×Üʱ¼ä£©
else
{
if (totalTime <= 0)
{
anim.Stop(animName);
this.Finish();
}
}
}
else
{
this.Finish();
}
}
public void OnFinish()
{
// Debug.Log("µ÷ÓÃÕâ¸öAnimActionfinish");
OnFinished?.Invoke(); // ´¥·¢Íⲿ»Øµ÷
}
public void Reset()
{
Status = ActionStatus.NotStart;
Paused = false;
}
public bool Paused
{
get; set;
}
public void Deinit()
{
if (!Deinited)
{
if (obj != null && anim != null)
{
anim.Stop();
}
animDot?.Kill();
OnFinished = null;
Deinited = true;
obj = null;
mPool.Recycle(this);
}
}
public bool Deinited
{
get; set;
}
}
}