summaryrefslogtreecommitdiff
path: root/ch.sycoforge.Decal.Demo/PathAgent.cs
blob: 27908d7eb9e038988d844330e9d746af04cdd348 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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);
		}
	}
}