|
@@ -0,0 +1,303 @@
|
|
|
+ using System.Collections;
|
|
|
+using System.Collections.Generic;
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.AI;
|
|
|
+using RootMotion.Dynamics;
|
|
|
+using SensorToolkit;
|
|
|
+using Sirenix.OdinInspector;
|
|
|
+using KairoEngine.Core;
|
|
|
+using KairoEngine.Inventory;
|
|
|
+
|
|
|
+namespace KairoEngine.CharacterSystem
|
|
|
+{
|
|
|
+ public class CharacterController : MonoBehaviour
|
|
|
+ {
|
|
|
+ [HorizontalGroup("Name"), LabelText("Name")] public string characterName;
|
|
|
+ [HorizontalGroup("Name", 0.2f), ReadOnly, HideLabel] public string id;
|
|
|
+ public string unique_name
|
|
|
+ {
|
|
|
+ get { return $"{characterName}_{id}"; }
|
|
|
+ }
|
|
|
+ public Race race;
|
|
|
+ public Faction faction;
|
|
|
+ public Gender gender;
|
|
|
+ public int age;
|
|
|
+ public Animator animator;
|
|
|
+ public NavMeshAgent navMeshAgent;
|
|
|
+ public TriggerSensor visionSensor;
|
|
|
+ public RangeSensor hearingSensor;
|
|
|
+ public SkinnedMeshRenderer meshRenderer;
|
|
|
+ public DamageController damageController;
|
|
|
+ public PuppetMaster puppetMaster;
|
|
|
+ public GameObject puppetMasterRoot;
|
|
|
+ public ItemContainer itemContainer;
|
|
|
+ public Transform rootTransform;
|
|
|
+
|
|
|
+ public GameObject head;
|
|
|
+ public GameObject rightHand;
|
|
|
+ public GameObject leftHand;
|
|
|
+
|
|
|
+ public GameObject rightUnarmedObject;
|
|
|
+ public GameObject leftUnarmedObject;
|
|
|
+
|
|
|
+ [ReadOnly] public string bodyModelName;
|
|
|
+ [ReadOnly] public string bodyMaterialName;
|
|
|
+ [ReadOnly] public string headAttachmentName;
|
|
|
+ [ReadOnly] public string faceAttachmentName;
|
|
|
+
|
|
|
+ private ItemRef equipedItem;
|
|
|
+ private GameObject equipedGameObject;
|
|
|
+ private bool isDead = false;
|
|
|
+ private float deadTime = 0f;
|
|
|
+ private bool removeColliders = false;
|
|
|
+
|
|
|
+ public void Start()
|
|
|
+ {
|
|
|
+ if(rightUnarmedObject != null) rightUnarmedObject.SetActive(false);
|
|
|
+ else Debug.LogError(unique_name + " has no rightUnarmedObject!");
|
|
|
+ if(leftUnarmedObject != null) leftUnarmedObject.SetActive(false);
|
|
|
+ else Debug.LogError(unique_name + " has no leftUnarmedObject!");
|
|
|
+ if(rootTransform != null) rootTransform.parent = null;
|
|
|
+ // Register this character in CharacterManager
|
|
|
+ RegisterEvents.RegisterCharacter(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Die()
|
|
|
+ {
|
|
|
+ if(isDead == true) return;
|
|
|
+ animator.SetTrigger("Death");
|
|
|
+ isDead = true;
|
|
|
+ ActionController actionController = gameObject.GetComponent<ActionController>();
|
|
|
+ if(HasEquipedItem())
|
|
|
+ {
|
|
|
+ ItemContainer itemContainer = gameObject.GetComponent<ItemContainer>();
|
|
|
+ //DropItemAction action = new DropItemAction(itemContainer, GetEquipedItem());
|
|
|
+ CharacterUnequipItemAction action = new CharacterUnequipItemAction(this);
|
|
|
+ actionController.AddAction(action);
|
|
|
+ GameObject.Destroy(GetEquipedGameObject());
|
|
|
+ SetEquipedItem(null);
|
|
|
+ SetEquipedGameObject(null);
|
|
|
+ }
|
|
|
+ actionController.CancelActions();
|
|
|
+ actionController.enabled = false;
|
|
|
+ if(navMeshAgent != null) navMeshAgent.enabled = false;
|
|
|
+ // Remove character rigidbody
|
|
|
+ Rigidbody rigidbody = gameObject.GetComponent<Rigidbody>();
|
|
|
+ if(rigidbody != null) Destroy(rigidbody);
|
|
|
+ rigidbody = gameObject.GetComponentInChildren<Rigidbody>();
|
|
|
+ if(rigidbody != null) Destroy(rigidbody);
|
|
|
+ // Disable character collider
|
|
|
+ CapsuleCollider collider = gameObject.GetComponent<CapsuleCollider>();
|
|
|
+ if(collider != null) collider.enabled = false;
|
|
|
+ BoxCollider boxCollider = gameObject.GetComponentInChildren<BoxCollider>();
|
|
|
+ if(boxCollider != null) boxCollider.enabled = false;
|
|
|
+ // Remove hand damage objects
|
|
|
+ Rigidbody rightHandRigidbody = rightHand.GetComponentInChildren<Rigidbody>();
|
|
|
+ Rigidbody leftHandRigidbody = leftHand.GetComponentInChildren<Rigidbody>();
|
|
|
+ if(rightHandRigidbody != null) Destroy(rightHandRigidbody);
|
|
|
+ if(leftHandRigidbody != null) Destroy(leftHandRigidbody);
|
|
|
+ // Remove Head rigidbody and DamagePoint
|
|
|
+ Rigidbody headRigidbody = head.GetComponent<Rigidbody>();
|
|
|
+ if(headRigidbody != null) Destroy(headRigidbody);
|
|
|
+ DamagePoint damagePoint = head.GetComponent<DamagePoint>();
|
|
|
+ if(damagePoint != null) Destroy(damagePoint);
|
|
|
+ if(visionSensor != null) visionSensor.gameObject.SetActive(false);
|
|
|
+ if(hearingSensor != null) hearingSensor.gameObject.SetActive(false);
|
|
|
+ // Disable IKs
|
|
|
+ SetAimIK setAimIK = gameObject.GetComponentInChildren<SetAimIK>();
|
|
|
+ if(setAimIK != null)
|
|
|
+ {
|
|
|
+ setAimIK.aimIK.enabled = false;
|
|
|
+ setAimIK.limbIK.enabled = false;
|
|
|
+ setAimIK.secondHandOnGun.enabled = false;
|
|
|
+ setAimIK.aimController.enabled = false;
|
|
|
+ setAimIK.enabled = false;
|
|
|
+ }
|
|
|
+ //animator.enabled = false;
|
|
|
+ if(puppetMaster != null)
|
|
|
+ {
|
|
|
+ puppetMaster.mode = PuppetMaster.Mode.Active;
|
|
|
+ puppetMaster.pinWeight = 0f;
|
|
|
+ puppetMaster.mappingWeight = 1f;
|
|
|
+ puppetMaster.muscleWeight = 0.4f;
|
|
|
+ }
|
|
|
+ puppetMaster.gameObject.SetActive(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool IsDead()
|
|
|
+ {
|
|
|
+ return isDead;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Injury()
|
|
|
+ {
|
|
|
+ animator.SetTrigger("Injury");
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Update()
|
|
|
+ {
|
|
|
+ animator.transform.localPosition = new Vector3(0, 0, 0);
|
|
|
+ if(isDead)
|
|
|
+ {
|
|
|
+ deadTime += Time.deltaTime;
|
|
|
+ puppetMaster.gameObject.SetActive(true);
|
|
|
+ if(deadTime > 5f && removeColliders == false)
|
|
|
+ {
|
|
|
+ removeColliders = true;
|
|
|
+ puppetMaster.state = PuppetMaster.State.Dead;
|
|
|
+ //RemoveColliders();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool HasEquipedItem()
|
|
|
+ {
|
|
|
+ if(equipedItem != null) return true;
|
|
|
+ else return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ItemRef GetEquipedItem()
|
|
|
+ {
|
|
|
+ return equipedItem;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void SetEquipedItem(ItemRef itemRef)
|
|
|
+ {
|
|
|
+ equipedItem = itemRef;
|
|
|
+ }
|
|
|
+
|
|
|
+ public GameObject GetEquipedGameObject()
|
|
|
+ {
|
|
|
+ return equipedGameObject;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void SetEquipedGameObject(GameObject obj)
|
|
|
+ {
|
|
|
+ equipedGameObject = obj;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool HasRangedWeapon()
|
|
|
+ {
|
|
|
+ ItemRef itemRef = GetEquipedItem();
|
|
|
+ if(itemRef != null)
|
|
|
+ {
|
|
|
+ if(itemRef.item.category == ItemType.firearm) return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool HasMeleeWeapon()
|
|
|
+ {
|
|
|
+ ItemRef itemRef = GetEquipedItem();
|
|
|
+ if(itemRef != null)
|
|
|
+ {
|
|
|
+ if(itemRef.item.category == ItemType.handWeapon) return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool HasAmmo()
|
|
|
+ {
|
|
|
+ if(HasRangedWeapon() == false) return false;
|
|
|
+ ItemRef itemRef = GetEquipedItem();
|
|
|
+ if(itemRef == null) return false;
|
|
|
+ ItemFirearmRef firearmRef = (ItemFirearmRef)itemRef;
|
|
|
+ if(firearmRef == null) return false;
|
|
|
+ if(firearmRef.ammo > 0) return true;
|
|
|
+ else return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool HasSpareAmmo(ItemRef itemRef = null)
|
|
|
+ {
|
|
|
+ if(itemRef == null) itemRef = GetEquipedItem();
|
|
|
+ if(itemRef == null) return false;
|
|
|
+ ItemBaseFirearm firearmItem = (ItemBaseFirearm)itemRef.item;
|
|
|
+ if(firearmItem == null) return false;
|
|
|
+ ItemContainer itemContainer = GetComponent<ItemContainer>();
|
|
|
+ if(itemContainer == null) return false;
|
|
|
+ for (int i = 0; i < itemContainer.inventory.Count; i++)
|
|
|
+ {
|
|
|
+ if(itemContainer.inventory[i].item.title == firearmItem.ammoType.title) return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool IsEnemy(Transform objTransform)
|
|
|
+ {
|
|
|
+ CharacterController targetCharacter = objTransform.GetComponentInParent<CharacterController>();
|
|
|
+ if(targetCharacter == null) return false;
|
|
|
+ if(targetCharacter.IsDead()) return false;
|
|
|
+ return faction.IsEnemy(targetCharacter.faction.title);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ItemRef GetEquipableWeapon()
|
|
|
+ {
|
|
|
+ ItemContainer itemContainer = GetComponent<ItemContainer>();
|
|
|
+ if(itemContainer == null) return null;
|
|
|
+ for (int i = 0; i < itemContainer.inventory.Count; i++)
|
|
|
+ {
|
|
|
+ if(itemContainer.inventory[i].item.category == ItemType.firearm)
|
|
|
+ {
|
|
|
+ if(HasSpareAmmo(itemContainer.inventory[i]))
|
|
|
+ {
|
|
|
+ return itemContainer.inventory[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int i = 0; i < itemContainer.inventory.Count; i++)
|
|
|
+ {
|
|
|
+ if(itemContainer.inventory[i].item.category == ItemType.handWeapon)
|
|
|
+ {
|
|
|
+ return itemContainer.inventory[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public float GetAttackDistance(ItemRef itemRef = null)
|
|
|
+ {
|
|
|
+ if(itemRef == null) itemRef = GetEquipedItem();
|
|
|
+ if(itemRef == null) return 0.8f;
|
|
|
+
|
|
|
+ if(itemRef.item.category == ItemType.firearm)
|
|
|
+ {
|
|
|
+ ItemBaseFirearm firearmItem = (ItemBaseFirearm)itemRef.item;
|
|
|
+ return ((firearmItem.maxDistance - firearmItem.halfDistance)/2) + firearmItem.halfDistance;
|
|
|
+ }
|
|
|
+ else if(itemRef.item.category == ItemType.handWeapon)
|
|
|
+ {
|
|
|
+ ItemBaseHandWeapon handWeapon = (ItemBaseHandWeapon)itemRef.item;
|
|
|
+ return handWeapon.attackDistance;
|
|
|
+ }
|
|
|
+ return 0.8f;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void RemoveColliders()
|
|
|
+ {
|
|
|
+ if(puppetMaster != null)
|
|
|
+ {
|
|
|
+ //puppetMaster.pinWeight = 0f;
|
|
|
+ //puppetMaster.mappingWeight = 1f;
|
|
|
+ //puppetMaster.muscleWeight = 0f;
|
|
|
+ puppetMaster.state = PuppetMaster.State.Frozen;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Collider[] colliders = gameObject.transform.root.GetComponentsInChildren<Collider>();
|
|
|
+ // for (int i = 0; i < colliders.Length; i++)
|
|
|
+ // {
|
|
|
+ // Destroy(colliders[i]);
|
|
|
+ // }
|
|
|
+ // ConfigurableJoint[] joints = gameObject.transform.root.GetComponentsInChildren<ConfigurableJoint>();
|
|
|
+ // for (int i = 0; i < joints.Length; i++)
|
|
|
+ // {
|
|
|
+ // Destroy(joints[i]);
|
|
|
+ // }
|
|
|
+ // Rigidbody[] rigidbodies = gameObject.transform.root.GetComponentsInChildren<Rigidbody>();
|
|
|
+ // for (int i = 0; i < rigidbodies.Length; i++)
|
|
|
+ // {
|
|
|
+ // Destroy(rigidbodies[i]);
|
|
|
+ // }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|