Files
Main/Assets/Plugins/ExternalLibs/FlyTeleport/FlyTeleportEditorScript.cs
2025-01-25 04:38:09 +08:00

222 lines
7.3 KiB
C#

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<List<FlyTeleportNodeScript>> GetChildNodes()
{
List<FlyTeleportNodeScript> childNodes = new List<FlyTeleportNodeScript>();
for (int i = 0; i < transform.childCount; ++i)
{
var script = transform.GetChild(i).GetComponent<FlyTeleportNodeScript>();
if (script != null)
{
childNodes.Add(script);
}
}
List<List<FlyTeleportNodeScript>> result = new List<List<FlyTeleportNodeScript>>();
if (childNodes.Count >= 2)
{
List<FlyTeleportNodeScript> curNodes = new List<FlyTeleportNodeScript>();
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<FlyTeleportNodeScript>();
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<List<FlyTeleportNodeScript>> 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
);
}
}