654 lines
22 KiB
C#
654 lines
22 KiB
C#
|
using UnityEngine;
|
|||
|
#if UNITY_EDITOR
|
|||
|
using UnityEditor;
|
|||
|
#endif
|
|||
|
using System.Collections.Generic;
|
|||
|
using System;
|
|||
|
using System.IO;
|
|||
|
|
|||
|
namespace Thousandto.Cinematic
|
|||
|
{
|
|||
|
//剧情对象
|
|||
|
[Serializable]
|
|||
|
public class CinematicObj : ICinematic
|
|||
|
{
|
|||
|
public int EventType = 0;
|
|||
|
public List<CinematicKeyframe> KeyframeList;
|
|||
|
public string Name;
|
|||
|
public int CurFrame = -1;
|
|||
|
|
|||
|
//帧率
|
|||
|
public int FrameRate = 30;
|
|||
|
public bool IsCamera;
|
|||
|
public int CameraDepth = 10;
|
|||
|
public int LayMask = 1;
|
|||
|
public bool IsFollowCamera = false;
|
|||
|
|
|||
|
[NonSerialized]
|
|||
|
public Vector3[] PathV3Array;
|
|||
|
[NonSerialized]
|
|||
|
public GameObject GameObject;
|
|||
|
[NonSerialized]
|
|||
|
public Animation Animation;
|
|||
|
[NonSerialized]
|
|||
|
public Action RefreshAction;
|
|||
|
|
|||
|
//是否场景里面的物件,这种物件是不能销毁的
|
|||
|
[NonSerialized]
|
|||
|
private bool _isSceneObj = false;
|
|||
|
//当前是camera,只有等到第一个有事件的帧才能显现出来
|
|||
|
[NonSerialized]
|
|||
|
private bool _isCameraCanShow = true;
|
|||
|
//包含位移的关键帧
|
|||
|
[NonSerialized]
|
|||
|
public List<CinematicKeyframe> TransKeyframeList;
|
|||
|
//关键帧图片宽度
|
|||
|
private int _keyFrameIconWidth = 15;
|
|||
|
[NonSerialized]
|
|||
|
public Dictionary<int, CinematicKeyframe> KeyframeDict;
|
|||
|
|
|||
|
public override void WriteAll(BinaryWriter bw)
|
|||
|
{
|
|||
|
//写入顺序必须按照上面成员定义的顺序,读取亦然
|
|||
|
PrepareWriter(bw);
|
|||
|
WriteInt(EventType);
|
|||
|
WriteList(KeyframeList);
|
|||
|
WriteString(Name);
|
|||
|
WriteInt(CurFrame);
|
|||
|
WriteInt(FrameRate);
|
|||
|
WriteBool(IsCamera);
|
|||
|
WriteInt(CameraDepth);
|
|||
|
WriteInt(LayMask);
|
|||
|
WriteV3Array(PathV3Array);
|
|||
|
}
|
|||
|
|
|||
|
public override void ReadAll(BinaryReader rd)
|
|||
|
{
|
|||
|
PrepareReader(rd);
|
|||
|
EventType = ReadInt();
|
|||
|
KeyframeList = ReadList<CinematicKeyframe>();
|
|||
|
Name = ReadString();
|
|||
|
CurFrame =ReadInt();
|
|||
|
FrameRate = ReadInt();
|
|||
|
IsCamera = ReadBool();
|
|||
|
CameraDepth = ReadInt();
|
|||
|
if (CameraDepth < 10)
|
|||
|
CameraDepth = 10;
|
|||
|
LayMask = ReadInt();
|
|||
|
PathV3Array = ReadV3Array();
|
|||
|
}
|
|||
|
|
|||
|
public CinematicObj()
|
|||
|
{
|
|||
|
KeyframeList = new List<CinematicKeyframe>();
|
|||
|
TransKeyframeList = new List<CinematicKeyframe>();
|
|||
|
Name = GetType().Name;
|
|||
|
}
|
|||
|
|
|||
|
public CinematicObj(string name)
|
|||
|
{
|
|||
|
KeyframeList = new List<CinematicKeyframe>();
|
|||
|
TransKeyframeList = new List<CinematicKeyframe>();
|
|||
|
Name = name;
|
|||
|
InitGameObject();
|
|||
|
}
|
|||
|
|
|||
|
//保存之前,调用一次这个函数
|
|||
|
public void SortKeyframe()
|
|||
|
{
|
|||
|
KeyframeList.Sort((a, b) => { return a.Keyframe - b.Keyframe; });
|
|||
|
KeyframeDict = new Dictionary<int, CinematicKeyframe>();
|
|||
|
for (int i = 0; i < KeyframeList.Count; ++i)
|
|||
|
{
|
|||
|
if (i - 1 >= 0)
|
|||
|
KeyframeList[i].PreEventData = KeyframeList[i - 1];
|
|||
|
else
|
|||
|
KeyframeList[i].PreEventData = null;
|
|||
|
|
|||
|
if (i + 1 < KeyframeList.Count)
|
|||
|
KeyframeList[i].NextKeyframe = KeyframeList[i + 1];
|
|||
|
else
|
|||
|
KeyframeList[i].NextKeyframe = null;
|
|||
|
|
|||
|
KeyframeDict.Add(KeyframeList[i].Keyframe, KeyframeList[i]);
|
|||
|
|
|||
|
KeyframeList[i].RemoveTransEventWhileHasSyncEvent();
|
|||
|
|
|||
|
//runtime 使用
|
|||
|
for(int m = 0; m < KeyframeList[i].EventData.Count; ++m)
|
|||
|
{
|
|||
|
if(KeyframeList[i].EventData[m].EventTypeEx == KeyFrameEvent.坐标变换)
|
|||
|
{
|
|||
|
KeyframeList[i].TransformEvent = KeyframeList[i].EventData[m];
|
|||
|
TransKeyframeList.Add(KeyframeList[i]);
|
|||
|
}
|
|||
|
if(KeyframeList[i].EventData[m].EventTypeEx == KeyFrameEvent.同步到本地相机坐标 ||
|
|||
|
KeyframeList[i].EventData[m].EventTypeEx == KeyFrameEvent.同步到本地角色坐标)
|
|||
|
{
|
|||
|
KeyframeList[i].HasSyncTrans = true;
|
|||
|
}
|
|||
|
if(KeyframeList[i].EventData[m].EventTypeEx == KeyFrameEvent.播放动作)
|
|||
|
{
|
|||
|
KeyframeList[i].AnimEvent = KeyframeList[i].EventData[m];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//给当前帧赋值下一个含有位移的关键帧
|
|||
|
for (int n = 1; n < KeyframeList.Count; ++n)
|
|||
|
{
|
|||
|
var curKeyframe = KeyframeList[n - 1];
|
|||
|
curKeyframe.NextTransKeyframe = null;
|
|||
|
var nextKeyframe = KeyframeList[n];
|
|||
|
while (nextKeyframe != null)
|
|||
|
{
|
|||
|
if (nextKeyframe.TransformEvent != null)
|
|||
|
{
|
|||
|
curKeyframe.NextTransKeyframe = nextKeyframe;
|
|||
|
break;
|
|||
|
}
|
|||
|
nextKeyframe = nextKeyframe.NextKeyframe;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public CinematicKeyframe GetKeyframeData(int frame)
|
|||
|
{
|
|||
|
InitDicData();
|
|||
|
|
|||
|
CinematicKeyframe ret = null;
|
|||
|
KeyframeDict.TryGetValue(frame, out ret);
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
private void InitDicData()
|
|||
|
{
|
|||
|
if(KeyframeDict == null)
|
|||
|
{
|
|||
|
KeyframeDict = new Dictionary<int, CinematicKeyframe>();
|
|||
|
for (int i = 0; i < KeyframeList.Count; ++i)
|
|||
|
{
|
|||
|
if (i - 1 >= 0)
|
|||
|
KeyframeList[i].PreEventData = KeyframeList[i - 1];
|
|||
|
else
|
|||
|
KeyframeList[i].PreEventData = null;
|
|||
|
|
|||
|
if (i + 1 < KeyframeList.Count)
|
|||
|
KeyframeList[i].NextKeyframe = KeyframeList[i + 1];
|
|||
|
else
|
|||
|
KeyframeList[i].NextKeyframe = null;
|
|||
|
|
|||
|
KeyframeDict.Add(KeyframeList[i].Keyframe, KeyframeList[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public CinematicKeyframe GetPreTransKeyframeData(int frame)
|
|||
|
{
|
|||
|
CinematicKeyframe ret = null;
|
|||
|
for(int i = KeyframeList.Count - 1; i >= 0; --i)
|
|||
|
{
|
|||
|
if(KeyframeList[i].Keyframe < frame && KeyframeList[i].GetTransEvent() != null)
|
|||
|
{
|
|||
|
ret = KeyframeList[i];
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
public CinematicKeyframe GetPreAnimKeyframeData(int frame)
|
|||
|
{
|
|||
|
CinematicKeyframe ret = null;
|
|||
|
for (int i = KeyframeList.Count - 1; i >= 0; --i)
|
|||
|
{
|
|||
|
if (KeyframeList[i].Keyframe < frame && KeyframeList[i].GetAnimEvent() != null)
|
|||
|
{
|
|||
|
ret = KeyframeList[i];
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
public bool ExistFrame(int frame, out CinematicKeyframe keyFrameData)
|
|||
|
{
|
|||
|
keyFrameData = null;
|
|||
|
for (int i = 0; i < KeyframeList.Count; ++i)
|
|||
|
{
|
|||
|
if (KeyframeList[i].Keyframe == frame)
|
|||
|
{
|
|||
|
keyFrameData = KeyframeList[i];
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public bool ExistFrame(int frame)
|
|||
|
{
|
|||
|
for (int i = 0; i < KeyframeList.Count; ++i)
|
|||
|
{
|
|||
|
if (KeyframeList[i].Keyframe == frame)
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public void AddEvent(int frame, KeyFrameEvent e)
|
|||
|
{
|
|||
|
CinematicKeyframe eData;
|
|||
|
if(ExistFrame(frame, out eData))
|
|||
|
{
|
|||
|
eData.AddEvent(new CinematicEventData(e));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool IsEndFrame(int frame)
|
|||
|
{
|
|||
|
if (KeyframeList == null || KeyframeList.Count == 0) return true;
|
|||
|
|
|||
|
return KeyframeList[KeyframeList.Count - 1].Keyframe <= frame;
|
|||
|
}
|
|||
|
|
|||
|
//添加关键帧
|
|||
|
public CinematicKeyframe AddFrame(int frame)
|
|||
|
{
|
|||
|
CinematicKeyframe keyFrameData;
|
|||
|
if (ExistFrame(frame, out keyFrameData))
|
|||
|
{
|
|||
|
keyFrameData.SetData(frame);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
keyFrameData = new CinematicKeyframe();
|
|||
|
keyFrameData.SetData(frame);
|
|||
|
|
|||
|
KeyframeList.Add(keyFrameData);
|
|||
|
}
|
|||
|
|
|||
|
keyFrameData.Selected = true;
|
|||
|
|
|||
|
CurFrame = frame;
|
|||
|
|
|||
|
return keyFrameData;
|
|||
|
}
|
|||
|
|
|||
|
//移除关键帧
|
|||
|
public void RemoveFrame(int frame)
|
|||
|
{
|
|||
|
CinematicKeyframe keyFrameData = null;
|
|||
|
if (ExistFrame(frame, out keyFrameData))
|
|||
|
{
|
|||
|
KeyframeList.Remove(keyFrameData);
|
|||
|
keyFrameData.OnRefreshEditor(true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//复制关键帧
|
|||
|
public List<CinematicEventData> CopyFrameData(int frame)
|
|||
|
{
|
|||
|
CinematicKeyframe keyFrameData;
|
|||
|
List<CinematicEventData> retList = new List<CinematicEventData>();
|
|||
|
if (!ExistFrame(frame, out keyFrameData)) return retList;
|
|||
|
|
|||
|
retList = keyFrameData.CloneEventData();
|
|||
|
return retList;
|
|||
|
}
|
|||
|
|
|||
|
//粘贴关键帧
|
|||
|
public void PasteFrameData(int frame, List<CinematicEventData> eData)
|
|||
|
{
|
|||
|
CinematicKeyframe keyFrameData;
|
|||
|
if (ExistFrame(frame, out keyFrameData))
|
|||
|
{
|
|||
|
keyFrameData.SetData(frame, eData);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
keyFrameData = new CinematicKeyframe();
|
|||
|
keyFrameData.SetData(frame, eData);
|
|||
|
KeyframeList.Add(keyFrameData);
|
|||
|
}
|
|||
|
keyFrameData.Selected = true;
|
|||
|
|
|||
|
CurFrame = frame;
|
|||
|
}
|
|||
|
|
|||
|
public void ClearSelectState()
|
|||
|
{
|
|||
|
for(int i = 0; i < KeyframeList.Count; ++i)
|
|||
|
{
|
|||
|
KeyframeList[i].Selected = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void SetSelectState(int frame)
|
|||
|
{
|
|||
|
CinematicKeyframe keyFrameData;
|
|||
|
if(ExistFrame(frame, out keyFrameData))
|
|||
|
{
|
|||
|
keyFrameData.SetSelected();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void MoveFrameWhileDrag(int deltaFrame)
|
|||
|
{
|
|||
|
for(int i = 0; i < KeyframeList.Count; ++i)
|
|||
|
{
|
|||
|
if(KeyframeList[i].Selected)
|
|||
|
{
|
|||
|
KeyframeList[i].Keyframe += deltaFrame;
|
|||
|
if(KeyframeList[i].Keyframe < 0)
|
|||
|
{
|
|||
|
KeyframeList[i].Keyframe = 0;
|
|||
|
}
|
|||
|
|
|||
|
KeyframeList[i].OnRefreshEditor();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ResetTransState();
|
|||
|
SortKeyframe();
|
|||
|
|
|||
|
RefreshEditorData();
|
|||
|
}
|
|||
|
|
|||
|
public void RefreshEditorData()
|
|||
|
{
|
|||
|
if (RefreshAction != null) RefreshAction();
|
|||
|
}
|
|||
|
|
|||
|
static Vector3 CalculateLinearVector(Vector3 start, Vector3 end, float t, float t2)
|
|||
|
{
|
|||
|
float distance = (end - start).magnitude;
|
|||
|
Vector3 deltaV3 = end - start;
|
|||
|
Vector3 dir = (end - start).normalized;
|
|||
|
Vector3 newStart = start + (dir * distance / (t)) * t2;
|
|||
|
return newStart;
|
|||
|
}
|
|||
|
|
|||
|
static Quaternion CalculateLinearQuaternion(Quaternion from, Quaternion to, float t, float t2)
|
|||
|
{
|
|||
|
return Quaternion.Slerp(from, to, (1f / (t)) * t2);
|
|||
|
}
|
|||
|
|
|||
|
#region runtime
|
|||
|
|
|||
|
[NonSerialized]
|
|||
|
private bool _hasNextTransform = true;
|
|||
|
[NonSerialized]
|
|||
|
private CinematicEventData _nextTransEvent;
|
|||
|
[NonSerialized]
|
|||
|
private List<GameObject> _childrenGO;
|
|||
|
|
|||
|
public void Prepare()
|
|||
|
{
|
|||
|
SortKeyframe();
|
|||
|
ResetTransState();
|
|||
|
InitGameObject();
|
|||
|
}
|
|||
|
|
|||
|
public void ResetTransState()
|
|||
|
{
|
|||
|
_nextTransEvent = null;
|
|||
|
_hasNextTransform = true;
|
|||
|
}
|
|||
|
|
|||
|
public void InitGameObject()
|
|||
|
{
|
|||
|
if (GameObject == null)
|
|||
|
{
|
|||
|
_childrenGO = new List<GameObject>();
|
|||
|
GameObject = new GameObject(Name);
|
|||
|
GameObject.transform.parent = CinematicManager.RootGo.transform;
|
|||
|
|
|||
|
if(IsCamera)
|
|||
|
{
|
|||
|
GameObject.name = "Camera";
|
|||
|
var camera = GameObject.AddComponent<Camera>();
|
|||
|
camera.depth = CameraDepth;
|
|||
|
camera.cullingMask = LayMask;
|
|||
|
GameObject.SetActive(false);
|
|||
|
_isCameraCanShow = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR //编辑器下描绘曲线
|
|||
|
var script = GameObject.AddComponent<Plugin.CinematicUI_Curve>();
|
|||
|
script.CinematicObj = this;
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void SetCameraLayerMask(int layerMask)
|
|||
|
{
|
|||
|
LayMask = layerMask;
|
|||
|
if (GameObject == null) return;
|
|||
|
|
|||
|
Camera camera = GameObject.GetComponent<Camera>();
|
|||
|
if(camera != null)
|
|||
|
{
|
|||
|
camera.cullingMask = LayMask;
|
|||
|
camera.depth = CameraDepth;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void ClearChild()
|
|||
|
{
|
|||
|
if (_childrenGO == null) return;
|
|||
|
|
|||
|
for(int i = 0; i < _childrenGO.Count; ++i)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
GameObject.DestroyImmediate(_childrenGO[i]);
|
|||
|
#else
|
|||
|
GameObject.Destroy(_childrenGO[i]);
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
_childrenGO.Clear();
|
|||
|
}
|
|||
|
|
|||
|
public void Destory()
|
|||
|
{
|
|||
|
|
|||
|
if (GameObject != null && !_isSceneObj)
|
|||
|
{
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
GameObject.DestroyImmediate(GameObject);
|
|||
|
#else
|
|||
|
GameObject.Destroy(GameObject);
|
|||
|
#endif
|
|||
|
}
|
|||
|
if(_childrenGO != null) _childrenGO.Clear();
|
|||
|
}
|
|||
|
|
|||
|
public void LoadPrefab(string param, string editorParam, bool isLocalPlayer = false)
|
|||
|
{
|
|||
|
_isSceneObj = false;
|
|||
|
ClearChild();
|
|||
|
{
|
|||
|
UnityEngine.Debug.LogWarning("Use editor load prefab!!!");
|
|||
|
//if (CinematicObjManager.IsEditorPreview && !string.IsNullOrEmpty(editorParam))
|
|||
|
{
|
|||
|
GameObject go = GameObject.Instantiate(Resources.Load<GameObject>(editorParam)) as GameObject;
|
|||
|
go.transform.parent = GameObject.transform;
|
|||
|
|
|||
|
go.transform.localPosition = Vector3.zero;
|
|||
|
go.transform.localScale = Vector3.one;
|
|||
|
go.transform.localRotation = Quaternion.identity;
|
|||
|
_childrenGO.Add(go);
|
|||
|
|
|||
|
Animation = go.GetComponent<Animation>();
|
|||
|
|
|||
|
//return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void LoadPrefabFromScene(string nodeFullPath)
|
|||
|
{
|
|||
|
//不做clear,可能会删除掉场景中的物件
|
|||
|
//ClearChild();
|
|||
|
_isSceneObj = true;
|
|||
|
GameObject = GameObject.Find(nodeFullPath);
|
|||
|
Animation = GameObject.GetComponent<Animation>();
|
|||
|
}
|
|||
|
|
|||
|
public void SetTransform(CinematicEventData data)
|
|||
|
{
|
|||
|
if (GameObject == null) return;
|
|||
|
SetCameraVisiable();
|
|||
|
GameObject.transform.localPosition = data.Position;
|
|||
|
GameObject.transform.localScale = data.Scale;
|
|||
|
GameObject.transform.localRotation = Quaternion.Euler(data.Rotation);
|
|||
|
}
|
|||
|
|
|||
|
public void SetCameraVisiable()
|
|||
|
{
|
|||
|
if (IsCamera && !_isCameraCanShow)
|
|||
|
{
|
|||
|
GameObject.SetActive(true);
|
|||
|
_isCameraCanShow = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//曲线变换
|
|||
|
public void SetTransformCurveTo(CinematicEventData preTransData, CinematicKeyframe curKeyframe, float preKeyframe, float deltaFrame)
|
|||
|
{
|
|||
|
if (IsCamera && !_isCameraCanShow)
|
|||
|
{
|
|||
|
GameObject.SetActive(true);
|
|||
|
_isCameraCanShow = true;
|
|||
|
}
|
|||
|
|
|||
|
var nextKeyframe = deltaFrame > 0 ? curKeyframe.NextTransKeyframe: curKeyframe.PreEventData;
|
|||
|
if (!_hasNextTransform || nextKeyframe == null || GameObject == null) return;
|
|||
|
_nextTransEvent = nextKeyframe.TransformEvent;
|
|||
|
float durationFame = nextKeyframe.Keyframe - preKeyframe;
|
|||
|
|
|||
|
if (durationFame > 0)
|
|||
|
{
|
|||
|
if (deltaFrame < 0) deltaFrame = durationFame + deltaFrame;
|
|||
|
//路点小于2,用线性差值 或者不使用曲线
|
|||
|
if (PathV3Array.Length < 2 || !curKeyframe.TransformEvent.UseCurve)
|
|||
|
{
|
|||
|
GameObject.transform.localPosition = CalculateLinearVector(preTransData.Position, _nextTransEvent.Position, durationFame, deltaFrame);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//去掉曲线影响,相同的两个点还会产生位移的情况
|
|||
|
if (curKeyframe.TransformEvent.Position == nextKeyframe.TransformEvent.Position)
|
|||
|
{
|
|||
|
GameObject.transform.localPosition = curKeyframe.TransformEvent.Position;
|
|||
|
curKeyframe.TransPercentageInCurve = nextKeyframe.TransPercentageInCurve;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//偏移量/活动区间 = 该区域移动百分比
|
|||
|
float percent = (deltaFrame / durationFame) * (nextKeyframe.TransPercentageInCurve - curKeyframe.TransPercentageInCurve) + curKeyframe.TransPercentageInCurve;
|
|||
|
|
|||
|
Vector3 curvPos = CinematicSerialize.Interp(PathV3Array, percent);
|
|||
|
//Vector3 newDir = (curvPos - GameObject.transform.localPosition);
|
|||
|
//newDir.y = 0;
|
|||
|
//GameObject.transform.forward = newDir;
|
|||
|
GameObject.transform.localPosition = curvPos;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
GameObject.transform.localScale = CalculateLinearVector(preTransData.Scale, _nextTransEvent.Scale, durationFame, deltaFrame);
|
|||
|
GameObject.transform.localRotation = CalculateLinearQuaternion(Quaternion.Euler(preTransData.Rotation), Quaternion.Euler(_nextTransEvent.Rotation), durationFame, deltaFrame);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//线性变换
|
|||
|
public void SetTransform(CinematicEventData fromTrans, CinematicEventData toTrans, float durationFrame, float deltaFrame)
|
|||
|
{
|
|||
|
if (GameObject == null || fromTrans == null || toTrans == null || durationFrame == 0) return;
|
|||
|
GameObject.transform.localPosition = CalculateLinearVector(fromTrans.Position, toTrans.Position, durationFrame, deltaFrame);
|
|||
|
GameObject.transform.localScale = CalculateLinearVector(fromTrans.Scale, toTrans.Scale, durationFrame, deltaFrame);
|
|||
|
GameObject.transform.localRotation = CalculateLinearQuaternion(Quaternion.Euler(fromTrans.Rotation), Quaternion.Euler(toTrans.Rotation), durationFrame, deltaFrame);
|
|||
|
}
|
|||
|
|
|||
|
//播放动作,支持逐帧播放
|
|||
|
public void PlayAnimationByFrame(CinematicEventData eventData, int keyframe, float curFrame)
|
|||
|
{
|
|||
|
if (Animation != null && eventData != null && curFrame >= keyframe && eventData.IsLocalPlayer)
|
|||
|
{
|
|||
|
var animEvent = eventData;
|
|||
|
if (Animation[animEvent.Param] != null)
|
|||
|
{
|
|||
|
{
|
|||
|
float durationFame = curFrame - keyframe;
|
|||
|
AnimationState state = Animation[animEvent.Param];
|
|||
|
AnimationClip clip = Animation.GetClip(animEvent.Param);
|
|||
|
float length = state.length;
|
|||
|
float totalFrame = length * 30;// clip.frameRate;
|
|||
|
float deltaTime = (durationFame / totalFrame);
|
|||
|
float speed = 1;
|
|||
|
if (!string.IsNullOrEmpty(eventData.EditorParam))
|
|||
|
{
|
|||
|
if (!float.TryParse(eventData.EditorParam, out speed))
|
|||
|
speed = 1;
|
|||
|
}
|
|||
|
deltaTime *= speed;
|
|||
|
if (animEvent.WrapMode == WrapMode.Loop)
|
|||
|
{
|
|||
|
if (deltaTime > 1.0f)
|
|||
|
{
|
|||
|
deltaTime = deltaTime - (float)Math.Truncate(deltaTime);
|
|||
|
}
|
|||
|
}
|
|||
|
state.normalizedTime = deltaTime;
|
|||
|
state.normalizedSpeed = 0;
|
|||
|
}
|
|||
|
|
|||
|
Animation.Play(animEvent.Param);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//播放动作,不按照帧播放
|
|||
|
public void PlayAnimation(CinematicEventData eventData)
|
|||
|
{
|
|||
|
if (Animation != null && eventData != null)
|
|||
|
{
|
|||
|
var animEvent = eventData;
|
|||
|
if (Animation[animEvent.Param] != null)
|
|||
|
{
|
|||
|
Animation.Stop();
|
|||
|
var state = Animation[animEvent.Param];
|
|||
|
state.wrapMode = eventData.WrapMode;
|
|||
|
float speed = 1;
|
|||
|
if (!string.IsNullOrEmpty(eventData.EditorParam))
|
|||
|
{
|
|||
|
if (!float.TryParse(eventData.EditorParam, out speed))
|
|||
|
speed = 1;
|
|||
|
}
|
|||
|
state.speed = speed;
|
|||
|
Animation.Play(animEvent.Param);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Update()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public void EditorUpdate()
|
|||
|
{
|
|||
|
if (GameObject != null)
|
|||
|
Name = GameObject.name;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|
|||
|
|