我这次制作的是狼这个敌人:unity中有免费的资源,我选择的资源如下图所示,望读者下载方便动手以便更好地学习和理解:
Wolf Animated | 3D Animals | Unity Asset Store
在检测器中新增两个组件:分别为Rigidbody和Boxcollider:
注意细节!记得冻结y轴旋转。
接下来拖入animator的控制器,加入nav mesh agent:
狼有很多动画之间的转换,我设置了两个Layer,分别为:BaseLayer和AttackLayer
BaseLayer中狼执行正常的移动巡逻动画:
AttackLayer中狼执行发现攻击目标(玩家)后的追击功能;
接下来设置四个bool值,分别为:walk chase follow hit
接下来为动作切换时bool值得转换,鼠标单击动画之间的箭头:
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。
调整一下狼身上挂载的脚本相关信息:
最后还需要找到地形,手动烘培一下地形,让navmesh生成自动寻路的路径!!!否则会报错
Original: https://blog.csdn.net/weixin_51083610/article/details/126285158
Author: 发什么光儿呀
Title: Unity3D敌人AI自动追击功能
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/787075/
转载文章受原作者版权保护。转载请注明原作者出处!