首页 > 其他分享 >Unity引擎2D游戏开发,受伤和死亡的逻辑和动画

Unity引擎2D游戏开发,受伤和死亡的逻辑和动画

时间:2023-12-19 16:23:11浏览次数:32  
标签:动画 受伤 创建 2D Unity 添加 public Animator

一、创建受伤动画

找到相关受伤的动画素材,然后在Animation窗口创建动画。此处不再赘述。

image

image

此时在Animator窗口删除刚才创建的两个动画,因为现在要采用另一种方式创建动画:采用Animator的Layer方式

使用Animator→Layer创建受伤闪烁动画

受伤闪烁动画意为受伤后短暂无敌时间

点击右边号,创建新的动画图层,并命名为Hurt Layer
image

点击创建的新的图层的齿轮,将Weight设置为1,Blending设置为Additive
image
Weight为权重,即权重越高,动画播放优先级越高。
Blending为混合模式,Overrides为覆盖模式,Additive为叠加模式

在Animator窗口,右击选中Create State创建新的状态
image

创建新的Animation动画,更名为blueHurt2。将用此动画创建闪烁动画
image

在此动画下方点击Add Property,选中Sprite Renderer.Material._Color
image
Add Property可以使此动画片段修改其中任意一个被添加的属性

展开被添加的属性,可以看到其中有多个从属性,可以在动画时间轴添加关键帧修改这些从属性
image

将Samples修改为6,并在0:2、0:4、1:0处打上关键帧,分别将Material._Color.a设置为0.2、1、0.2
image
可以将鼠标点击对应的时间轴位置,然后修改需要修改的从属性,即可自动打上关键帧。
Material._Color.a为Alpha通道

在Hurt Layer动画图层中,将blueHurt2动画添加进来
image

由于此受伤后无敌动画需要触发进行,因此添加一个Trigger,命名为hurt
image

选中连线,在右下角将此Trigger添加进Condition中。并在上方设置好连线参数。
image

连接退出动画,选中连线,设置好退出参数
image

编写受伤闪烁触发器相关代码

打开PlayerAnimation代码。由于添加的触发器(Trigger)是一次执行,因此不能写在Update()方法内,另外新写一个方法。

public void PlayerHurt()
{
    animator.SetTrigger("hurt");
}

由于是写的关于受伤相关的代码,并且根据正常游戏需求,受伤后需要处理的操作非常庞大,比如UI抖动、人物受击动画、人物受击位移、扣血、削减属性等等。因此,此时需要利用Unity自带的“事件”(Event)进行处理。
打开Character代码。在头部添加UnityEvent包。

using UnityEngine.Events;

添加新的全局变量

// 将Transform坐标传入事件中
public UnityEvent<Transform> OnTakeDamage;

由于此处打算编写受击位移,需要坐标值,所以将Transform传入UnityEvent

此时,在Player的组件列表中,Character内多了一个On Take Damage(Transform)事件处理器。
image
只要此事件触发,会执行下方添加的所有方法。

将PlayAnimation拖入下面小格中
image

点击+号,添加PlayHurt()方法
image

将触发条件设置为Runtime Only
image
Editor And Runtime为编辑器运行和执行时
Runtime Only为只在执行时

在Character的TakeDamage()方法内,添加新的代码

// 执行受伤
OnTakeDamage?.Invoke(attacker.transform);

OnTakeDamage?用于判断此组件是否绑定了方法,如果绑定了则进一步处理。否则不进行处理
Invoke()方法为开始执行
attacker.transform将攻击者的坐标传入

此时开始Play,可以发现人物受伤后,无论怎么操作,受击闪烁都会执行。这就是Blending中叠加模式(Additive)的效果

创建受击后撤动画

选择中blueHurt2,然后在右侧Motion中,选择blueHurt
image

在Animation中,选择blueHurt,添加Color的Property
image

在时间轴中打关键帧,调整颜色数值(可根据自己的需要进行更改)
image

编写受击后撤的代码

受击后撤需要两个变量,一个受伤时反弹施加的力,一个是否受伤的状态

// 受伤时反弹施加的力
public float hurtForce;
// 是否受伤的状态
public bool isHurt;

新建GetHurt()方法,在里面写相关逻辑

public void GetHurt(Transform attacker)
{
    isHurt = true;
    // 受伤时强行使人物停止移动
    rb.velocity = Vector2.zero;
    // 用人物的x坐标减去攻击者的x坐标,如果得到一个负数,则人物在攻击者左侧。否则,在攻击者的右侧。
    // 用差得到方向,乘以受伤的力即可得到加速的效果
    Vector2 dir = new Vector2((transform.position.x - attacker.position.x), 0).normalized;

    rb.AddForce(dir * hurtForce, ForceMode2D.Impulse);
}

normalized属性为标准化属性,使数值无论多大,都标准化为1

normalized属性文档:https://docs.unity3d.com/cn/2022.3/ScriptReference/Vector2-normalized.html

修改FixedUpdate()方法,进行进一步的判断

private void FixedUpdate()
{
    if(!isHurt)
    {
        Move();
    }
}

在Player的On Take Damage(Transform)中,添加GetHurt()方法
image

在Player的PlayerController中,将Hurt Force设置为自己想要的数值
image

此时执行,可以发现人物受击后,确实发生了后撤,但是后续无法进行操作

解决受击后撤后无法操作的问题

在Animator窗口中,选中blueHurt2。接着,在右侧窗口中,选择Add Behavior
image

添加新的脚本,命名为HurtAnimation,并将新创建的脚本拖入Player文件夹中
image

打开HurtAnimation

public class HurtAnimation : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    //override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    //override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}

OnStateEnter():当被绑定此代码的动画进入时执行
OnStateUpdate():当被绑定此代码的动画执行时执行
OnStateExit():当被绑定此代码的动画退出时执行

