Skip to content

Instantly share code, notes, and snippets.

@chiepomme
Last active March 18, 2017 04:44
Show Gist options
  • Save chiepomme/5838334034bf89767c30d06a911c1a08 to your computer and use it in GitHub Desktop.
Save chiepomme/5838334034bf89767c30d06a911c1a08 to your computer and use it in GitHub Desktop.
SplineEditor https://www.assetstore.unity3d.com/jp/#!/content/58080 のスプラインを実線にするようなやつ
using Battlehub.SplineEditor;
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter), typeof(MeshCollider))]
public class MyLineRenderer : MonoBehaviour
{
[SerializeField]
public Material material;
[SerializeField]
public Spline spline;
[SerializeField, Range(0.1f, 100f)]
public float segmentPerUnit = 10;
[SerializeField, Range(0, 1)]
public float segmentStartT;
[SerializeField, Range(0, 1)]
public float width;
int currentSegmentCount;
Mesh mesh;
MeshFilter filter;
MeshRenderer meshRenderer;
Vector3[] vertices;
Vector2[] uvs;
int[] triangles;
void Awake()
{
filter = GetComponent<MeshFilter>();
meshRenderer = GetComponent<MeshRenderer>();
meshRenderer.material = material;
mesh = new Mesh();
mesh.hideFlags = HideFlags.DontSave;
filter.mesh = mesh;
GetComponent<MeshCollider>().sharedMesh = mesh;
InitializeVertices(CalculateSegmentCount());
UpdateMesh();
}
void Update()
{
if (!Application.isPlaying)
{
// セグメント数が変わったら作り直す
var newSegmentcount = CalculateSegmentCount();
if (newSegmentcount != currentSegmentCount)
{
InitializeVertices(newSegmentcount);
}
}
UpdateMesh();
}
int CalculateSegmentCount()
{
return Mathf.Max(1, (int)(segmentPerUnit * spline.EvalSplineLength()));
}
void InitializeVertices(int segmentCount)
{
currentSegmentCount = segmentCount;
vertices = new Vector3[(segmentCount + 1) * 2];
uvs = new Vector2[(segmentCount + 1) * 2];
triangles = new int[segmentCount * 2 * 3];
}
void UpdateMesh()
{
for (var i = 0; i <= currentSegmentCount; i++) // 普通のループよりひとつおおく
{
var t = (float)i / currentSegmentCount;
var lerpedT = Mathf.Lerp(segmentStartT, 1, t);
var pos = spline.GetPoint(lerpedT);
var dir = spline.GetDirection(lerpedT);
var vertexStart = i * 2;
// SplineBase の DrawTwistAngle() から借りてきた
Vector3 v3;
if (Mathf.Abs(Vector3.Dot(dir, Vector3.up)) < 1.0f)
{
v3 = Vector3.Cross(dir, Vector3.up).normalized;
}
else
{
v3 = Vector3.Cross(dir, Vector3.forward).normalized;
}
vertices[vertexStart + 0] = transform.InverseTransformPoint(pos + Quaternion.AngleAxis(spline.GetTwist(lerpedT), dir) * Quaternion.LookRotation(v3, Vector3.up) * Vector3.forward * (width / 2));
vertices[vertexStart + 1] = transform.InverseTransformPoint(pos - Quaternion.AngleAxis(spline.GetTwist(lerpedT), dir) * Quaternion.LookRotation(v3, Vector3.up) * Vector3.forward * (width / 2));
uvs[vertexStart + 0] = uvs[vertexStart + 1] = Vector2.one * i;
if (i != currentSegmentCount) // 最後は面がない
{
var faceStart = i * 2 * 3;
triangles[faceStart + 0] = vertexStart + 0;
triangles[faceStart + 1] = vertexStart + 1;
triangles[faceStart + 2] = vertexStart + 2;
triangles[faceStart + 3] = vertexStart + 2;
triangles[faceStart + 4] = vertexStart + 1;
triangles[faceStart + 5] = vertexStart + 3;
}
}
mesh.Clear();
mesh.vertices = vertices;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
}
using UnityEngine;
[ExecuteInEditMode]
public class SplineFollowingObject : MonoBehaviour
{
[SerializeField]
MyLineRenderer myLineRenderer;
void Update()
{
transform.position = myLineRenderer.spline.GetPoint(myLineRenderer.segmentStartT);
var dir = myLineRenderer.spline.GetDirection(myLineRenderer.segmentStartT);
// SplineBase の DrawTwistAngle() から借りてきた
Vector3 v3;
if (Mathf.Abs(Vector3.Dot(dir, Vector3.up)) < 1.0f)
{
v3 = Vector3.Cross(dir, Vector3.up).normalized;
}
else
{
v3 = Vector3.Cross(dir, Vector3.forward).normalized;
}
var twist = myLineRenderer.spline.GetTwist(myLineRenderer.segmentStartT);
transform.LookAt(transform.position + dir, Quaternion.AngleAxis(twist, dir) * Quaternion.LookRotation(v3, Vector3.up) * Vector3.right);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment