Files
2026-02-21 16:45:37 +08:00

238 lines
5.1 KiB
C#

using UnityEngine;
public class MegaDrawSpline : MonoBehaviour
{
public float updatedist = 1f;
public float smooth = 0.7f;
public Material mat;
public float width = 1f;
public float height = 1f;
public float radius = 0.1f;
public bool closed = true;
public MeshShapeType meshtype = MeshShapeType.Box;
public float offset = 0.01f;
public float tradius = 1f;
public float meshstep = 1f;
public float closevalue = 0.1f;
public bool constantspd = true;
private GameObject obj;
private Vector3 lasthitpos;
private bool building;
private float travelled;
private Vector3 lastdir;
private MegaSpline cspline;
private MegaShape cshape;
private int splinecount;
private void Update()
{
if (building)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
bool flag = Physics.Raycast(ray, out hitInfo);
if (Input.GetMouseButtonUp(0) || !flag)
{
building = false;
if (ValidSpline())
{
FinishSpline(obj, lasthitpos);
}
else
{
Object.Destroy(obj);
}
obj = null;
cspline = null;
cshape = null;
}
else
{
if (!flag)
{
return;
}
Vector3 point = hitInfo.point;
point.y += offset;
float num = Vector3.Distance(lasthitpos, point);
travelled += num;
if (travelled > updatedist)
{
cspline.AddKnot(cshape.transform.worldToLocalMatrix.MultiplyPoint3x4(point), Vector3.zero, Vector3.zero);
cshape.AutoCurve();
travelled -= updatedist;
}
else
{
cspline.knots[cspline.knots.Count - 1].p = cshape.transform.worldToLocalMatrix.MultiplyPoint3x4(point);
cshape.AutoCurve();
if (cspline.knots.Count == 2)
{
float num2 = cspline.KnotDistance(0, 1);
if (num2 > 0.1f)
{
cshape.BuildMesh();
}
}
else if (cspline.knots.Count > 2)
{
cshape.BuildMesh();
}
}
lasthitpos = point;
}
}
else if (Input.GetMouseButtonDown(0))
{
Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo2;
if (Physics.Raycast(ray2, out hitInfo2))
{
Vector3 point2 = hitInfo2.point;
point2.y += offset;
lasthitpos = point2;
travelled = 0f;
obj = CreateSpline(point2);
building = true;
}
}
}
private bool ValidSpline()
{
if (cspline.knots.Count == 2)
{
float num = cspline.KnotDistance(0, 1);
if (num <= 0.1f)
{
return false;
}
}
return true;
}
public MegaSpline NewSpline(MegaShape shape)
{
if (shape.splines.Count == 0)
{
MegaSpline item = new MegaSpline();
shape.splines.Add(item);
}
MegaSpline megaSpline = shape.splines[0];
megaSpline.knots.Clear();
megaSpline.closed = false;
return megaSpline;
}
private GameObject CreateSpline(Vector3 pos)
{
GameObject gameObject = new GameObject();
gameObject.name = base.name + " - Spline " + splinecount++;
gameObject.transform.position = base.transform.position;
MegaShape megaShape = gameObject.AddComponent<MegaShape>();
megaShape.smoothness = smooth;
megaShape.drawHandles = false;
MegaSpline megaSpline = megaShape.splines[0];
megaSpline.knots.Clear();
megaSpline.constantSpeed = constantspd;
megaSpline.subdivs = 40;
megaShape.splines.Add(megaSpline);
megaShape.cap = true;
megaShape.BuildSpline(0, new Vector3[2]
{
gameObject.transform.worldToLocalMatrix.MultiplyPoint3x4(pos),
gameObject.transform.worldToLocalMatrix.MultiplyPoint3x4(pos)
}, false);
megaShape.CalcLength();
megaShape.mat1 = mat;
megaShape.drawTwist = true;
megaShape.makeMesh = true;
megaShape.meshType = meshtype;
megaShape.boxwidth = width;
megaShape.boxheight = height;
megaShape.offset = (0f - height) * 0.5f;
megaShape.tradius = tradius;
megaShape.stepdist = meshstep;
megaShape.SetMats();
megaSpline.closed = closed;
cspline = megaSpline;
cshape = megaShape;
return gameObject;
}
private void FinishSpline(GameObject obj, Vector3 p)
{
if (!closed)
{
Vector3 b = obj.transform.worldToLocalMatrix.MultiplyPoint3x4(p);
float num = Vector3.Distance(cspline.knots[0].p, b);
if (num < updatedist * closevalue)
{
cspline.closed = true;
cshape.cap = false;
cspline.knots.RemoveAt(cspline.knots.Count - 1);
}
else
{
cshape.cap = true;
}
}
else
{
if (cspline.knots.Count > 2)
{
float num2 = cspline.KnotDistance(cspline.knots.Count - 1, cspline.knots.Count - 2);
if (num2 < updatedist * 0.25f)
{
cspline.knots.RemoveAt(cspline.knots.Count - 1);
}
}
float num3 = cspline.KnotDistance(cspline.knots.Count - 1, 0);
if (num3 < updatedist * closevalue)
{
cspline.knots.RemoveAt(cspline.knots.Count - 1);
}
}
cshape.AutoCurve();
cshape.BuildMesh();
}
private void OnDrawGizmosSelected()
{
if ((bool)cshape && cspline != null)
{
Gizmos.color = Color.white;
Gizmos.matrix = obj.transform.localToWorldMatrix;
for (int i = 1; i < cspline.knots.Count; i++)
{
Gizmos.DrawLine(cspline.knots[i - 1].p, cspline.knots[i].p);
}
Gizmos.color = Color.green;
for (int j = 0; j < cspline.knots.Count; j++)
{
Gizmos.DrawSphere(cspline.knots[j].p, radius);
}
}
}
}