在OnStateExit()中,获取PlayerController组件,修改当中的isHurt为false

override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    animator.GetComponent<PlayerController>().isHurt = false;
}

二、创建死亡动画

找到相关死亡的动画素材,然后在Animation窗口创建动画。此处不再赘述。

在Animator窗口,创建死亡动画

将Hurt Layer的Blending更改为覆盖模式(Override)
image

将死亡动画拖入Animator窗口中,与Any State连线。因为,任何情况都会进入死亡动画
image

在左侧Parameters窗口中,创建新的参数isDead
image

选择连线,将isDead参数添加进条件,并调整相关参数
image

将BlueDeath与Exit连线,并将isDead参数添加进条件,调整相关参数
image

编写死亡相关的代码

在Character文件中,新建onDie事件属性。由于死亡后也需要处理很多的操作,所以在此创建为UnityEvent事件对象。

public UnityEvent onDie;

TakeDamage中,调用此创建全局变量

onDie?.Invoke();

在PlayerController文件中,创建isDead全局属性

// 是否死亡状态
public bool isDead;

创建PlayerDead()方法,禁止玩家的操作输入

public void PlayerDead()
{
    isDead = true;
    playerInputControl.Gameplay.Disable();
}

在PlayerAnimation文件中,链接Controller中的isDead状态

animator.SetBool("isDead", playerController.isDead);

将PlayerController组件拖入,并绑定PlayerDead()方法
image

此时将玩家血量设置到最低,受伤后就会播放死亡动画。但是,目前会不断反复播放。

解决死亡动画反复播放的问题

选择BlueDeath动画,在右侧将LoopTime取消勾选,即可单次执行
image

只要连接了Any State的动画,基本就不存在反复执行的问题。连接了Any State的动画,即可根据需求,判断是否需要反复执行。

标签:动画,受伤,创建,2D,Unity,添加,public,Animator
From: https://www.cnblogs.com/xinlindeyu/p/17914057.html

相关文章

  • CF1902D Robot Queries 题解
    题意:有一个二维平面直角坐标系,给定一串向某个方向移动\(1\)个单位的操作。有\(q\)个询问,对于每个询问给定\(x,y,l,r\),问如果倒着做\(l\)到\(r\)这段区间中的操作,是否会经过\((x,y)\)。ds题。先预处理出\(sx_i,sy_i\)表示执行完操作\(i\)后的位置,如果在\([l,r]\)......
  • Unity3D 程序员常用的核心类及方法详解
    Unity3D是一款强大的游戏引擎,广泛应用于游戏开发领域。作为Unity3D程序员,掌握常用的核心类及方法是非常重要的。本文将详细介绍Unity3D中程序员常用的核心类及方法,并给出代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发......
  • Unity3D 拖拽赋值组件与通过Find赋值组件的优点与缺点详解
    前言Unity3D是一款流行的游戏开发引擎,提供了丰富的功能和工具,使开发人员能够轻松创建高质量的游戏。在Unity3D中,我们经常需要通过拖拽赋值组件或通过Find赋值组件来实现不同对象之间的交互。本文将详细介绍这两种方法的优点和缺点,并给出相应的技术详解和代码实现。对啦!这里有个......
  • Unity引擎2D游戏开发,人物属性及伤害计算
    一、创建敌人2D模型裁切野猪素材,并放置在Scene窗口中打开文件夹,找到野猪待机素材将素材进行必要的设置点击窗口中的SpriteEditor,打开裁切窗口。点击Slice,选择Type,进行按网格计数裁切(GridByCellCount)接着,然后在Column&Row中,写入4、1。即,4列1行。将中心点Pivot选择Bot......
  • Vue 过渡 & 动画
    在Vue的过渡效果中,.enter-active、.leave-active、.enter和.leave-to是一些预定义的CSS类名,用于控制过渡的不同阶段。.enter-active:表示进入过渡的活动状态。在元素插入到DOM中时添加,然后在过渡结束时移除。通过设置此类的样式,可以定义元素进入过渡时的动画效果。.......
  • 进一步学习 CommunityToolkit.Mvvm
    1.属性绑定privatestringtitle;publicstringTitle{get;set;} 可用以下属性方式替换,生成器会自动生成;[ObservableProperty]privatestringtitle; 另一种情况:命令privateboolisEnabled;publicboolIsEnabled{......
  • 进一步学习 CommunityToolkit.Mvvm 之 Messenger
    一、带token1.订阅消息WeakReferenceMessenger.Default.Register<UserMessage,string>(this,"MyToken",(r,m)=>{});2.发送消息WeakReferenceMessenger.Default.Send(newUserMessage(value),"MyToken");二、某一种数据类型发送接收消息1.订阅消息V......
  • wowjs动画库
    介绍一款极简的动画小插件,依赖animate.css,支持animate.css多达60多种的动画效果animate官网兼容性IE6、IE7等老浏览器不支持CSS3动画,所以没有效果;而wow.js也使用了querySelectorAll方法,IE低版本会报错使用1.animate.css引入<linkrel="stylesheet"type="te......
  • 【Unity】使用VSCode调试
    安装2022.3.14f1c1版本的unity编辑器并使用VSCode调试c#脚本。VSCode请使用最新版本(1.85.1),并安装Unity插件最新版本v0.9.3。在Unity中配置外部编辑器,选择VisualStudioCode(v1.85.1)。从Unity中双击一个.cs文件,可以在vscode中打开此文件。找到v......
  • 基于Unity3D 低多边形地形模型纹理贴图
    在线工具推荐:3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.jsAI自动纹理开发包 - YOLO虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎当谈到游戏角色的3D模型风格时,有几种不同的风格:写实风格:这种风格追求高度真实......