238 lines
5.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|