diff options
author | chai <215380520@qq.com> | 2024-03-13 11:00:58 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2024-03-13 11:00:58 +0800 |
commit | 6ce8b9e22fc13be34b442c7b6af48b42cd44275a (patch) | |
tree | b38119d2acf0a982cb67e381f146924b9bfc3b3f /ch.sycoforge.Decal.Demo/PathAgent.cs |
+init
Diffstat (limited to 'ch.sycoforge.Decal.Demo/PathAgent.cs')
-rw-r--r-- | ch.sycoforge.Decal.Demo/PathAgent.cs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/ch.sycoforge.Decal.Demo/PathAgent.cs b/ch.sycoforge.Decal.Demo/PathAgent.cs new file mode 100644 index 0000000..27908d7 --- /dev/null +++ b/ch.sycoforge.Decal.Demo/PathAgent.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.AI; + +namespace ch.sycoforge.Decal.Demo; + +[RequireComponent(typeof(NavMeshAgent))] +[RequireComponent(typeof(LineRenderer))] +public class PathAgent : MonoBehaviour +{ + public float PathThickness = 1f; + + [Tooltip("Distance from the ground.")] + public float NormalPathOffset; + + [Tooltip("Max radius between segments.")] + [Range(0.001f, 0.5f)] + public float Radius = 0.25f; + + [Tooltip("Discard segments when their angle is smaller than this value.")] + public float AngleThreshold = 5f; + + public bool DrawGizmos; + + public EasyDecal TargetAimDecal; + + public GameObject TargetPointDecalPrefab; + + private List<Vector3> path = new List<Vector3>(); + + private NavMeshAgent agent; + + private LineRenderer lineRenderer; + + private Vector3 decalOffset = Vector3.up * 0.5f; + + private const int MAXDISTANCE = 50; + + private void Start() + { + TargetAimDecal.gameObject.SetActive(value: false); + agent = GetComponent<NavMeshAgent>(); + lineRenderer = GetComponent<LineRenderer>(); + } + + private void Update() + { + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + CreatePath(ray); + SetTarget(ray); + } + + private void SetTarget(Ray mouseRay) + { + if (Input.GetMouseButtonUp(0) && Physics.Raycast(mouseRay, out var hitInfo, 50f)) + { + agent.SetDestination(hitInfo.point); + EasyDecal.ProjectAt(TargetPointDecalPrefab, hitInfo.collider.gameObject, hitInfo.point + decalOffset, Quaternion.identity); + } + } + + private void CreatePath(Ray mouseRay) + { + if (Physics.Raycast(mouseRay, out var hitInfo, 50f)) + { + Vector3 position = base.transform.position; + Vector3 point = hitInfo.point; + path.Clear(); + NavMeshPath navMeshPath = new NavMeshPath(); + if (NavMesh.CalculatePath(position, point, -1, navMeshPath) && navMeshPath.status == NavMeshPathStatus.PathComplete) + { + int num = navMeshPath.corners.Length; + Vector3 vector = base.transform.up; + for (int i = 0; i < num; i++) + { + if (i > 0 && NormalPathOffset > 0f && Physics.Raycast(navMeshPath.corners[i], Vector3.down, out var _, NormalPathOffset * 10f)) + { + vector = hitInfo.normal; + } + Vector3 item = navMeshPath.corners[i] + vector * NormalPathOffset; + path.Add(item); + } + Vector3[] array = BezierUtil.InterpolatePath(path, 10, Radius, AngleThreshold).ToArray(); + lineRenderer.SetVertexCount(array.Length); + lineRenderer.SetPositions(array); + TargetAimDecal.gameObject.SetActive(value: true); + TargetAimDecal.gameObject.transform.position = navMeshPath.corners[num - 1] + decalOffset; + return; + } + } + TargetAimDecal.gameObject.SetActive(value: false); + } + + private void OnDrawGizmos() + { + if (!DrawGizmos) + { + return; + } + Gizmos.color = Color.red; + foreach (Vector3 item in path) + { + Gizmos.DrawSphere(item, 0.05f); + } + } +} |