-
Notifications
You must be signed in to change notification settings - Fork 0
/
Navigator.cs
98 lines (82 loc) · 2.58 KB
/
Navigator.cs
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
using UnityEngine;
using System.Collections;
public class Navigator : MonoBehaviour {
public float ReactionTime = 0.5f;
public float TurnSpeed = 0.77f;
public float DetourSize = 300f;
public float SafeDistance = 100f;
public float SafetyForceScalar = 1.0f;
public GameObject EngineFX;
float MoveSpeed = 0;
float ResponseTimer = 0;
AI_Agent agent;
Rigidbody rb;
Vector3 LocalPosition = Vector3.zero;
Vector3 DestPosition = Vector3.zero;
public void Init()
{
agent = GetComponent<AI_Agent>();
rb = GetComponent<Rigidbody>();
MoveSpeed = agent.botMaxSpeed.z;
ResponseTimer = 0;
LocalPosition = transform.position;
}
public void NavigateTo(Transform Destination)
{
LocalPosition = transform.position;
DestPosition = Destination.position;
RaycastHit hit;
/// Main Line to destination
if (Physics.Linecast(LocalPosition, DestPosition, out hit))
{
if (hit.transform == Destination)
{ MoveTo(Destination.position); }
else
{
if (hit.transform.tag != "Navigation")
{
Vector3 Detour = hit.normal * DetourSize;
Debug.DrawRay(hit.point, Detour, Color.blue);
Vector3 DetourActual = Detour + hit.point;
MoveTo(DetourActual);
}
else
{
MoveTo(Destination.position);
}
}
}
/// Safety Forces - checks sphere for nearby obstacles
ResponseTimer += Time.deltaTime;
if (ResponseTimer >= ReactionTime)
{
Collider[] surroundings = Physics.OverlapSphere(LocalPosition, DetourSize / 2);
foreach (Collider c in surroundings)
{
if (c.transform != transform && c.transform.tag != "Navigation")
{
Vector3 HitPosition = c.ClosestPointOnBounds(LocalPosition);
float ScalarAcutal = MoveSpeed * SafetyForceScalar;
/// Decelerate if too close to obj
float DistToObj = Vector3.Distance(LocalPosition, c.transform.position);
if (DistToObj <= SafeDistance)
rb.velocity *= 0.985f;
Vector3 SafetyVector = (LocalPosition - HitPosition).normalized;
rb.AddForce(SafetyVector * ScalarAcutal, ForceMode.Impulse);
///Debug.DrawLine(LocalPosition, HitPosition, Color.white);
}
}
ResponseTimer = 0.0f;
}
}
public void MoveTo(Vector3 endPoint)
{
/// Rotation
Vector3 ToPoint = (endPoint - LocalPosition).normalized;
Vector3 LookDirection = Vector3.Slerp(transform.forward, ToPoint, Time.deltaTime * TurnSpeed);
transform.rotation = Quaternion.LookRotation(LookDirection, Vector3.up);
/// Thrust
rb.AddForce(transform.forward * MoveSpeed);
EngineFX.SetActive(true);
}
}