Unity2D - 基本战斗系统(Battle System Design)

news2024/11/25 6:50:32

1. 攻击逻辑

在Entity中初始化两个变量,因为在每个角色几乎都拥有攻击状态。这两个变量分别是transform类,接收一个坐标和一个半径画一个圆作为攻击的判定范围

public Transform attackCheck;
public float attackCheckRadius;

为了可视化攻击范围,我们使用辅助画图帮助我们对范围进行设定

protected virtual void OnDrawGizmos()
{
    Gizmos.DrawWireSphere(attackCheck.position,attackCheckRadius);
}

对于敌人的处理也是如此,不要忘记将我们实体Transform传入我们的变量。

之后将创建attack方法,作用于动画中的某一帧,在这一帧中才是真正造成了攻击,也就是应用到了某一函数方法。有经验的读者想必已经想到了事件功能。

创建一个新的脚本命名为PlayerAnimationTrigger,将动画中某一帧与这个脚本中的某一个方法相结合就可以产生当动画执行至某一帧后执行当前脚本事件的效果。

我们编写脚本在动画这一帧中检查二维空间中所有与这个圆重叠的Collider2D的组件,并将这些组件存储在colliders数组中。

private void AttackTrigger()
{
    Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position,player.attackCheckRadius);
    foreach (var hit in colliders)
    {
        if (hit.GetComponent<Enemy>() != null)
        {hit.GetComponent<Enemy>().Damage();}
    }
}
  • Physics2D.OverlapCircleAll:这是Unity Physics2D模块中的一个静态方法,用于检测并返回与指定圆形区域相交的所有Collider2D组件。这个方法不依赖于物理引擎的碰撞检测(即不依赖于速度或力的计算),而是直接基于碰撞体的几何形状和位置进行判断。

  • 注意:默认情况下,Physics2D.OverlapCircleAll会检测所有层的碰撞体。如果你只想检测特定层的碰撞体,可以使用Physics2D.OverlapCircleAll(Vector2 position, float radius, int layerMask)的重载版本,其中layerMask参数允许你指定要检测的层

然后获取敌人组件中Enemy脚本,若不为空,则执行其中的Damage方法。

2. 碰撞器检测

在默认情况下,两个碰撞体相互碰撞会造成位移,为了防止敌人与玩家之间造成位移,我们需要修改如下设定:点击左上角Edit,选中Project Settings,找到Physics2D中的layer Collision Matrix,将对应两个图层勾选取消即可。

3. 被击打效果

3.1 被击打变色

我们需要创建一个新的材料作为被击打时变换的样子,将shader(着色器)搜索设定为GUI

被击打变色的底层逻辑就是在某一事件发生后,将物体的材料改变,持续多久之后恢复原有状态。

新建一个协程EntityFX

public class EntityFX
{
    private SpriteRenderer sr;
    
    [SerializeField] private Material hitMat;
    private Material originalMat;

    private void Start()
    {
        sr = GetComponentInChildren<SpriteRenderer>();
        originalMat = sr.material;
    }

    private IEumerator FlashFX()
    {
        sr.material = hitMat; //更改材料
        yield return new WaitForSeconds(.2f); //暂停协程,等待0.2s
        sr.material = originalMat; 
    }
}

  • sr.material = hitMat;:这行代码将某个渲染器(假设为 sr)的材质更改为 hitMat。这通常用于显示一个“被击中”或“激活”的视觉效果。
  • yield return new WaitForSeconds(.2f);:这行代码暂停协程的执行,等待 0.2 秒。WaitForSeconds 是一个特殊的 yield 指令,用于在协程中创建等待时间。
  • sr.material = originalMat;:等待时间过后,将渲染器的材质改回原始材质 originalMat,从而完成闪烁效果

将上述类定义好之后,我们还需要在角色父类中实例化此类才可进行调用。

对于我们的damage方法,我们添加:

Public virtual void Damage()
{
    fx.StartCoroutine("FlashFX");
}

