-
Notifications
You must be signed in to change notification settings - Fork 0
/
HealerUnit.cs
152 lines (115 loc) · 3.44 KB
/
HealerUnit.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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[RequireComponent(typeof(Movement))]
public class HealerUnit : Unit
{
#region Variables
[SerializeField] private int m_healPower = 5;
[SerializeField] private float m_healCooldown = 1f;
[SerializeField] private float m_healingRadius = 2f;
private bool m_canHeal = false;
private float m_lastTimeHealing = 0f;
[SerializeField] private Unit m_target;
private GameObject m_healFX;
private ParticleSystem m_healFParticles;
#endregion
#region Properties
public Unit Target
{
get { return m_target; }
set
{
// Unregister the assigned healer from the old target
if (m_target != null) m_target.assignedHealer = null;
// If the new target does not have an assigned healer
if (value == null || value.assignedHealer == null)
{
m_target = value;
// If the new target is valid register 'this' as the assigned healer
if (m_target) m_target.assignedHealer = this;
}
}
}
#endregion
#region MonoBehaviour
protected new void Awake()
{
base.Awake();
m_healFX = Resources.Load("FXs/ParticleHealing") as GameObject;
if (m_healFX)
{
GameObject instance = Instantiate(m_healFX, null);
m_healFParticles = instance.GetComponentInChildren<ParticleSystem>();
m_healFParticles?.Stop(true);
}
}
protected void Update()
{
// Healer timer
if(!m_canHeal)
{
if(Time.time - m_lastTimeHealing >= m_healCooldown)
{
m_lastTimeHealing = Time.time;
m_canHeal = true;
}
}
}
protected new void OnEnable()
{
base.OnEnable();
agent?.OnHit.AddListener(CallForCover);
}
protected new void OnDisable()
{
base.OnDisable();
Target = null;
agent?.OnHit.RemoveListener(CallForCover);
}
private void OnDestroy()
{
Target = null;
}
#endregion
#region Functions
public float TargetHealNeedFactor()
{
return m_target != null && m_target.gameObject.activeInHierarchy ? Mathf.Max(1f - m_target.agent.GetLifePercent(), 0f) : 0f;
}
public void Heal()
{
Vector3 targetPos = m_target.transform.position;
Vector3 position = targetPos + Vector3.Normalize(transform.position - targetPos) * m_healingRadius;
movement.MoveTo(position);
if (Vector3.SqrMagnitude(position - transform.position) <= m_healingRadius * m_healingRadius)
{
TryStartParticles();
if (m_canHeal && m_target.agent.AddHealth(m_healPower))
{
// Stop healing
Target = null;
}
m_canHeal = false;
}
}
private void TryStartParticles()
{
if (m_healFParticles && !m_healFParticles.isPlaying)
{
m_healFParticles.Play();
m_healFParticles.transform.SetParent(m_target.transform);
m_healFParticles.transform.localPosition = Vector3.zero;
}
}
public void CallForCover()
{
m_squad.AssignSupportTo(this);
}
public override bool HasDuty()
{
return TargetHealNeedFactor() > 0f;
}
#endregion
}