using HQFPSWeapons; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; using Mirror; public class zombieBehaviour : NetworkBehaviour { public Transform player; public float curDistance; public float minDistance = 10; float defaultSpeed; NavMeshAgent agent; Animator anim; [Header("Health")] [SyncVar] public float health = 100; // public GameObject bloodPrefab; public GameObject BloodAttach; public GameObject[] BloodFX; [Header("Attack")] public float damage = 1; public float attackTime = 2; public float t; public bool acceptCommonItems = true; public List dropOnDie; public UnityEvent OnDie; public bool patrol = false; public bool kinematicState; [HideInInspector] public int effectIdx; void Start() { anim = GetComponentInChildren(); if (!isServer) { Destroy(GetComponent()); return; } agent = GetComponent(); t = attackTime; defaultSpeed = agent.speed; SetKinematic(true); StartCoroutine(lookForHoards()); minDistance += Random.Range(-minDistance / 5f, minDistance / 5f); } bool chasing = false; bool higherPlace = false; // Update is called once per frame IEnumerator lookForHoards() { while (true) { zombieBehaviour[] zombies = FindObjectsOfType(); foreach (zombieBehaviour zombie in zombies) { if (Vector3.Distance(transform.position, zombie.transform.position) < minDistance) { if (zombie.chasing) { chasing = true; break; } } } yield return new WaitForSeconds(1); } } void Update() { if (!isServer) { return; } if (player == null) { player = m_zombieArea.giveMePlayer(); return; } curDistance = Vector3.Distance(transform.position, new Vector3(player.position.x, transform.position.y, player.position.z)); // Debug.Log(player.GetComponent().isGrounded); // if (chasing && player != null) { agent.SetDestination(player.position); return; } float dist = curDistance; if (dist > agent.stoppingDistance) { } if (dist < minDistance || chasing) { if (agent.stoppingDistance > dist || higherPlace) { _attack(); } else { t = attackTime; } /* else if(anim.GetCurrentAnimatorStateInfo(0).IsName("Attack")) { t = 0; anim.CrossFadeInFixedTime("Idle", 0.1f); }*/ transform.LookAt(new Vector3(player.position.x, transform.position.y, player.position.z)); // if (anim.GetCurrentAnimatorStateInfo(0).IsName("Attack") || higherPlace) { return; } NavMeshHit hit; if (NavMesh.SamplePosition(player.position, out hit, 2.0f, NavMesh.AllAreas)) { if (!Mathf.Approximately(player.position.y, hit.position.y)) { // Debug.Log("D:"+Vector3.Distance(transform.position,hit.position)); if (Vector3.Distance(transform.position, hit.position) < 1.5f ) { Debug.Log("Attack for higher"); higherPlace = true; } else { higherPlace = false; } // _attack(); } agent.SetDestination(hit.position); } chasing = true; anim.SetBool("moving", (dist > agent.stoppingDistance)); agent.speed = defaultSpeed; } else { agent.speed = defaultSpeed / 10f; if (!patrol) { agent.destination = transform.position; anim.SetBool("moving", false); anim.SetBool("walking", false); } else {/* anim.SetBool("walking", true); Transform[] pathObjs = pathParent.GetComponentsInChildren(); if (Vector3.Distance(transform.position, pathObjs[curPathIndex].position) > minDistToPath) { agent.SetDestination(pathObjs[curPathIndex].position); } else { if (curPathIndex < pathObjs.Length - 1) { curPathIndex++; } else { curPathIndex = 0; } } */ } } } public void SetKinematic(bool newValue) { Rigidbody[] bodies = GetComponentsInChildren(); foreach (Rigidbody rb in bodies) { rb.isKinematic = newValue; rb.tag = "Zombie"; // rb.gameObject.layer = (newValue) ? 0 : 11; } kinematicState = newValue; if(agent!=null)agent.enabled = newValue; } void _attack() { if (t < attackTime) { t += Time.deltaTime; return; } else { anim.CrossFadeInFixedTime("Attack", 0.1f); StartCoroutine(attack()); Debug.Log("Done damages 2"); t = 0; } } IEnumerator attack() { yield return new WaitForSeconds(0.5f); // if (agent.stoppingDistance > Vector3.Distance(player.position, transform.position)) // { player.GetComponent().callDamage(damage); Debug.Log("Done damages"); // } } public zombieManager m_zombieArea; public void hitboxDamage(HealthEventData damageData, shotType hitboxType) { float dmg = 0; switch (hitboxType) { case shotType.headshot: dmg = damageData.Delta * 5; break; case shotType.chestshot: dmg = damageData.Delta; break; case shotType.legshot: dmg = damageData.Delta / 2f; break; } if (!isServer) { CmdDmg(dmg); } } [Command(requiresAuthority =false)] public void CmdDmg(float damage) { health += damage; chasing = true; // Debug.Log("shotY : " + damageData.HitPoint.y + " ,chestBottom : " + chestBottom + " ,headBottom" + headBottom); // Instantiate(bloodPrefab, damageData.HitPoint, Quaternion.Euler(damageData.HitDirection)); if (health < 0) { health = 0; if (m_zombieArea != null) { m_zombieArea.currentZombies.Remove(gameObject); } Destroy(agent); die(); RpcDie(); } } [ClientRpc] public void RpcDie() { die(); } public void die() { Collider[] bodies = GetComponentsInChildren(); foreach (Collider collider in bodies) { collider.gameObject.layer = 6; } //anim.CrossFadeInFixedTime("die", 0.1f); SetKinematic(false); if (GetComponent() != null) { Destroy(GetComponent()); } Destroy(anim); Destroy(GetComponent()); // OnDie.Invoke(); float lastX = 0; foreach (GameObject go in dropOnDie) { go.transform.parent = null; if (go.GetComponent() != null) { go.GetComponent().velocity = Vector3.zero; } go.transform.position += new Vector3(lastX, 0, 0); lastX += go.transform.lossyScale.x / 2f; go.SetActive(true); } Destroy(this); } } public enum shotType { headshot, chestshot, legshot }