九、怪物行为逻辑

一、怪物正常行为

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

相关推荐
Jae den9 小时前
网络延迟为什么会影响游戏和实时业务?
网络·游戏
思盛iOS签名上架12 小时前
ipa企业签名闪退是什么原因?
游戏·ios·testfight
狂人开飞机13 小时前
14、游戏手感与视觉打磨
游戏·游戏引擎·godot
狂人开飞机19 小时前
15、音频系统
游戏引擎·godot
狂人开飞机19 小时前
16、粒子线条与视觉特效
游戏引擎·godot
心前阳光1 天前
Unity发布PC软件图标不能改变
unity·游戏引擎
笨鸟先飞的橘猫1 天前
系统设计第十七天决策卡
学习·游戏
一孤程1 天前
游戏测试专题第二篇:游戏功能测试与用例设计实战
功能测试·游戏·测试·测试覆盖率
科技泡泡堂1 天前
想玩《黎明行者之血》?2026年这4款适合玩3A的游戏本值得一看
游戏
an86950012 天前
unity如何在visual studio中打断点debug
unity·游戏引擎·visual studio