其中StartCoroutine是一个协程函数,允许你在游戏运行时异步执行代码,而不需要使用多线程的复杂性。协程(Coroutine)可以视为一个可以暂停和恢复的函数。

协程函数通常返回一个IEnumerator类型,这是通过System.Collections命名空间提供的。在协程函数内部,你可以使用yield return语句来暂停协程的执行,并在未来的某个时间点恢复执行。

3.2 击退状态

在角色父类中定义击退相关信息

[SerializeField] protected Vector2 knockbackDirection;
protected bool isKnocked;
[SerializeField] protected float knockbackDuration;

声明击退函数,被击打了向后退一定距离。

protected virtual IEnumerator Hitknockback()
{
    isKnocked = true;
    rb.velocity = new Vector2(knockbackDirection.x * -facingDir,knockbackDirection.y);
    yield return new WaitForSeconds(knockbackDuration);
    isKnocked = false;
}

//在前进函数中我们需要设定,如果被击退则无法继续前进
public void SetVelocity(float _xvelocity,float _yvelocity)
{
    if (isKnocked)
    {
        return;
    }
}

在damage方法中加入这一事件:

public virtual void Damage()
{
    StartCoroutine("HitKnockback");
}

4. 防守与反击效果

4.1 敌人被反击效果

将相关动画以及动画参数,逻辑设定好之后,根据状态机创建一个新的状态,不要忘记在角色中声明该状态SkeltonStunnedState,然后声明相应的构造函数以及重构。

与之前一样,在主函数中声明相应信息。stunDuration,stunDirection。

public class SkeltonStunnedState
{
    public override void Enter()
    {
        base.Enter();
        stateTimer = enemy.StunDuration;
        rb.velocity = new Vector2(-enemy.facingDir * enemy.stunDirection.x,enemy.stunDirection.y);
    }

    public override void Update()
    {
        base.Update();
        if (stateTimer < 0)
        {
            statemachine.changeState(enemy.idleState);
        }
    }
}

让我们会到EntityFX渲染类中,对攻击效果进行进一步设定,有着闪烁的效果,相应的也要设定取消这个效果的方法。

private void RedcolorBlink()
{
    if (sr.color != Color.white)
    {
        sr.color = Color.white;
    }
    else
    {
        sr.color = Color.red;
    }
}

private void CancelRedBlink()
{
    CancelInvoke();
    sr.color = Color.white;
}

在进入状态时声明闪烁相应秒数:

public override void Enter()
{
    enemy.fx.InvokeRepeating("RedColorBlink",0,.1f); //分别是调用方法,延迟时间,持续时间
}

public override void Exit()
{
    base.Exit();
    enemy.fx.Invoke("CancelRedBlink",0);
}

Invoke函数是MonoBehaviour类中的一个非常有用的方法,它允许你在指定的延迟时间后自动调用另一个MonoBehaviour中的方法,而无需使用额外的线程或定时器。

4.2 防守反击

将动画的逻辑与相关参数设定好之后进行脚本的编辑

public class PlayerCounterAttackState:PlayerState
{
    //构造函数
    public override void Enter()
    {
        base.Enter();
        stateTimer = player.counterAttackDuration;
        player.anim.SetBool("SuccessfulCounterAttack",false); //反击成功参数先设置为0
    }

    public override void Exit()
    {
    }

    public override void Update()
    {
        base.Update();
        player.ZeroVelocity(); //防守期间不能移动
        Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position,player.attackCheckRadius);
        foreach (var hit in colliders) //如果防守期间检测到攻击
        {
            if (hit.GetComponent<Enemy>() != null)
            {
                stateTimer = 10;
                player.anim.SetBool("SuccessfulCounterAttack",true);
            }
        }
        if (stateTimer < 0 || triggerCalled)
        {
            stateMachine.ChangeState(player.idleState); //时间到了或者动画结束,自动结束该状态
        }
    }
}

