using Thousandto.Plugins.Common.UniScene; using System; using System.Collections.Generic; using UnityEngine; public class FlyTeleportEditorScript : MonoBehaviour { public int ID = 0; public string MapName = string.Empty; public float Length = 0f; public void InitWithData(FlyTeleportCfgData data) { ID = data.ID; MapName = data.MapName; Length = data.Length; } public List> GetChildNodes() { List childNodes = new List(); for (int i = 0; i < transform.childCount; ++i) { var script = transform.GetChild(i).GetComponent(); if (script != null) { childNodes.Add(script); } } List> result = new List>(); if (childNodes.Count >= 2) { List curNodes = new List(); curNodes.Add(childNodes[0]); result.Add(curNodes); for (int i = 1; i < childNodes.Count; ++i) { curNodes.Add(childNodes[i]); if (childNodes[i].BreakPoint) { curNodes = new List(); curNodes.Add(childNodes[i]); result.Add(curNodes); } } for (int i = result.Count - 1; i >= 0; --i) { if(result[i].Count <= 1) { result.RemoveAt(i); } } } return result; } public List> CalculatePathNodePercent() { var chileNodes = GetChildNodes(); Length = 0f; for (int j = 0; j < chileNodes.Count; ++j) { var child = chileNodes[j]; Vector3[] path = new Vector3[child.Count]; for (int i = 0; i < child.Count; ++i) { path[i] = child[i].transform.position; } Vector3[] itweenPath = iTween.PathControlPointGenerator(path); //先计算长度 Vector3 prevPt = iTween.Interp(itweenPath, 0); int SmoothAmount = path.Length * 100; float pathLength = 0f; int k = 1; for (int i = 1; i <= SmoothAmount; i++) { float pm = (float)i / SmoothAmount; Vector3 currPt = iTween.Interp(itweenPath, pm); float nowDis = Vector3.Distance(prevPt, currPt); if (k < child.Count) { var node = child[k]; if (node.transform.position == currPt) { node.Distance = pathLength + nowDis; ++k; } else { var oldDir = prevPt - node.transform.position; var newDir = currPt - node.transform.position; if (oldDir.x * newDir.x < 0 || oldDir.y * newDir.y < 0 || oldDir.z * newDir.z < 0) { node.Distance = pathLength + Vector3.Distance(prevPt, node.transform.position); ++k; } } } pathLength += nowDis; prevPt = currPt; } for (int i = 1; i < child.Count; ++i) { child[i].Percent = child[i].Distance / pathLength; } Length += pathLength; } return chileNodes; } void OnDrawGizmos() { var childNodes = GetChildNodes(); for(int i=0;i< childNodes.Count;++i) { var posArray = new Vector3[childNodes[i].Count]; for(int j=0;j< childNodes[i].Count;++j) { posArray[j] = childNodes[i][j].transform.position; } DrawPath(posArray, Color.green); for (int j = 0; j < childNodes[i].Count; ++j) { Gizmos.DrawSphere(childNodes[i][j].transform.position, 0.2f); } } } public static void DrawPath(Vector3[] path, Color color) { if (path.Length > 0) { DrawPathHelper(path, color, "gizmos"); } } private static void DrawPathHelper(Vector3[] path, Color color, string method) { Vector3[] vector3s = PathControlPointGenerator(path); //Line Draw: Vector3 prevPt = Interp(vector3s, 0); Gizmos.color = color; int SmoothAmount = path.Length * 20; for (int i = 1; i <= SmoothAmount; i++) { float pm = (float)i / SmoothAmount; Vector3 currPt = Interp(vector3s, pm); 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; } } public static Vector3[] PathControlPointGenerator(Vector3[] path) { Vector3[] suppliedPath; Vector3[] vector3s; //create and store path points: suppliedPath = path; //populate calculate path; int offset = 2; 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 static 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 ); } }