forked from Serinoxxx/NGOAC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NetworkAnimal.cs
228 lines (200 loc) · 8.05 KB
/
NetworkAnimal.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
using MalbersAnimations;
using MalbersAnimations.Controller;
using MalbersAnimations.NetCode;
using MalbersAnimations.Weapons;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Unity.Netcode;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
public class NetworkAnimal : NetworkBehaviour
{
ServerAuthAnimal _animal;
Stats _stats;
public NetworkVariable<float> _healthValue = new NetworkVariable<float>(writePerm: NetworkVariableWritePermission.Owner);
public NetworkVariable<float> _staminaValue = new NetworkVariable<float>(writePerm: NetworkVariableWritePermission.Owner);
public NetworkVariable<float> _visibilityValue = new NetworkVariable<float>(writePerm: NetworkVariableWritePermission.Owner);
[SerializeField] StatID healthStatID;
[SerializeField] StatID staminaStatID;
[SerializeField] StatID visibilityStatID;
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
Debug.Log("Spawning...");
Invoke(nameof(GetComponentsDelayed), 0.1f);
}
// PlayerConectedEvents will add/remove some components, so we need to retrieve the components after a short delay
void GetComponentsDelayed()
{
_animal = GetComponent<ServerAuthAnimal>();
_stats = GetComponent<Stats>();
_animal.OnStateChange.AddListener(OnStateChangeHandler);
_animal.OnModeStart.AddListener(ActivateMode);
_animal.OnModeEnd.AddListener(DeactivateMode);
if (IsOwner)
{
foreach (var attackTrigger in GetComponentsInChildren<MAttackTrigger>())
{
attackTrigger.OnHitPosition.AddListener((x) => HandleAttackTrigger(x, attackTrigger.Index)); //Add the Hit Event to the attackTrigger.transform);
}
}
}
void HandleAttackTrigger(Vector3 position, int attackTriggerIndex)
{
AttackTriggerHitRpc(attackTriggerIndex, position);
}
[Rpc(SendTo.NotOwner)]
void AttackTriggerHitRpc(int attackTriggerIndex, Vector3 position)
{
Debug.Log("RPC CLIENT: attack trigger " + attackTriggerIndex + " hit");
var attackTrigger = GetComponentsInChildren<MAttackTrigger>().FirstOrDefault(x=>x.Index == attackTriggerIndex);
if (attackTrigger != null)
{
Debug.Log("Found attack trigger with index " + attackTriggerIndex);
if (attackTrigger.HitEffect != null)
{
Debug.Log("Spawning hit effect at " + position);
Instantiate(attackTrigger.HitEffect, position, Quaternion.identity);
}
}
else
{
Debug.LogWarning("No attack trigger found with index " + attackTriggerIndex);
}
}
private void ActivateMode(int modeId, int abilityId)
{
ActivateModeRpc(modeId,abilityId);
}
[Rpc(SendTo.NotOwner)]
private void ActivateModeRpc(int modeId, int abilityId)
{
Debug.Log("RPC CLIENT: activating mode " + modeId + " ability " + abilityId);
var mode = _animal.modes.FirstOrDefault(x=>x.ID.ID == modeId);
if (mode != null)
{
mode.OnEnterMode?.Invoke();
var ability = mode.Abilities.FirstOrDefault(x=>x.Index.Value == abilityId);
if (ability != null)
{
ability.OnEnter?.Invoke();
if (ability.audioSource != null)
{
ability.audioSource.Play();
}
}
}
}
private void DeactivateMode(int modeId, int abilityId)
{
DeactivateModeRpc(modeId,abilityId);
}
[Rpc(SendTo.NotOwner)]
private void DeactivateModeRpc(int modeId, int abilityId)
{
Debug.Log("RPC CLIENT: deactivating mode " + modeId + " ability " + abilityId);
var mode = _animal.modes.FirstOrDefault(x=>x.ID.ID == modeId);
if (mode != null)
{
mode.OnExitMode?.Invoke();
var ability = mode.Abilities.FirstOrDefault(x=>x.Index.Value == abilityId);
if (ability != null)
{
ability.OnExit?.Invoke();
}
}
}
private void OnStateChangeHandler(int stateID)
{
if (!IsOwner) return;
Debug.Log($"Informing others of new state: {stateID}");
StateChangedRpc(stateID);
}
[Rpc(SendTo.NotOwner)]
private void StateChangedRpc(int stateID)
{
Debug.Log($"Received new state: {stateID}");
_animal.Set_State(stateID);
_animal.OnStateChange?.Invoke(stateID);
}
private void FixedUpdate()
{
//Return if stats is null
if (_stats == null) return;
//If we're the owner, set the networkVar value to the stat value
if (IsOwner)
{
_healthValue.Value = _stats.Stat_GetValue(healthStatID);
_staminaValue.Value = _stats.Stat_GetValue(staminaStatID);
_visibilityValue.Value = _stats.Stat_GetValue(visibilityStatID);
}
//If we're not the owner, set the stat value to the networkVar value
else
{
_stats.Stat_SetValue(healthStatID, _healthValue.Value);
_stats.Stat_SetValue(staminaStatID, _staminaValue.Value);
_stats.Stat_SetValue(visibilityStatID, _visibilityValue.Value);
}
}
public void ActivateMode(int ModeID)
{
if (IsServer && !IsOwner)
{
Debug.Log($"SERVER: Sending activate mode {ModeID} to owner");
ActivateModeRpc(ModeID);
}
else
{
Debug.Log($"activating mode {ModeID}");
_animal.Mode_TryActivate(ModeID);
}
}
[Rpc(SendTo.Owner)]
private void ActivateModeRpc(int ModeID)
{
Debug.Log($"RPC CLIENT: activating mode {ModeID}");
_animal.Mode_TryActivate(ModeID);
}
public void SpawnProjectileOnOtherClients(GameObject projectileGO)
{
Debug.Log("SpawnProjectileOnOtherClients method called.");
// Send the RPC to all clients except the one invoking the RPC to spawn the projectile with the same trajectory
var projectile = projectileGO.GetComponent<MProjectile>();
SpawnProjectileOnOtherClientsRpc(projectileGO.transform.position, projectileGO.transform.rotation, projectile.Velocity, projectile.Gravity);
}
Vector3 projectilePosition;
Quaternion projectileRotation;
Vector3 projectileVelocity;
Vector3 projectileGravity;
[Rpc(SendTo.NotMe)]
private void SpawnProjectileOnOtherClientsRpc(Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 gravity)
{
projectilePosition = position;
projectileRotation = rotation;
projectileVelocity = velocity;
projectileGravity = gravity;
Debug.Log("SpawnProjectileOnOtherClientsRpc method called.");
var mShootable = GetComponentInChildren<MShootable>();
//Instantiate the projectile from the shootable and apply the position, rotation, velocity and gravity
var projectileGO = Instantiate(mShootable.Projectile, position, rotation);
var projectile = projectileGO.GetComponent<MProjectile>();
projectile.Prepare(gameObject, projectileGravity, projectileVelocity, projectile.m_hitLayer, projectile.TriggerInteraction);
projectileGO.transform.SetPositionAndRotation(projectilePosition, projectileRotation);
projectile.Fire();
//mShootable.EquipProjectile();
//mShootable.OnFireProjectile.AddListener(PrepareProjectile);
//mShootable.FireProjectile();
//mShootable.OnFireProjectile.RemoveListener(PrepareProjectile);
}
private void PrepareProjectile(GameObject projectileGO)
{
var projectile = projectileGO.GetComponent<MProjectile>();
Debug.Log("PositionAndRotateProjectile method called.");
projectile.Prepare(gameObject, projectileGravity, projectileVelocity, projectile.m_hitLayer, projectile.TriggerInteraction);
projectileGO.transform.SetPositionAndRotation(projectilePosition, projectileRotation);
}
}