后续对于玩家进行指定的事件操作即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1893095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于改进高斯-拉普拉斯滤波器的一维时间序列平滑与降噪(MATLAB)

以图像处理为例&#xff0c;拉普拉斯算子是基于图像的二阶导数来找到边缘并搜索过零点&#xff0c;传统的拉普拉斯算子常产生双像素宽的边缘&#xff0c;对于较暗区域中的亮斑进行边缘检测时&#xff0c;拉普拉斯运算就会使其变得更亮。因此&#xff0c;与梯度算子一样&#xf…

亚马逊跟卖选品erp采集,跟卖卖家的选品利器,提升选品效率!

今天给亚马逊跟卖卖家&#xff0c;分享我现在在用的两种选品方式&#xff0c;做个铺货或者是跟卖都可以&#xff0c;是不是很多卖家选品现在都是亚马逊前端页面或是新品榜单选择产品跟卖&#xff0c;这样找品这就相当于大海捞针&#xff0c;而且新品榜单的产品你能看到那其他卖…

Zabbix6.4安装教程

目录 前言 主要功能 常见应用场景 一. 环境准备 二. 部署安装 三. Web页面安装 前言 Zabbix是一个开源的企业级监控解决方案&#xff0c;用于监控各种网络设备、服务器、应用程序和云资源。它能够提供全面的监控、告警和数据分析功能&#xff0c;帮助管理员及时发现和解决…

Cocos 7.2~7.4

这几天没更新CSDN&#xff0c;跑去玩Cocos了。自从知道我的粉丝百分之十之八九都是假人&#xff0c;更新确实没什么动力了。主要还是把这边当成一个日记本吧。 选择cocos的原因也很简单。会点js&#xff0c;技术栈比较接近&#xff0c;上手估计也快。简单记录下这几天的内容 主…

2-24 基于图像处理的细胞计数方法

基于图像处理的细胞计数方法。经过初次二值化、中值滤波后二值化、优化后二值化图像、填充背景色的二进制图像、开运算后的图像一系列运算后&#xff0c;进行标签设置&#xff0c;最终得到细胞总数。程序已调通&#xff0c;可直接运行。 2-24 细胞计数方法 中值滤波后二值化 - …

RAL论文:基于弹性体形变仿真的视触觉传感器仿真器Tacchi

近期伦敦国王学院罗山教授和清华大学计算机系方斌在IEEE RAL联合发表了“视触觉传感器仿真”的论文研究工作"Tacchi: A Pluggable and Low Computational Cost Elastomer Deformation Simulator for Optical Tactile Sensors"。 https://ieeexplore.ieee.org/docume…

mac如何压缩视频大小不改变画质,mac怎么压缩视频软件

在数字时代&#xff0c;视频已成为信息传递和娱乐消遣的重要媒介。然而&#xff0c;视频带来的愉悦体验背后&#xff0c;是日益增长的存储和分享压力。大视频文件不仅占用大量存储空间&#xff0c;上传和下载也变得异常缓慢。那么&#xff0c;如何才能有效压缩视频&#xff0c;…

图书电商引入实在Agent:自动化运营提效80%,节省人天1000+

某知名教辅图书品牌深耕中小学教辅图书领域&#xff0c;是中国最具影响力的教育出版策划与发行集团之一&#xff0c;以丰富的图书品类&#xff0c;满足了小学、初中、高中各年龄段读者多元化的阅读需求。 2023年&#xff0c;该品牌在运营、客服等多部门超60个场景中部署实在Ag…

CPU/内存/综合性能评估工具汇总-3:unixbench

目录 一、概括二、UnixBench 一、概括 嵌入式开发中对要设计的产品、立项的项目进行设计时&#xff0c;往往需要对关键芯片进行性能评估&#xff0c;本文主要总结基于linux系统的产品在性能评估时的工具使用总结&#xff0c;在aarch64(arm64平台下测试)&#xff0c;板卡根文件…

PowerToys 是什么?如何在 Windows 上进行安装

