301 lines
8.2 KiB
C#
301 lines
8.2 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);
|
|
}
|
|
}
|
|
|
|
[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<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
|
|
}
|