You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.7 KiB
117 lines
3.7 KiB
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. =========== |
|
|
|
using HTC.UnityPlugin.Pointer3D; |
|
using UnityEngine; |
|
|
|
public class GuideLineDrawer : MonoBehaviour |
|
{ |
|
public const float MIN_SEGMENT_LENGTH = 0.01f; |
|
|
|
public Vector3 gravityDirection = Vector3.down; |
|
public bool showOnHitOnly; |
|
public float segmentLength = 0.05f; |
|
|
|
public Pointer3DRaycaster raycaster; |
|
public LineRenderer lineRenderer; |
|
|
|
#if UNITY_EDITOR |
|
protected virtual void Reset() |
|
{ |
|
for (var tr = transform; raycaster == null && tr != null; tr = tr.parent) |
|
{ |
|
raycaster = tr.GetComponentInChildren<Pointer3DRaycaster>(); |
|
} |
|
|
|
if (lineRenderer == null) { lineRenderer = GetComponentInChildren<LineRenderer>(); } |
|
if (lineRenderer == null && raycaster != null) { lineRenderer = gameObject.AddComponent<LineRenderer>(); } |
|
if (lineRenderer != null) |
|
{ |
|
#if UNITY_5_5_OR_NEWER |
|
lineRenderer.startWidth = 0.01f; |
|
lineRenderer.endWidth = 0f; |
|
#else |
|
lineRenderer.SetWidth(0.01f, 0f); |
|
#endif |
|
} |
|
} |
|
#endif |
|
protected virtual void LateUpdate() |
|
{ |
|
var result = raycaster.FirstRaycastResult(); |
|
if (showOnHitOnly && !result.isValid) |
|
{ |
|
lineRenderer.enabled = false; |
|
return; |
|
} |
|
|
|
var points = raycaster.BreakPoints; |
|
var pointCount = points.Count; |
|
|
|
if (pointCount < 2) |
|
{ |
|
return; |
|
} |
|
|
|
lineRenderer.enabled = true; |
|
lineRenderer.useWorldSpace = false; |
|
|
|
var startPoint = points[0]; |
|
var endPoint = points[pointCount - 1]; |
|
|
|
if (pointCount == 2) |
|
{ |
|
#if UNITY_5_6_OR_NEWER |
|
lineRenderer.positionCount = 2; |
|
#elif UNITY_5_5_OR_NEWER |
|
lineRenderer.numPositions = 2; |
|
#else |
|
lineRenderer.SetVertexCount(2); |
|
#endif |
|
lineRenderer.SetPosition(0, transform.InverseTransformPoint(startPoint)); |
|
lineRenderer.SetPosition(1, transform.InverseTransformPoint(endPoint)); |
|
} |
|
else |
|
{ |
|
var systemY = gravityDirection; |
|
var systemX = endPoint - startPoint; |
|
var systemZ = default(Vector3); |
|
|
|
Vector3.OrthoNormalize(ref systemY, ref systemX, ref systemZ); |
|
|
|
var initialV = Vector3.ProjectOnPlane(points[1] - points[0], systemZ); // initial projectile direction |
|
var initialVx = Vector3.Dot(initialV, systemX); |
|
var initialVy = Vector3.Dot(initialV, systemY); |
|
var initSlope = initialVy / initialVx; |
|
|
|
var approachV = endPoint - startPoint; |
|
var approachVx = Vector3.Dot(approachV, systemX); |
|
var approachVy = Vector3.Dot(approachV, systemY); |
|
|
|
var lenx = Mathf.Max(segmentLength, MIN_SEGMENT_LENGTH); |
|
var segments = Mathf.Max(Mathf.CeilToInt(approachVx / lenx), 0); |
|
|
|
var factor = (approachVy - initSlope * approachVx) / (approachVx * approachVx); |
|
|
|
#if UNITY_5_6_OR_NEWER |
|
lineRenderer.positionCount = segments + 1; |
|
#elif UNITY_5_5_OR_NEWER |
|
lineRenderer.numPositions = segments + 1; |
|
#else |
|
lineRenderer.SetVertexCount(segments + 1); |
|
#endif |
|
lineRenderer.SetPosition(0, transform.InverseTransformPoint(startPoint)); |
|
for (int i = 1, imax = segments; i < imax; ++i) |
|
{ |
|
var x = i * lenx; |
|
var y = factor * x * x + initSlope * x; |
|
lineRenderer.SetPosition(i, transform.InverseTransformPoint(systemX * x + systemY * y + startPoint)); |
|
} |
|
lineRenderer.SetPosition(segments, transform.InverseTransformPoint(endPoint)); |
|
} |
|
} |
|
|
|
protected virtual void OnDisable() |
|
{ |
|
lineRenderer.enabled = false; |
|
} |
|
}
|
|
|