九、怪物行为逻辑

一、怪物正常行为

1、导入资源

2、创建怪物预制体

新建一个空物体,作为父级、怪物作为子级

3、导入怪物动画

在怪物身上添加角色控制器和动画组件

此时怪物会有碰撞不会穿模

创建一个动画控制器,放入攻击状态和正常状态

并设置一个Bool值,为攻击

注:模型动画预览时,需要拖入子物体模型,不能放入父级物体

如图所示:

如果模型是预制体,那么只能拖入模型,不能放入父级

如果模型与父级是同一个预制体,那么拖入父级也就相当于一个整体的人物模型

二、AI寻路组件

1、地图烘焙

2、挂载AI组件和代码

注意:

敌人可能会出现进入玩家的身体里的情况

解决方法:

AI组件中有一个停止距离,敌人的脚本中有一个攻击距离,二者之间需要有一个大小值

第一种情况:敌人的攻击距离大于停止距离,则先停止后攻击,不会进入身体中

第二种情况:敌人的攻击距离小于停止距离,则会出现一直进入身体的Bug

写敌人的逻辑时需要注意一下。

3、代码

注:使怪物始终朝向玩家,必须设置锁定Y轴的代码

否则会出现,敌人身体倾斜

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public enum BossState
{
    idle,
    attack,
    run
}
public class EnemyControl : MonoBehaviour
{
    private BossState CurrentState= BossState.idle;//枚举状态
    private Animator Anim;//怪物动画控制器
    private NavMeshAgent Agent;//导航网格代理
    private float HpNow = 100;
    private bool ISDead = false;
    private Transform player;//玩家位置
    

    public float IdleDis = 100.0f;//站立寻敌范围
    public float AttackDis = 3.0f;//攻击距离
    public float HpMax = 100.0f;
	//声音管理组件
	public AudioSource AudioSource1;
	//播放声音大小
	public float SoundValue = 1.0f;
	//第一个攻击声音
	public AudioClip AudioClip1;


	private void Start() 
	{
        HpNow = HpMax;
		Anim = GetComponent<Animator>(); 
        Agent = GetComponent<NavMeshAgent>();
        player = GameObject.FindWithTag("Player").transform;
	}
	private void Update()
	{
        LookAtPlayer();
        EnemyState();
	}
    /// <summary>
    /// 始终朝向玩家
    /// </summary>
    public void LookAtPlayer()
    {
        if (!ISDead)
        {
            Vector3 PlayerPos = player.position;
            PlayerPos.y = transform.position.y;
            transform.LookAt(PlayerPos);
        }
    }
    /// <summary>
    /// 切换怪物状态
    /// </summary>
    public void EnemyState()
    {
        if (!ISDead)
        {
            float Distance1=Vector3.Distance(transform.position, player.position);
            switch (CurrentState)
            {
                //静止状态
                case BossState.idle:
                    Anim.Play("RunTree");
                    Anim.SetFloat("MoveSpeed", 0f);
                    Anim.SetBool("Attack", false);
                    Agent.isStopped = true;
                    if(Distance1> AttackDis && Distance1 <= IdleDis)
                    {
                        CurrentState=BossState.run;
                    }
                    break;
                //追踪状态
                case BossState.run:
                    Agent.isStopped = false;
                    Agent.SetDestination(player.position);
                    Anim.SetFloat("MoveSpeed", 1f);
                    Anim.SetBool("Attack", false);
                    if (Distance1 > IdleDis)
                    {
                        CurrentState= BossState.idle;
                    }
                    else if (Distance1 <= AttackDis)
                    {
                        CurrentState = BossState.attack;
                    }
                    break;
                //攻击状态
                case BossState.attack:
                    Agent.isStopped=true;
                    BossAttack();
                    if (Distance1 > AttackDis)
                    {
                        CurrentState= BossState.run ;
                    }
                    else
                    {
                        Anim.SetFloat("MoveSpeed", 0f);
                    }

					break;
            }
        }
    }
    //Boss攻击
    public void BossAttack()
    {
        if (Anim.GetBool("Attack"))
        {
            return;
        }

        Anim.SetBool("Attack", true);

    }
    //播放声音,在动画事件中调用
    public void PlayAttackSound()
    {
        AudioSource1.PlayOneShot(AudioClip1, SoundValue);

    }
}

4、混合树

将敌人的Idle和Run状态混合

混合度、播放速度、镜像

二者的区别是Play没有过度;CrossFade有过度

三、添加敌人音效

技巧:在动画事件上添加攻击音效,这样只会在敌人攻击时播放

1、代码

声明部分

2、动画事件

四、敌人伤害

1、实现原理

和之前一样,也是在动画事件中进行调用,在挥砍的那一瞬间调用

在此项目中,使用一个攻击点和一个预制体(触发器)进行实例化,判断触发伤害

动画事件和触发器一起使用

还有一种方法使用射线检测

2、制作点和实例化物体

把空物体放置在子物体下,不然会出现实例化位置移动

建一个空物体挂载代码,并制作成预制体

注意:此处选择小写的gameobject,为此物体

在实例化出来后,一定时间内销毁此物体

在玩家的每一个攻击中实例化此物体

3、伤害

写一个随机值

五、怪物受击特效

实现原理:实例化音效和特效在一个点,点挂载到玩家的身上

1、创建实例化位置

挂载到敌人的身上

创建一个空物体,添加代码和音效,音效设置为启用时播放

即可在实例化的时候 产生攻击特效和音效

2、代码

首先,实例化的物体要写消失条件

在敌人的受击方法中,添加实例化并播放受击动画

3、动画连接

相关推荐
程序猿阿伟12 分钟前
《C++游戏人工智能开发:开启智能游戏新纪元》
c++·人工智能·游戏
百里香酚兰2 小时前
【AI学习笔记】基于Unity+DeepSeek开发的一些BUG记录&解决方案
人工智能·学习·unity·大模型·deepseek
妙为2 小时前
unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发
游戏·游戏引擎·虚幻·碰撞预设
网站领航2 小时前
服装时尚与动漫游戏的跨界联动:创新运营与策划策略研究
游戏·流量运营·用户运营
龙智DevSecOps解决方案2 小时前
Perforce演讲回顾(上):从UE项目Project Titan,看Helix Core在大型游戏开发中的版本控制与集成使用策略
游戏·ue5·源代码管理·perforce·helix core
dangoxiba5 小时前
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十三集:制作小骑士的接触地刺复活机制以及完善地图的可交互对象
游戏·unity·visualstudio·c#·游戏引擎
新手unity自用笔记8 小时前
项目-坦克大战学习-游戏结束
学习·游戏
DK七七13 小时前
【PHP陪玩系统源码】游戏陪玩系统app,陪玩小程序优势
前端·vue.js·游戏·小程序·php·uniapp
先生沉默先1 天前
使用Materialize制作unity的贴图,Materialize的简单教程,Materialize学习日志
学习·unity·贴图