个人课设---怪物AI(自动锁定敌人,进行攻击)(敌人离开怪物的搜索范围取消跟踪)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEditor.FilePathAttribute;

public enum MonstorAIState
{
    idle,//闲置状态
    Patrol,//巡逻
    ChasePlayer,//追击玩家
    AttackPlayer,//攻击玩家
    //自己添加其他状态

}

public class MonsterAI : MonoBehaviour
{
    public float speed = 2f;//移动速度
    public Transform[] wayPointArr;//路径点数组
    public Transform pathObj;//路径点父物体
    //当前的路径点下标
    public int currentWaypointIndex = 0;
    private Animator _animator;//动画器
    public MonstorAIState monsterCurrentState=0;//怪物当前状态
    public MonstorAIState monsterOldState=0;
    private Transform playerObj;//玩家物体
    public bool isAlive=true;//丧尸是否活着
    public bool isFindPlayer = false;//是否发现玩家
   
    // Start is called before the first frame update
    void Start()
    {
        //在场景里通过标签查找玩家物体
        playerObj = GameObject.FindGameObjectWithTag("Player").transform;
        //判断玩家是否已经正确找到
        if(playerObj==null)
        {
            Debug.LogError("没有找到玩家物体,请查看玩家标签是否正确设置为Player");

        }
            _animator = GetComponent<Animator>();//获取动画器组件引用

            //自动搜索场景中的路径点加载到路径点数组中
            if (pathObj != null)
            {
                //数组开辟内存
                wayPointArr = new Transform[pathObj.childCount];
                for (int i = 0; i < pathObj.childCount; i++)
                {
                    wayPointArr[i] = pathObj.GetChild(i).transform;
                }
            }
            else
            {
                Debug.LogError("路径点父物体没有拽入参数栏");
            }

        //开启协程
        StartCoroutine(IsFindPlayer(1f,25f));
        }



    // Update is called once per frame
    void Update()
    {
        //如果丧失已经死亡,则不郧西下面代码
        if (!isAlive)
            return;
        switch (monsterCurrentState)
        { 
            case MonstorAIState.idle:
                Idle();
                break;
            case MonstorAIState.Patrol://巡逻状态
                Patrol();
                break;
            case MonstorAIState.ChasePlayer://追击玩家
                ChasePlayer();
                break;
            case MonstorAIState.AttackPlayer://追击玩家
                AttackPlayer();
                break;
        }

    }
  
    void Patrol()//巡逻状态
    {
        speed = 0.5f;
        _animator.SetFloat("moveSpeed",speed);
        //计算怪物与目标点之间的角度  并进行方向修正
        Vector3 direction = wayPointArr[currentWaypointIndex].position - transform.position;
        //计算旋转角度并旋转
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), 0.1f);
        if (direction.sqrMagnitude < 0.02f)
        {
            if (currentWaypointIndex++ == wayPointArr.Length - 1)
            {
                currentWaypointIndex = 0;
            }
        }
        //一直前进
        transform.Translate(Vector3.forward * Time.deltaTime * speed);
        //播放动画
        _animator.SetFloat("moveSpeed", speed);
    }

    //闲置
    void Idle()
    {
        speed = 0;
        _animator.SetFloat("moveSpeed",speed);
    }
    //追击玩家方法
    void ChasePlayer()
    {
        speed = 0.8f;
        _animator.SetFloat("moveSpeed", speed);
        //面向玩家
        //计算与玩家的角度
        Vector3 direction = playerObj.position - transform.position;
        //计算旋转角度并旋转
        transform.rotation = Quaternion.Slerp(transform.rotation,
                                                 Quaternion.LookRotation(direction),
                                                   0.1f);
        //一直前进
        transform.Translate(Vector3.forward * Time.deltaTime * speed);
        //播放动画 
        _animator.SetFloat("moveSpeed", speed);
        //如果玩家与怪物之间的距离大于设定的N米,则返回旧状态
        
        if(direction.sqrMagnitude>10f*10f)
        {
            monsterCurrentState = monsterOldState;
            isFindPlayer = false;//玩家追丢了,重置
        }
        //查找玩家的协程有没有开启

        //如果玩家与怪物之间的距离小于设定的距离,则进入到攻击状态
        print(direction.sqrMagnitude);
        if(direction.sqrMagnitude<0.4f)
        {
            monsterCurrentState=MonstorAIState.AttackPlayer;//攻击玩家
        }
    }
    //通过与玩家距离来判断是否发现玩家
    IEnumerator IsFindPlayer(float intervalTime, float discoveryDistance)
    {
        while (isAlive)
        {
            if (!isFindPlayer && playerObj != null)
            {//计算与玩家的距离
                Vector3 direction = playerObj.position - transform.position;
                if (direction.sqrMagnitude < discoveryDistance*discoveryDistance)
                {
                    //发现玩家
                    print("怪物已经发现玩家!");
                    isFindPlayer = true;
                    //记录旧状态
                    monsterOldState = monsterCurrentState;
                    //将当前的怪物状态设置为追击玩家状态
                    monsterCurrentState = MonstorAIState.ChasePlayer;
                }
               /* else
                {
                    //将当前的怪物状态设置为闲置状态
                    monsterCurrentState = MonstorAIState.idle;
                }*/
            }
            yield return new WaitForSeconds(intervalTime);
        }

    }
    void AttackPlayer()
    {
        speed = 0;
        _animator.SetFloat("moveSpeed", speed);
        _animator.SetTrigger("Attack");//播放攻击玩家动画
        //计算与玩家的距离
        Vector3 direction = playerObj.position - transform.position;
        if(direction.sqrMagnitude>0.4f)
        {
            monsterCurrentState = MonstorAIState.ChasePlayer;
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值