-
Notifications
You must be signed in to change notification settings - Fork 0
/
PlayerWeaponManager.cs
156 lines (131 loc) · 4.56 KB
/
PlayerWeaponManager.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
using UnityEngine;
using System.Collections.Generic;
public class PlayerWeaponManager : MonoBehaviour {
public AbstractPlayer player {get; private set;}
public List<GameObject> weaponBag; // Weapon instance. Operations must be sync between weaponBag and prefabDefinition
public int maxWeapons = 3;
public GameObject pickablePrefab;
public int weaponCurrent {get; set;} = -1; // -1 means no weapon.
public bool AddBlueprintWeapon(GameObject weaponPrefab) {
if(weaponBag.Capacity == weaponBag.Count) {
return false;
}
weaponBag.Add(InstantiateWeapon(weaponPrefab));
return true;
}
public bool AddExistWeapon(GameObject weaponInstance) {
if(weaponBag.Capacity == weaponBag.Count) {
return false;
}
// IMPORTANT ! Otherwise, when player picks up weapon, the weapon object is stil at the root of pickable.
// Then it will be deleted by weaponPickable, leaving a null reference to an object, which causes a bunch of errors.
AttachWeaponToPlayer(weaponInstance);
weaponBag.Add(weaponInstance);
return true;
}
// Set weapon instance to player cam root. Do this after every instantiation.
private void AttachWeaponToPlayer(GameObject weaponInstance) {
// Let the weapon move with cam
weaponInstance.transform.parent = player.mainCamera.transform;
// Make child collider useless
ToggleChildColliders(weaponInstance, false);
// Deactive unequipped weapons
weaponInstance.SetActive(false);
}
// Construct weapon instance by prefab definitions.
public GameObject InstantiateWeapon(GameObject weaponPrefab) {
GameObject obj = Instantiate<GameObject>(weaponPrefab);
AttachWeaponToPlayer(obj);
return obj;
}
public bool IsEmpty() {
return weaponBag.Count == 0;
}
public void RemoveWeapon(int index) {
// Destroy(weaponBag[index]);
weaponBag.RemoveAt(index);
}
// Destroy all attached information, create a model
public GameObject ThrowWeapon(int index) {
GameObject weaponInstance = weaponBag[index];
GameObject pickable = Instantiate<GameObject>(pickablePrefab);
WeaponPickable weaponPickable = pickable.GetComponent<WeaponPickable>();
weaponPickable.needInstantiation = false;
weaponPickable.weaponPrefab = weaponInstance;
BaseWeapon weaponData = weaponInstance.GetComponent<BaseWeapon>();
weaponData.owner = null;
weaponInstance.transform.SetParent(pickable.transform);
RemoveWeapon(index);
weaponCurrent = (int)Mathf.Clamp(weaponCurrent, 0, weaponBag.Count-1);
PrintList();
EquipWeapon(weaponCurrent);
return pickable;
}
public bool EquipEmpty() {
player.weaponPrefab = null;
return true;
}
// Set player's weapon prefab and weapon data.
public void EquipWeapon(int index) {
if(index >= 0 && index < weaponBag.Count) {
GameObject weaponInstance = weaponBag[index];
BaseWeapon baseWeapon = weaponInstance.GetComponent<BaseWeapon>();
player.weaponPrefab = weaponInstance;
player.weaponData = baseWeapon;
baseWeapon.owner = player;
baseWeapon.ownerIsPlayer = true;
baseWeapon.ResizeCrossHair();
// Init weapon's place.
baseWeapon.transform.position = player.anchor.transform.position;
// Handle deriviation relations in order to make animation system works properly.
baseWeapon.transform.SetParent(player.anchor.transform);
if(weaponCurrent != -1) {
// Disable old weapon.
weaponBag[weaponCurrent].SetActive(false);
}
weaponCurrent = index;
weaponBag[weaponCurrent].SetActive(true);
} else {
// @Warning: empty weapon will not be allowed
EquipEmpty();
}
}
private void ToggleChildColliders(GameObject weaponInstance, bool enabled) {
Collider[] childColliders = weaponInstance.GetComponentsInChildren<Collider>();
foreach(Collider collider in childColliders) {
collider.enabled = enabled;
}
}
// Whether the weapon to equip exists.
public bool CanEquip(int index) {
return index < weaponBag.Count && weaponBag[index] != null;
}
// Get next available weapon slot.
// asc = 1 | -1
public int GetNextAvailable(int asc) {
int nextpos = weaponCurrent + asc;
int currentLength = weaponBag.Count;
if(nextpos >= currentLength) {
nextpos = 0;
} else if (nextpos < 0) {
nextpos = currentLength - 1;
}
return nextpos;
}
// Reset current weapon number.
// @Warning : Should only be executed once!
public void Init(AbstractPlayer player) {
this.player = player;
weaponBag.Capacity = maxWeapons;
for(int i=0; i<weaponBag.Count; i++) {
weaponBag[i] = InstantiateWeapon(weaponBag[i]);
}
}
public void PrintList() {
string sb = "[LIST]";
foreach(GameObject obj in weaponBag) {
sb += obj.ToString();
}
Debug.Log(sb);
}
}