zombie_mp/Assets/Scripts/zombies/zombieBehaviour.cs
2021-11-13 18:59:45 +05:30

306 lines
8.4 KiB
C#

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<GameObject> dropOnDie;
public UnityEvent OnDie;
public bool patrol = false;
public bool kinematicState;
[HideInInspector]
public int effectIdx;
void Start()
{
anim = GetComponentInChildren<Animator>();
if (!isServer) { Destroy(GetComponent<NavMeshAgent>()); return; }
agent = GetComponent<NavMeshAgent>();
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<zombieBehaviour>();
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<CharacterController>().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<Transform>();
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<Rigidbody>();
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<netPlayer>().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);
}else{
Dmg(dmg);
}
}
[Command(requiresAuthority =false)]
public void CmdDmg(float damage)
{
Dmg(damage);
}
void Dmg(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()
{
if(isServer){return;}
die();
}
public void die()
{
Collider[] bodies = GetComponentsInChildren<Collider>();
foreach (Collider collider in bodies)
{
collider.gameObject.layer = 6;
}
//anim.CrossFadeInFixedTime("die", 0.1f);
SetKinematic(false);
if (GetComponent<NetworkAnimator>() != null) { Destroy(GetComponent<NetworkAnimator>()); }
Destroy(anim);
Destroy(GetComponent<AudioSource>());
// OnDie.Invoke();
float lastX = 0;
foreach (GameObject go in dropOnDie)
{
go.transform.parent = null;
if (go.GetComponent<Rigidbody>() != null)
{
go.GetComponent<Rigidbody>().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
}