PowerToys 是一组由微软开发的系统实用工具&#xff0c;旨在增强 Windows 操作系统的功能和用户体验。这些工具主要针对高级用户和专业人士&#xff0c;提供了许多实用且强大的功能&#xff0c;使得 Windows 的日常使用更加高效和便捷。 PowerToys 最早出现在 Windows 95 时代…

ActiViz实战:鼠标交互和vtkCommand的问题

文章目录 前言一、消失的vtkCallbackCommand二、自定义命令vtkCommand1、自定义一个左键双击事件的命令2、使用观察者/命令模式3、结果 三、vtkObject类中的事件1、vtkCommand中所有的事件2、鼠标事件测试3、如何添加左键的双击事件 四、总结 前言 在C的VTK中&#xff0c;我们…

这次终于能把神经网络学习原理搞清楚了!

在本文中&#xff0c;我们将深入训练过程&#xff0c;探讨神经网络到底是如何学习的。 内容很肝&#xff0c;建议收藏反复观看学习&#xff01; 假设我们想创建一个神经网络&#xff0c;这个神经网络使用温度和星期几特征来预测每天冰淇淋的销售额。 这是我们使用的训练数据…

spring中集成mybatis,并测试是否成功

首先你要配置pom.xml <!-- 连接 MySQL 数据库的驱动程序 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><!-- spring-jdbc -->&…

纯前端低代码开发脚手架 - daelui/molecule

daelui/molecule低代码开发脚手架&#xff1a;分子组件开发、预览、打包 页面代码示例、大屏代码示例预览 可开发页面组件 可开发大屏组件 项目git地址&#xff1a;https://gitee.com/daelui/molecule 在线预览&#xff1a;http://www.daelui.com/daelui/molecule/app/index.…

一个使用 g++ 模块化编译的 hello world 示例( Ubuntu 20.04 )

1. 确认 ubuntu 版本&#xff1a; 2. 文件夹结构&#xff1a; 3. 各个文件内容&#xff1a; 3.1. myadd.cpp&#xff1a; #include<iostream> using namespace std; int add_xxx( int a,int b ){int result a b;cout << a << " " << …

【android】【adb shell】写一个shell脚本,监听进程pid变化

前言 当前业务&#xff0c;需要写一个脚本&#xff0c;不断监视com.android.phone 进程是否异常死掉 脚本 #!/system/bin/sh last_pid"" current_pid"" while(true){current_pidps -A | grep com.android.phone | awk {print $2}if [ -n "$current…

企业必备:Airflow与TASKCTL在任务调度中的优势

在实际系统运维工作中&#xff0c;Airflow 和 TASKCTL 都是强大的任务调度工具&#xff0c;但它们在功能、安全性、技术架构和应对压力方面各有特点。以下是我对两者的对比&#xff1a; 功能对比 Airflow: ● 基于 Python&#xff0c;使用有向无环图&#xff08;DAG&#xff…

伦敦金价格走势图的资金管理怎么进行?

要成熟地交易伦敦金价格走势图&#xff0c;其实并不是一件容易的事情。其一&#xff0c;我们在很多广告或者周边朋友的宣传之下&#xff0c;觉得它能够帮助我们很快之内实现很多的财富增值&#xff0c;其二&#xff0c;很多投资者觉得伦敦金交易虽然不错&#xff0c;但是风险好…

RKNN3588——YOLOv8的PT模型转RKNN模型

一&#xff1a;PT转ONNX 1. 首先克隆rknn修改后的ultralytics版本项目到本地 https://github.com/airockchip/ultralytics_yolov8 cd ultralytics-main pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install -e . 主要是修改了源码的ul…

【管理咨询宝藏140】安永大型国央企内控合规体系建设培训

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏140】安永大型国央企内控合规体系建设培训 【格式】PDF版本 【关键词】安永、内控风控、合规体系 【核心观点】 - 合规是指企业的经营活动与法律…