/
ItemBehaviour.cs
155 lines (127 loc) · 4.63 KB
/
ItemBehaviour.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemBehaviour : MonoBehaviour
{
public int ItemIndex = -1; // ID
[SerializeField] float TimeToSpawn = 1f;
[SerializeField] float TimeToHover = 5f;
[SerializeField] float TimeToFlySmooth = 0.5f;
private Vector3 CurrentVelocity = Vector3.zero;
[SerializeField] private float RotateSpeed = 10f;
[SerializeField] float BobbingIntensity = 0.005f;
[SerializeField] float BobbingFrequency = 3f;
[SerializeField] float CollectionRadius = 2f;
[SerializeField] float DetectionRadius = 5f;
[SerializeField] private GameObject TargetCollector;
[SerializeField] private GameObject TargetInventory;
void Start()
{
TargetCollector = PlayerSetup.instance.ItemCollector;
TargetInventory = PlayerSetup.instance.Player;
RandomizeTimes();
StartCoroutine(StartBehaviour());
StartCoroutine(DetectProximity());
}
private void RandomizeTimes()
{
TimeToSpawn = Random.Range(0.5f, 1.5f);
TimeToHover = Random.Range(4f, 6f);
TimeToFlySmooth = Random.Range(0.3f, 0.5f);
}
IEnumerator DetectProximity()
{
/* Continually Check if Item is close enough to collector to be picked up automatically */
while (true)
{
if (TargetCollector == null)
{
Debug.Log("No Target Attached, No check proximity.");
break;
}
if (GetDistanceToTarget() <= DetectionRadius)
{
this.StopAllCoroutines();
StartCoroutine(StartFlyToTarget());
break;
}
yield return null;
}
}
IEnumerator StartBehaviour()
{
// Do Nothing for TimeToSpawn seconds
yield return new WaitForSeconds(TimeToSpawn);
StartCoroutine(StartHover());
}
IEnumerator StartHover()
{
/* Let Item float in place for a few seconds*/
// Remove RigidBody to avoid physics
float timePassed = 0f;
Destroy(this.gameObject.GetComponent<Rigidbody>());
while (timePassed < TimeToHover)
{
timePassed += Time.deltaTime;
// Bobbing Animation
var newPosition = Vector3.up * Mathf.Cos(timePassed * BobbingFrequency) * BobbingIntensity;
this.gameObject.transform.position += newPosition;
// Reset Rotation
var newRotation = Quaternion.RotateTowards(this.gameObject.transform.rotation, Quaternion.identity, timePassed * RotateSpeed);
this.gameObject.transform.rotation = newRotation;
yield return null;
}
StartCoroutine(StartFlyToTarget());
}
IEnumerator StartFlyToTarget()
{
/* Move item towards collector */
float timePassed = 0f;
this.StopCoroutine(DetectProximity());
while (true)
{
if (TargetCollector == null)
{
Debug.Log("No Target Attached, will Despawn.");
Destroy(this.gameObject);
break;
}
// Set Position
var newPosition = Vector3.SmoothDamp(
this.gameObject.transform.position,
TargetCollector.transform.position,
ref CurrentVelocity,
TimeToFlySmooth
);
this.gameObject.transform.position = newPosition;
// Set Rotation
var direction = (TargetCollector.transform.position - this.gameObject.transform.position).normalized;
var lookTo = Quaternion.LookRotation(direction);
var newRotation = Quaternion.RotateTowards(this.gameObject.transform.rotation, lookTo, timePassed * RotateSpeed);
timePassed += Time.deltaTime;
this.gameObject.transform.rotation = newRotation;
if (GetDistanceToTarget() <= CollectionRadius) {
GetCollected();
break;
}
yield return null;
}
}
private void GetCollected()
{
if(ItemIndex == -1)
{
Debug.Log("Invalid Item Index, Not marked on Instantiate.");
return;
}
var targetInventory = TargetInventory.GetComponent<ItemController>();
targetInventory.CollectItem(ItemIndex);
Destroy(this.gameObject);
}
private float GetDistanceToTarget()
{
var currentPosition = this.gameObject.transform.position;
var targetPosition = TargetCollector.transform.position;
return Vector3.Distance(currentPosition, targetPosition);
}
}