九、怪物行为逻辑

一、怪物正常行为

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、动画连接

相关推荐
lingzhilab1 小时前
零知开源——基于STM32F103RBT6与ADXL362三轴加速度计的体感迷宫游戏设计与实现
游戏
SmalBox2 小时前
【渲染流水线】[逐片元阶段]-[透明度测试]以UnityURP为例
unity·渲染
代码改变世界100863 小时前
像素风球球大作战 HTML 游戏
前端·游戏·html
三只坚果16 小时前
blender制作动画导入unity两种方式
unity·游戏引擎·blender
benben04416 小时前
《Unity Shader入门精要》学习笔记二
unity·unity shader
YF云飞17 小时前
Unity音频管理:打造沉浸式游戏音效
游戏·unity·游戏引擎·游戏程序·个人开发
SmalBox1 天前
【渲染流水线】[逐片元阶段]-[裁剪测试]以UnityURP为例
unity·渲染
王廷胡_白嫖帝1 天前
Qt猜数字游戏项目开发教程 - 从零开始构建趣味小游戏
开发语言·qt·游戏
m0_552200821 天前
《UE5_C++多人TPS完整教程》学习笔记43 ——《P44 奔跑混合空间(Running Blending Space)》
c++·游戏·ue5
阳光阴郁大boy1 天前
一个基于纯前端技术实现的五子棋游戏,无需后端服务,直接在浏览器中运行。
前端·游戏