You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
6.8 KiB
227 lines
6.8 KiB
using System.Collections; |
|
using UnityEngine; |
|
using UnityEngine.AI; |
|
|
|
//战士敌军类 |
|
//带有武器的战士可以使用 |
|
//用于一般敌人,小boss身上 |
|
//会攻击,血量低于一定值时会奔跑 |
|
//拥有攻击间隔及攻击力属性,攻击玩家后不会消失,玩家躲开后会继续追击玩家 |
|
public class GhostWarrior : Hurtable |
|
{ |
|
//数值相关 |
|
//是否碰到玩家 |
|
public bool isTouched; |
|
//是否死亡 |
|
public bool isDeath; |
|
//是否暂停 |
|
public bool isPause; |
|
//怪物的状态(0为行走,1为站立,2为跑步,3为攻击,4为死亡) |
|
private int status; |
|
//怪物的各项属性值(攻击力,护甲值,行走速度,奔跑速度) |
|
public int atk; |
|
public int def; |
|
public float runningSpeed; |
|
public float walkingSpeed; |
|
//显示或与玩家相关 |
|
private GameObject Player; |
|
private Player playerScript; |
|
private float distancePE_; |
|
//敌人发动攻击时离玩家的距离 |
|
private float standTimer; |
|
public float attackDistace; |
|
//玩家所持盾 |
|
private LightShield playerShield_; |
|
//判断攻击对象是不是玩家(不是玩家就是盾牌) |
|
private bool isAttackedPlayer; |
|
//敌人最大生命值 |
|
private float maxHp; |
|
//死亡特效 |
|
public GameObject deathEffect_; |
|
//动作 |
|
public Animator warriorAnime_; |
|
//判断敌人是否愤怒 |
|
private bool isAngry; |
|
|
|
//攻击间隔(以秒计)(攻击过程中进行判定) |
|
public float nextAttackTimer; |
|
//攻击过程中的计时器 |
|
public float attackTimer; |
|
public float attackEndTimer; |
|
//是否处于攻击状态 |
|
private bool isAttacking_; |
|
//是否命中玩家 |
|
private bool isHitPlayer; |
|
//是否被防御(攻击判定圈里有检测到盾牌) |
|
private bool isDefended; |
|
|
|
// Use this for initialization |
|
void Start() |
|
{ |
|
Player = GameObject.FindGameObjectWithTag("Player"); |
|
playerScript = Player.GetComponent<Player>(); |
|
hitEvent.AddListener(GhostAttacked_); |
|
deathEvent.AddListener(GhostDeath_); |
|
status = 0; |
|
standTimer = 0.3f; |
|
isAttackedPlayer = false; |
|
myself_1.GetComponent<NavMeshAgent>().speed = walkingSpeed; |
|
maxHp = hp; |
|
warriorAnime_.SetBool("walk", true); |
|
myself_1.GetComponent<BoxCollider>().enabled = false; |
|
isDefended = false; |
|
} |
|
|
|
// Update is called once per frame |
|
void Update() |
|
{ |
|
distancePE_ = CaculatePlayerDistance(); |
|
if (!isDeath) |
|
{ |
|
GhostAlive_(); |
|
} |
|
//生气了之后2倍速奔跑 |
|
if (hp <= maxHp / 2 && !isAngry) |
|
{ |
|
isAngry = true; |
|
warriorAnime_.SetBool("walk", false); |
|
warriorAnime_.SetBool("run", true); |
|
myself_1.GetComponent<NavMeshAgent>().speed = walkingSpeed * 2; |
|
} |
|
|
|
//敌人攻击相关判定 |
|
if (isAttacking_ && isTouched) { |
|
isHitPlayer = true; |
|
isTouched = false; |
|
} |
|
if (isHitPlayer) { |
|
if (isAttackedPlayer) |
|
{ |
|
//warriorAnime_.SetBool("attack", true); |
|
if (isDefended) |
|
{ |
|
playerShield_.shieldHit(); |
|
} |
|
else { |
|
playerScript.Hurted(atk); |
|
} |
|
isHitPlayer = false; |
|
} |
|
} |
|
|
|
} |
|
|
|
//敌人行为相关 |
|
private void GhostBirth_() |
|
{ |
|
|
|
} |
|
//原地不动 |
|
private void GhostStand_() |
|
{ |
|
myself_1.GetComponent<NavMeshAgent>().destination = myself_1.transform.position; |
|
warriorAnime_.SetBool("walk", false); |
|
warriorAnime_.SetBool("run", false); |
|
} |
|
//行走 |
|
private void GhostWalk_() |
|
{ |
|
//myself_1.transform.position += new Vector3(0, 0, Mathf.Sin(distancePE_) * 0.01f); |
|
myself_1.GetComponent<NavMeshAgent>().destination = Player.transform.position + Player.GetComponent<CapsuleCollider>().center; |
|
} |
|
//跑(这里的跑指最后的冲刺) |
|
private void GhostRun_() |
|
{ |
|
myself_1.GetComponent<NavMeshAgent>().speed = runningSpeed; |
|
warriorAnime_.SetBool("run", true); |
|
GhostWalk_(); |
|
} |
|
//攻击玩家 |
|
private void GhostAttack_() |
|
{ |
|
isHitPlayer = false; |
|
StartCoroutine(AttackAction()); |
|
/*if (isAttackedPlayer) |
|
{ |
|
//warriorAnime_.SetBool("attack", true); |
|
playerScript.Hurted(atk); |
|
}*/ |
|
} |
|
//受到攻击 |
|
private void GhostAttacked_() |
|
{ |
|
myself_1.GetComponentInChildren<Renderer>().material.color = new Vector4(1.0f, hp / maxHp, hp / maxHp, 1.0f); |
|
} |
|
//死亡 |
|
private void GhostDeath_() |
|
{ |
|
status = 4; |
|
isDeath = true; |
|
Instantiate(deathEffect_); |
|
deathEffect_.transform.position = myself_1.transform.position; |
|
int criticalRandom = Random.Range(0, 3); |
|
if (criticalRandom > 1) |
|
{ |
|
playerScript.speedUp(); |
|
} |
|
Destroy(myself_1); |
|
} |
|
|
|
//判断距离相关(计算敌人与玩家的距离) |
|
private float CaculatePlayerDistance() |
|
{ |
|
float posX = myself_1.transform.position.x; |
|
float posZ = myself_1.transform.position.z; |
|
Vector3 playerPos = Player.transform.position + Player.GetComponent<CapsuleCollider>().center; |
|
float playerX = playerPos.x; |
|
float playerZ = playerPos.z; |
|
float distancePE = Mathf.Sqrt((playerX - posX) * (playerX - posX) + (playerZ - posZ) * (playerZ - posZ)); |
|
return distancePE; |
|
} |
|
|
|
//怪物活着的时候该做的事情 |
|
private void GhostAlive_() |
|
{ |
|
if (status == 0 && distancePE_ > attackDistace) |
|
{ |
|
GhostWalk_(); |
|
} |
|
else if (status == 0 && distancePE_ <= attackDistace) |
|
{ |
|
GhostStand_(); |
|
status = 1; |
|
GhostAttack_(); |
|
} |
|
} |
|
|
|
|
|
private void OnCollisionEnter(Collision collision) |
|
{ |
|
if (collision.collider.gameObject.tag == "shield") |
|
{ |
|
isDefended = true; |
|
isTouched = true; |
|
playerShield_ = GameObject.FindGameObjectWithTag("shield").GetComponent<LightShield>(); |
|
} |
|
else if(collision.collider.gameObject.tag == "Player") |
|
{ |
|
isAttackedPlayer = true; |
|
isTouched = true; |
|
} |
|
} |
|
|
|
IEnumerator AttackAction() { |
|
warriorAnime_.SetBool("attack",true); |
|
yield return new WaitForSeconds(attackTimer) ; |
|
isDefended = false; |
|
myself_1.GetComponent<BoxCollider>().enabled = true; |
|
isAttacking_ = true; |
|
yield return new WaitForSeconds(attackEndTimer); |
|
isAttacking_ = false; |
|
isDefended = false; |
|
myself_1.GetComponent<BoxCollider>().enabled = false; |
|
warriorAnime_.SetBool("attack",false); |
|
yield return new WaitForSeconds(nextAttackTimer); |
|
status = 0; |
|
} |
|
}
|
|
|