VR模拟枪支打靶,消灭鬼怪,换弹以及上弦等等硬核枪支操作。 使用HTCVive设备,开启SteamVR进行游玩。
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.

228 lines
6.8 KiB

3 years ago
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;
}
}