九、怪物行为逻辑

一、怪物正常行为

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 小时前
如何在 Mac 上下载安装仙剑游戏仙剑世界?可以通过IPA砸壳包安装非常简单
游戏·macos·ios·游戏程序·mac
浅陌sss13 小时前
Unity中可靠的UDP实现
unity
虾球xz15 小时前
游戏引擎学习第107天
学习·游戏引擎
虾球xz16 小时前
游戏引擎学习第105天
前端·学习·游戏引擎
奔跑的犀牛先生19 小时前
unity学习46:反向动力学IK
unity
幻世界21 小时前
【工具插件类教学】实现运行时2D物体交互的利器Runtime2DTransformInteractor
unity·交互·运行时2d物体交互
虾球xz1 天前
游戏引擎学习第104天
学习·游戏引擎
音视频牛哥2 天前
Unity实现高性能多实例RTSP|RTMP播放器技术实践
unity·游戏引擎·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtsp player
Bluesonli2 天前
第 16 天:游戏 UI(UMG)开发,打造主菜单 & 血条!
学习·游戏·ui·ue5·虚幻·unreal engine
Artistation Game2 天前
三、Unity基础(主要框架)
游戏·unity·c#·游戏引擎