Unity3D敌人AI自动追击功能

我这次制作的是狼这个敌人:unity中有免费的资源,我选择的资源如下图所示,望读者下载方便动手以便更好地学习和理解:

Wolf Animated | 3D Animals | Unity Asset Store

Unity3D敌人AI自动追击功能

在检测器中新增两个组件:分别为Rigidbody和Boxcollider:

Unity3D敌人AI自动追击功能

注意细节!记得冻结y轴旋转。

接下来拖入animator的控制器,加入nav mesh agent:

Unity3D敌人AI自动追击功能

Unity3D敌人AI自动追击功能

狼有很多动画之间的转换,我设置了两个Layer,分别为:BaseLayer和AttackLayer

BaseLayer中狼执行正常的移动巡逻动画:

Unity3D敌人AI自动追击功能

AttackLayer中狼执行发现攻击目标(玩家)后的追击功能;

Unity3D敌人AI自动追击功能

接下来设置四个bool值,分别为:walk chase follow hit

Unity3D敌人AI自动追击功能

接下来为动作切换时bool值得转换,鼠标单击动画之间的箭头:

Unity3D敌人AI自动追击功能

AttakLayer中:

Base State到breathes之间的切换为:bool Chase ,Chase为1切换到breathes。,Chase为0代表breathes返回Base State

以此类推:

breathes与run之间为:follow;attack2和run之间为:hit;

BaseLayer中:

breathes和walk之间的bool为:walk。

完成好animator的设置之后我们便来到最后一步:代码:

首先放上完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public enum EnemyStates { GUARD,PATROL,CHASE,DEAD }  //守卫、巡逻、追击、死亡状态
[RequireComponent(typeof(NavMeshAgent))]
public class EnemyController : MonoBehaviour
{

    private EnemyStates enemyStates;
    private NavMeshAgent agent;    //确保变量组件一定存在

    private Animator anim;

    [Header("Basic Setting")]

    public float sightRadius;
    public GameObject attackTarget;
    public bool isGuard;
    private float speed;    //追玩家的时候是一个速度,自己回去的时候又是一个速度
    public float lookAtTime;
    private float AttackWaitTime;
    private float remainLookAtTime;

    [Header("Patrol State")]

    public float patrolRange;

    private Vector3 waypoint;

    private Vector3 guardPos;  //获取最开始怪物的坐标

    //怪物受伤

    private float attackTimer;
    public float attackTime;
    public float HP = 15;

    //bool值配合动画
    bool isWalk;
    bool isChase;
    bool isFollow;
    bool isHit;

    private void Awake()
    {
        agent = GetComponent();
        anim = GetComponent();

        speed = agent.speed;
        guardPos = transform.position;
        remainLookAtTime = lookAtTime;

    }

    private void Start()
    {
        attackTime = 2;
        attackTimer = attackTime;
        if (isGuard)
        {
            enemyStates = EnemyStates.GUARD;
        }
        else
        {
            enemyStates = EnemyStates.PATROL;
            GetNewWayPoint();//最开始给一个点
        }
    }
    private void Update()
    {
        Attacktimer();
        SwitchStates();
        SwitchAnimation();
    }

    void SwitchAnimation()
    {
        anim.SetBool("Walk", isWalk);
        anim.SetBool("Chase", isChase);
        anim.SetBool("Follow", isFollow);
        anim.SetBool("Hit", isHit); //bool值关联到一起

    }
    void SwitchStates()
    {
        //如果发现敌人切换为chase
        if (FoundPlayer())
        {
            enemyStates = EnemyStates.CHASE;
            Debug.Log("找到players");
        }

        switch(enemyStates)
        {
            case EnemyStates.GUARD:
                break;
            case EnemyStates.PATROL:
                isChase = false;
                agent.speed = speed * 0.5f;  //巡逻状态下移动速度更低
                if(Vector3.Distance(waypoint,transform.position) 0)
                    {
                        remainLookAtTime -= Time.deltaTime;
                    }
                    else
                    {
                        GetNewWayPoint();
                    }
                }
                else
                {
                    isWalk = true;
                    agent.destination = waypoint;
                }

                break;
            case EnemyStates.CHASE:

                //配合动画
                isWalk = false;
                isChase = true;
                agent.speed = speed;
                if(!FoundPlayer())
                {
                    //回到上一个状态

                    isFollow = false;
                    if (remainLookAtTime > 0)
                    {
                        agent.destination = transform.position;//脱离目标后,追击动画失效然而动物仍然会以idle状态移动至脱离目标时角色位置;
                        remainLookAtTime -= Time.deltaTime;
                    }
                    else if(isGuard)
                    {
                        enemyStates = EnemyStates.GUARD;
                    }
                    else
                    {
                        enemyStates = EnemyStates.PATROL;
                    }
                }
                else
                {
                    isFollow = true;
                    agent.SetDestination(attackTarget.transform.position);
                    if(Vector3.Distance(attackTarget.transform.position, transform.position)  0)
        {
            attackTimer -= Time.deltaTime * 2;
        }

    }
}

代码中有部分备注,值得注意的一个地方是:

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawWireSphere(transform.position, sightRadius);  //方便调节敌人追击范围。。。。
    }

这个可以显示出敌人发现目标玩家的范围,方便我们调整合适的距离。寻找玩家是在一定范围内寻找other.tag == “Player”的物体,因此记得把玩家的tag更改为Player,把狼的tag更改为Enemy。

Unity3D敌人AI自动追击功能

调整一下狼身上挂载的脚本相关信息:

Unity3D敌人AI自动追击功能

最后还需要找到地形,手动烘培一下地形,让navmesh生成自动寻路的路径!!!否则会报错

Unity3D敌人AI自动追击功能

Original: https://blog.csdn.net/weixin_51083610/article/details/126285158
Author: 发什么光儿呀
Title: Unity3D敌人AI自动追击功能

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/787075/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球