using System; using System.Collections.Generic; using UnityEngine; namespace Thousandto.Cinematic.Plugin { public class CinematicUI_Curve : MonoBehaviour { public List GameObjectList; public int CurvRate = 20; public int Offset = 2; public bool UseSlider = false; public float SliderValue = 0; public CinematicObj CinematicObj; private static int _offset = 2; private static int _rate = 20; private static bool _userSlider; private List _transDataList = new List(); private List _transKeyframeList = new List(); void Start() { InitTransformData(); } void InitTransformData() { if(CinematicObj != null) { _transDataList.Clear(); for (int i = 0; i < CinematicObj.KeyframeList.Count; ++i) { bool hasSyncEvent = false; bool hasPosition = false; Vector3 position = Vector3.zero; for(int m = 0; m < CinematicObj.KeyframeList[i].EventData.Count; ++m) { var eventData = CinematicObj.KeyframeList[i].EventData[m]; if (eventData.EventTypeEx == KeyFrameEvent.坐标变换) { hasPosition = true; position = eventData.Position; //_transDataList.Add(eventData.Position); _transKeyframeList.Add(CinematicObj.KeyframeList[i]); } if (eventData.EventTypeEx == KeyFrameEvent.同步到本地相机坐标 || eventData.EventTypeEx == KeyFrameEvent.同步到本地角色坐标) hasSyncEvent = true; } if(!hasSyncEvent && hasPosition) _transDataList.Add(position); } } } public void OnRefresh() { InitTransformData(); } void OnDrawGizmos() { _rate = CurvRate; _offset = Offset; _userSlider = UseSlider; Gizmos.color = Color.yellow; if(_transDataList != null && _transDataList.Count > 1) { var v3 = (_transDataList.ToArray()); if(!UseSlider) { DrawPathHelper(v3, Color.red, "gizmos"); } else { DrawPathHelper(v3, Color.red, SliderValue); } } Gizmos.color = Color.green; for (int i = 0; i < _transKeyframeList.Count; i += 2) { if (i + 1 >= _transKeyframeList.Count) break; if(!_transKeyframeList[i].TransformEvent.UseCurve || _transKeyframeList[i].HasSyncTrans || _transKeyframeList[i + 1].HasSyncTrans) { Gizmos.DrawLine(_transKeyframeList[i].TransformEvent.Position, _transKeyframeList[i+1].TransformEvent.Position); } } } Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) { float u = 1 - t; float tt = t * t; float uu = u * u; float uuu = uu * u; float ttt = tt * t; Vector3 p = uuu * p0; p += 3 * uu * t * p1; p += 3 * u * tt * p2; p += ttt * p3; return p; } public static Vector3[] PathControlPointGenerator(Vector3[] path) { Vector3[] suppliedPath; Vector3[] vector3s; //create and store path points: suppliedPath = path; //populate calculate path; int offset = _offset; vector3s = new Vector3[suppliedPath.Length + offset]; Array.Copy(suppliedPath, 0, vector3s, 1, suppliedPath.Length); //populate start and end control points: //vector3s[0] = vector3s[1] - vector3s[2]; vector3s[0] = vector3s[1] + (vector3s[1] - vector3s[2]); vector3s[vector3s.Length - 1] = vector3s[vector3s.Length - 2] + (vector3s[vector3s.Length - 2] - vector3s[vector3s.Length - 3]); //is this a closed, continuous loop? yes? well then so let's make a continuous Catmull-Rom spline! if (vector3s[1] == vector3s[vector3s.Length - 2]) { Vector3[] tmpLoopSpline = new Vector3[vector3s.Length]; Array.Copy(vector3s, tmpLoopSpline, vector3s.Length); tmpLoopSpline[0] = tmpLoopSpline[tmpLoopSpline.Length - 3]; tmpLoopSpline[tmpLoopSpline.Length - 1] = tmpLoopSpline[2]; vector3s = new Vector3[tmpLoopSpline.Length]; Array.Copy(tmpLoopSpline, vector3s, tmpLoopSpline.Length); } return (vector3s); } //andeeee from the Unity forum's steller Catmull-Rom class ( http://forum.unity3d.com/viewtopic.php?p=218400#218400 ): public Vector3 Interp(Vector3[] pts, float t) { int numSections = pts.Length - 3; int currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - 1); float u = t * (float)numSections - (float)currPt; Vector3 a = pts[currPt]; Vector3 b = pts[currPt + 1]; Vector3 c = pts[currPt + 2]; Vector3 d = pts[currPt + 3]; return .5f * ( (-a + 3f * b - 3f * c + d) * (u * u * u) + (2f * a - 5f * b + 4f * c - d) * (u * u) + (-a + c) * u + 2f * b ); } private void DrawPathHelper(Vector3[] path, Color color, string method) { Vector3[] vector3s = PathControlPointGenerator(path); //Line Draw: Vector3 prevPt = Interp(vector3s, 0); int SmoothAmount = path.Length * _rate; for (int i = 1; i <= SmoothAmount; i++) { float pm = (float)i / SmoothAmount; Vector3 currPt = Interp(vector3s, pm); Gizmos.color = color; if (method == "gizmos") { Gizmos.DrawLine(currPt, prevPt); } else if (method == "handles") { Debug.LogError("iTween Error: Drawing a path with Handles is temporarily disabled because of compatability issues with Unity 2.6!"); //UnityEditor.Handles.DrawLine(currPt, prevPt); } prevPt = currPt; } } private void DrawPathHelper(Vector3[] path, Color color, float t) { Vector3[] vector3s = PathControlPointGenerator(path); //Line Draw: Vector3 prevPt = Interp(vector3s, 0); Gizmos.color = color; int SmoothAmount = path.Length * _rate; for (int i = 1; i <= SmoothAmount; i++) { float pm = (float)i / SmoothAmount; if (pm > t) return; Vector3 currPt = Interp(vector3s, pm); Gizmos.DrawLine(currPt, prevPt); prevPt = currPt; } } } }