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(); if(HasEquipedItem()) { ItemContainer itemContainer = gameObject.GetComponent(); //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(); if(rigidbody != null) Destroy(rigidbody); rigidbody = gameObject.GetComponentInChildren(); if(rigidbody != null) Destroy(rigidbody); // Disable character collider CapsuleCollider collider = gameObject.GetComponent(); if(collider != null) collider.enabled = false; BoxCollider boxCollider = gameObject.GetComponentInChildren(); if(boxCollider != null) boxCollider.enabled = false; // Remove hand damage objects Rigidbody rightHandRigidbody = rightHand.GetComponentInChildren(); Rigidbody leftHandRigidbody = leftHand.GetComponentInChildren(); if(rightHandRigidbody != null) Destroy(rightHandRigidbody); if(leftHandRigidbody != null) Destroy(leftHandRigidbody); // Remove Head rigidbody and DamagePoint Rigidbody headRigidbody = head.GetComponent(); if(headRigidbody != null) Destroy(headRigidbody); DamagePoint damagePoint = head.GetComponent(); 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(); 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(); 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(); if(targetCharacter == null) return false; if(targetCharacter.IsDead()) return false; return faction.IsEnemy(targetCharacter.faction.title); } public ItemRef GetEquipableWeapon() { ItemContainer itemContainer = GetComponent(); 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(); // for (int i = 0; i < colliders.Length; i++) // { // Destroy(colliders[i]); // } // ConfigurableJoint[] joints = gameObject.transform.root.GetComponentsInChildren(); // for (int i = 0; i < joints.Length; i++) // { // Destroy(joints[i]); // } // Rigidbody[] rigidbodies = gameObject.transform.root.GetComponentsInChildren(); // for (int i = 0; i < rigidbodies.Length; i++) // { // Destroy(rigidbodies[i]); // } } } }