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.
171 lines
5.3 KiB
171 lines
5.3 KiB
3 years ago
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.AI;
|
||
|
|
||
|
//最简单的小怪,碰到玩家自动消失,拥有血量,会自动向主角发动进攻(此时玩家处于红眼状态并减少生命值)
|
||
|
//出生后,会向主角处进行行走,靠近主角时,会停下来(0.1-0.5s),之后跑向主角,发动攻击(攻击完后自动死亡)
|
||
|
//游戏暂停时进入僵持状态(无法受到任何攻击,也不能对玩家造成任何伤害,同时终止行动)
|
||
|
//受到攻击后自身颜色发生变化
|
||
|
public class GhostSouler : 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 LightShield playerShield_;
|
||
|
//敌人发动攻击时离玩家的距离
|
||
|
private float standTimer;
|
||
|
public float attackDistace;
|
||
|
//判断攻击对象是不是玩家(不是玩家就是盾牌)
|
||
|
private bool isAttackedPlayer;
|
||
|
//敌人最大生命值
|
||
|
private float maxHp;
|
||
|
//死亡特效
|
||
|
public GameObject deathEffect_;
|
||
|
|
||
|
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
// Update is called once per frame
|
||
|
void Update() {
|
||
|
distancePE_ = CaculatePlayerDistance();
|
||
|
if (playerScript.enemyDistance > distancePE_ * 4)
|
||
|
{
|
||
|
playerScript.enemyDistance = Mathf.Floor(distancePE_) * 8 / 2f;
|
||
|
}
|
||
|
if (!isDeath) {
|
||
|
GhostAlive_();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//敌人行为相关
|
||
|
private void GhostBirth_() {
|
||
|
|
||
|
}
|
||
|
//原地不动
|
||
|
private void GhostStand_() {
|
||
|
myself_1.GetComponent<NavMeshAgent>().destination = myself_1.transform.position;
|
||
|
}
|
||
|
//行走
|
||
|
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;
|
||
|
GhostWalk_();
|
||
|
}
|
||
|
//攻击玩家
|
||
|
private void GhostAttack_()
|
||
|
{
|
||
|
if (isAttackedPlayer)
|
||
|
{
|
||
|
playerScript.Hurted(atk);
|
||
|
deathEvent.Invoke();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = 0;
|
||
|
standTimer = 0.3f;
|
||
|
isTouched = false;
|
||
|
playerShield_.shieldHit();
|
||
|
}
|
||
|
}
|
||
|
//受到攻击
|
||
|
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)
|
||
|
{
|
||
|
status = 1;
|
||
|
GhostStand_();
|
||
|
}
|
||
|
else if (status == 1 && standTimer > 0f)
|
||
|
{
|
||
|
standTimer -= Time.deltaTime;
|
||
|
}
|
||
|
else if (status == 1 && standTimer <= 0f)
|
||
|
{
|
||
|
status = 2;
|
||
|
GhostRun_();
|
||
|
}
|
||
|
else if (status == 2 && isTouched)
|
||
|
{
|
||
|
status = 3;
|
||
|
GhostAttack_();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
private void OnCollisionEnter(Collision collision)
|
||
|
{
|
||
|
if (collision.collider.gameObject.tag == "Player")
|
||
|
{
|
||
|
isAttackedPlayer = true;
|
||
|
isTouched = true;
|
||
|
}
|
||
|
else if (collision.collider.gameObject.tag == "shield")
|
||
|
{
|
||
|
isTouched = true;
|
||
|
playerShield_ = GameObject.FindGameObjectWithTag("shield").GetComponent<LightShield>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|