CharacterController.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1.  using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. using RootMotion.Dynamics;
  6. using SensorToolkit;
  7. using Sirenix.OdinInspector;
  8. using KairoEngine.Core;
  9. using KairoEngine.Inventory;
  10. namespace KairoEngine.CharacterSystem
  11. {
  12. public class CharacterController : MonoBehaviour
  13. {
  14. [HorizontalGroup("Name"), LabelText("Name")] public string characterName;
  15. [HorizontalGroup("Name", 0.2f), ReadOnly, HideLabel] public string id;
  16. public string unique_name
  17. {
  18. get { return $"{characterName}_{id}"; }
  19. }
  20. public Race race;
  21. public Faction faction;
  22. public Gender gender;
  23. public int age;
  24. public Animator animator;
  25. public NavMeshAgent navMeshAgent;
  26. public TriggerSensor visionSensor;
  27. public RangeSensor hearingSensor;
  28. public SkinnedMeshRenderer meshRenderer;
  29. public DamageController damageController;
  30. public PuppetMaster puppetMaster;
  31. public GameObject puppetMasterRoot;
  32. public ItemContainer itemContainer;
  33. public Transform rootTransform;
  34. public GameObject head;
  35. public GameObject rightHand;
  36. public GameObject leftHand;
  37. public GameObject rightUnarmedObject;
  38. public GameObject leftUnarmedObject;
  39. [ReadOnly] public string bodyModelName;
  40. [ReadOnly] public string bodyMaterialName;
  41. [ReadOnly] public string headAttachmentName;
  42. [ReadOnly] public string faceAttachmentName;
  43. private ItemRef equipedItem;
  44. private GameObject equipedGameObject;
  45. private bool isDead = false;
  46. private float deadTime = 0f;
  47. private bool removeColliders = false;
  48. public void Start()
  49. {
  50. if(rightUnarmedObject != null) rightUnarmedObject.SetActive(false);
  51. else Debug.LogError(unique_name + " has no rightUnarmedObject!");
  52. if(leftUnarmedObject != null) leftUnarmedObject.SetActive(false);
  53. else Debug.LogError(unique_name + " has no leftUnarmedObject!");
  54. if(rootTransform != null) rootTransform.parent = null;
  55. // Register this character in CharacterManager
  56. RegisterEvents.RegisterCharacter(this);
  57. }
  58. public void Die()
  59. {
  60. if(isDead == true) return;
  61. animator.SetTrigger("Death");
  62. isDead = true;
  63. ActionController actionController = gameObject.GetComponent<ActionController>();
  64. if(HasEquipedItem())
  65. {
  66. ItemContainer itemContainer = gameObject.GetComponent<ItemContainer>();
  67. //DropItemAction action = new DropItemAction(itemContainer, GetEquipedItem());
  68. CharacterUnequipItemAction action = new CharacterUnequipItemAction(this);
  69. actionController.AddAction(action);
  70. GameObject.Destroy(GetEquipedGameObject());
  71. SetEquipedItem(null);
  72. SetEquipedGameObject(null);
  73. }
  74. actionController.CancelActions();
  75. actionController.enabled = false;
  76. if(navMeshAgent != null) navMeshAgent.enabled = false;
  77. // Remove character rigidbody
  78. Rigidbody rigidbody = gameObject.GetComponent<Rigidbody>();
  79. if(rigidbody != null) Destroy(rigidbody);
  80. rigidbody = gameObject.GetComponentInChildren<Rigidbody>();
  81. if(rigidbody != null) Destroy(rigidbody);
  82. // Disable character collider
  83. CapsuleCollider collider = gameObject.GetComponent<CapsuleCollider>();
  84. if(collider != null) collider.enabled = false;
  85. BoxCollider boxCollider = gameObject.GetComponentInChildren<BoxCollider>();
  86. if(boxCollider != null) boxCollider.enabled = false;
  87. // Remove hand damage objects
  88. Rigidbody rightHandRigidbody = rightHand.GetComponentInChildren<Rigidbody>();
  89. Rigidbody leftHandRigidbody = leftHand.GetComponentInChildren<Rigidbody>();
  90. if(rightHandRigidbody != null) Destroy(rightHandRigidbody);
  91. if(leftHandRigidbody != null) Destroy(leftHandRigidbody);
  92. // Remove Head rigidbody and DamagePoint
  93. Rigidbody headRigidbody = head.GetComponent<Rigidbody>();
  94. if(headRigidbody != null) Destroy(headRigidbody);
  95. DamagePoint damagePoint = head.GetComponent<DamagePoint>();
  96. if(damagePoint != null) Destroy(damagePoint);
  97. if(visionSensor != null) visionSensor.gameObject.SetActive(false);
  98. if(hearingSensor != null) hearingSensor.gameObject.SetActive(false);
  99. // Disable IKs
  100. SetAimIK setAimIK = gameObject.GetComponentInChildren<SetAimIK>();
  101. if(setAimIK != null)
  102. {
  103. setAimIK.aimIK.enabled = false;
  104. setAimIK.limbIK.enabled = false;
  105. setAimIK.secondHandOnGun.enabled = false;
  106. setAimIK.aimController.enabled = false;
  107. setAimIK.enabled = false;
  108. }
  109. //animator.enabled = false;
  110. if(puppetMaster != null)
  111. {
  112. puppetMaster.mode = PuppetMaster.Mode.Active;
  113. puppetMaster.pinWeight = 0f;
  114. puppetMaster.mappingWeight = 1f;
  115. puppetMaster.muscleWeight = 0.4f;
  116. }
  117. puppetMaster.gameObject.SetActive(true);
  118. }
  119. public bool IsDead()
  120. {
  121. return isDead;
  122. }
  123. public void Injury()
  124. {
  125. animator.SetTrigger("Injury");
  126. }
  127. public void Update()
  128. {
  129. animator.transform.localPosition = new Vector3(0, 0, 0);
  130. if(isDead)
  131. {
  132. deadTime += Time.deltaTime;
  133. puppetMaster.gameObject.SetActive(true);
  134. if(deadTime > 5f && removeColliders == false)
  135. {
  136. removeColliders = true;
  137. puppetMaster.state = PuppetMaster.State.Dead;
  138. //RemoveColliders();
  139. }
  140. }
  141. }
  142. public bool HasEquipedItem()
  143. {
  144. if(equipedItem != null) return true;
  145. else return false;
  146. }
  147. public ItemRef GetEquipedItem()
  148. {
  149. return equipedItem;
  150. }
  151. public void SetEquipedItem(ItemRef itemRef)
  152. {
  153. equipedItem = itemRef;
  154. }
  155. public GameObject GetEquipedGameObject()
  156. {
  157. return equipedGameObject;
  158. }
  159. public void SetEquipedGameObject(GameObject obj)
  160. {
  161. equipedGameObject = obj;
  162. }
  163. public bool HasRangedWeapon()
  164. {
  165. ItemRef itemRef = GetEquipedItem();
  166. if(itemRef != null)
  167. {
  168. if(itemRef.item.category == ItemType.firearm) return true;
  169. }
  170. return false;
  171. }
  172. public bool HasMeleeWeapon()
  173. {
  174. ItemRef itemRef = GetEquipedItem();
  175. if(itemRef != null)
  176. {
  177. if(itemRef.item.category == ItemType.handWeapon) return true;
  178. }
  179. return false;
  180. }
  181. public bool HasAmmo()
  182. {
  183. if(HasRangedWeapon() == false) return false;
  184. ItemRef itemRef = GetEquipedItem();
  185. if(itemRef == null) return false;
  186. ItemFirearmRef firearmRef = (ItemFirearmRef)itemRef;
  187. if(firearmRef == null) return false;
  188. if(firearmRef.ammo > 0) return true;
  189. else return false;
  190. }
  191. public bool HasSpareAmmo(ItemRef itemRef = null)
  192. {
  193. if(itemRef == null) itemRef = GetEquipedItem();
  194. if(itemRef == null) return false;
  195. ItemBaseFirearm firearmItem = (ItemBaseFirearm)itemRef.item;
  196. if(firearmItem == null) return false;
  197. ItemContainer itemContainer = GetComponent<ItemContainer>();
  198. if(itemContainer == null) return false;
  199. for (int i = 0; i < itemContainer.inventory.Count; i++)
  200. {
  201. if(itemContainer.inventory[i].item.title == firearmItem.ammoType.title) return true;
  202. }
  203. return false;
  204. }
  205. public bool IsEnemy(Transform objTransform)
  206. {
  207. CharacterController targetCharacter = objTransform.GetComponentInParent<CharacterController>();
  208. if(targetCharacter == null) return false;
  209. if(targetCharacter.IsDead()) return false;
  210. return faction.IsEnemy(targetCharacter.faction.title);
  211. }
  212. public ItemRef GetEquipableWeapon()
  213. {
  214. ItemContainer itemContainer = GetComponent<ItemContainer>();
  215. if(itemContainer == null) return null;
  216. for (int i = 0; i < itemContainer.inventory.Count; i++)
  217. {
  218. if(itemContainer.inventory[i].item.category == ItemType.firearm)
  219. {
  220. if(HasSpareAmmo(itemContainer.inventory[i]))
  221. {
  222. return itemContainer.inventory[i];
  223. }
  224. }
  225. }
  226. for (int i = 0; i < itemContainer.inventory.Count; i++)
  227. {
  228. if(itemContainer.inventory[i].item.category == ItemType.handWeapon)
  229. {
  230. return itemContainer.inventory[i];
  231. }
  232. }
  233. return null;
  234. }
  235. public float GetAttackDistance(ItemRef itemRef = null)
  236. {
  237. if(itemRef == null) itemRef = GetEquipedItem();
  238. if(itemRef == null) return 0.8f;
  239. if(itemRef.item.category == ItemType.firearm)
  240. {
  241. ItemBaseFirearm firearmItem = (ItemBaseFirearm)itemRef.item;
  242. return ((firearmItem.maxDistance - firearmItem.halfDistance)/2) + firearmItem.halfDistance;
  243. }
  244. else if(itemRef.item.category == ItemType.handWeapon)
  245. {
  246. ItemBaseHandWeapon handWeapon = (ItemBaseHandWeapon)itemRef.item;
  247. return handWeapon.attackDistance;
  248. }
  249. return 0.8f;
  250. }
  251. public void RemoveColliders()
  252. {
  253. if(puppetMaster != null)
  254. {
  255. //puppetMaster.pinWeight = 0f;
  256. //puppetMaster.mappingWeight = 1f;
  257. //puppetMaster.muscleWeight = 0f;
  258. puppetMaster.state = PuppetMaster.State.Frozen;
  259. }
  260. // Collider[] colliders = gameObject.transform.root.GetComponentsInChildren<Collider>();
  261. // for (int i = 0; i < colliders.Length; i++)
  262. // {
  263. // Destroy(colliders[i]);
  264. // }
  265. // ConfigurableJoint[] joints = gameObject.transform.root.GetComponentsInChildren<ConfigurableJoint>();
  266. // for (int i = 0; i < joints.Length; i++)
  267. // {
  268. // Destroy(joints[i]);
  269. // }
  270. // Rigidbody[] rigidbodies = gameObject.transform.root.GetComponentsInChildren<Rigidbody>();
  271. // for (int i = 0; i < rigidbodies.Length; i++)
  272. // {
  273. // Destroy(rigidbodies[i]);
  274. // }
  275. }
  276. }
  277. }