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

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.2ssr.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.mzph.cn/diannao/42671.shtml

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

相关文章

基于ROS的智能网联车远程交互软件,全UI无需记忆指令,剑指核心原理。

基于ROS的智能网联车远程交互软件&#xff0c;全UI无需记忆指令&#xff0c;剑指核心原理。 服务于中汽恒泰&#xff0c;伟大的项目&#xff0c;希望看官点赞&#xff0c;谢谢~~ 进程&#xff08;节点&#xff09;列表化&#xff0c;参数面板化&#xff0c;实现快速机器人配置…

Linux--V4L2摄像头驱动框架及UVC浅析

一、前言 对于一个usb摄像头&#xff0c;它的内核驱动源码位于/drivers/media/usb/uvc/ 核心层&#xff1a;V4L2_dev.c文件 硬件相关层&#xff1a; uvc_driver.c文件 本篇记录基于对6.8.8.8内核下vivid-core.c文件&#xff08;虚拟视频驱动程序&#xff09;的分析&#xff…

澳大利亚媒体发稿:怎样用图表提高易读性?-华媒舍

媒体发稿的可读性变得尤为重要。读者们不会再有时间与耐心去阅读文章繁琐的文本&#xff0c;他们更喜欢简洁明了的信息展现形式&#xff0c;在其中图表是一种极为高效的专用工具。下面我们就详细介绍怎么使用图表提高澳大利亚新闻媒体发稿的可读性&#xff0c;以适应读者的需要…

java 栅栏(CyclicBarrier)

Java中的栅栏&#xff08;CyclicBarrier&#xff09;是一种用于协调多个线程并发工作的同步辅助类。与CountDownLatch不同&#xff0c;CyclicBarrier允许一组线程相互等待&#xff0c;直到所有线程都到达一个共同的屏障点&#xff08;barrier&#xff09;后&#xff0c;才继续执…

CSS 【详解】样式选择器(含ID、类、标签、通配、属性、伪类、伪元素、Content属性、子代、后代、兄弟、相邻兄弟、交集、并集等选择器)

CSS 样式选择器&#xff0c;用于选中页面中的 html 元素&#xff0c;以便添加 CSS 样式。 按渲染性能由高到低 依次是&#xff1a; ID 选择器 #id 通过元素的 id 属性选中元素&#xff0c;区分大小写 <p id"p1" >第一段</p>#p1{color: red; }但不推荐使…

【SpringCloud应用框架】Nacos集群架构说明

第六章 Spring Cloud Alibaba Nacos之集群架构说明 文章目录 前言一、Nacos支持三种部署模式二、集群部署说明三、预备环境 前言 到目前为止&#xff0c;已经完成了对Nacos的一些基本使用和配置&#xff0c;接下来还需要了解一个非常重要的点&#xff0c;就是Nacos的集群相关的…

金斗云 HKMP智慧商业软件 任意用户创建漏洞复现

0x01 产品简介 金斗云智慧商业软件是一款功能强大、易于使用的智慧管理系统,通过智能化的管理工具,帮助企业实现高效经营、优化流程、降低成本,并提升客户体验。无论是珠宝门店、4S店还是其他零售、服务行业,金斗云都能提供量身定制的解决方案,助力企业实现数字化转型和智…

12.x86游戏实战-汇编指令and or not

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;11.x86游戏实战-汇编指令add sub inc dec and指令是与的意思 or指令是或的意思 …

MUX VLAN实现二层流量的弹性管控

一、模拟场景&#xff0c;企业有一台服务器&#xff0c;部门A&#xff0c;部门B&#xff0c;访客 二、要求&#xff1a;三者都可以访问服务器&#xff0c;部门A和B可以进行部门内部通信&#xff0c;A和B不可以通信&#xff0c;访客只能访问服务器 三、拓扑如下图 四、配置流程…

Linux系统(Centos)下MySQL数据库中文乱码问题解决

问题描述&#xff1a;在进行数据库使用过程中&#xff0c;数据库里的数据中文都显示乱码。操作数据库的时候&#xff0c;会出现中文乱码问题。 解决方法如下&#xff1a; 第一步&#xff1a;打开虚拟机进入系统&#xff0c;启动MySQL。 第二步&#xff1a;连接登录MySQL输入…

执行力不足是因为选择模糊

选择模糊&#xff1a;执行力不足的根源 选择模糊是指在面对多个选项时&#xff0c;缺乏明确的目标和方向。这种模糊感会导致犹豫不决&#xff0c;进而影响我们的执行力。 选择模糊的表现&#xff1a; 目标不明确&#xff0c;不知道应该做什么。优先级混乱&#xff0c;不清楚…

分布式技术栈、微服务架构 区分

1.分布式技术栈 这些技术栈都是为了更好的开发分布式架构的项目。 &#xff08;大营销平台的系统框架如下图&#xff0c;扩展的分布式技术栈&#xff09; &#xff08;1&#xff09;Dubbo——分布式技术栈 DubboNacos注册中心是应用可以分布式部署&#xff0c;并且提供RPC接…

Codeforces Round 955 E. Number of k-good subarrays【分治、记忆化】

E. Number of k-good subarrays 题意 定义 b i t ( x ) bit(x) bit(x) 为 x x x 的二进制表示下 1 1 1 的数量 一个数组的子段被称为 k − g o o d k-good k−good 的当且仅当&#xff1a;对于这个子段内的每个数 x x x&#xff0c;都有 b i t ( x ) ≤ k bit(x) \leq k…

鸿蒙开发管理:【@ohos.account.distributedAccount (分布式帐号管理)】

分布式帐号管理 本模块提供管理分布式帐号的一些基础功能&#xff0c;主要包括查询和更新帐号登录状态。 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff…

自动化设备上位机设计 四

目录 一 设计原型 二 后台代码 一 设计原型 二 后台代码 using SimpleTCP; using SqlSugar; using System.Text;namespace 自动化上位机设计 {public partial class Form1 : Form{SqlHelper sqlHelper new SqlHelper();SqlSugarClient dbContent null;bool IsRun false;i…

论文翻译 | (DSP)展示-搜索-预测:为知识密集型自然语言处理组合检索和语言模型

摘要 检索增强式上下文学习已经成为一种强大的方法&#xff0c;利用冻结语言模型 (LM) 和检索模型 (RM) 来解决知识密集型任务。现有工作将这些模型结合在简单的“检索-读取”流程中&#xff0c;其中 RM 检索到的段落被插入到 LM 提示中。 为了充分发挥冻结 LM 和 RM 的…

# Sharding-JDBC 从入门到精通(9)- 综合案例(二)添加商品

Sharding-JDBC 从入门到精通&#xff08;9&#xff09;- 综合案例&#xff08;二&#xff09;添加商品 一、Sharding-JDBC 综合案例-添加商品-dao 1、在 shopping 子工程&#xff08;子模块&#xff09;中&#xff0c;创建 dao 接口类 ProductDao.java /*** dbsharding\sh…

基于深度学习LightWeight的人体姿态之行为识别系统源码

一. LightWeight概述 light weight openpose是openpose的简化版本&#xff0c;使用了openpose的大体流程。 Light weight openpose和openpose的区别是&#xff1a; a 前者使用的是Mobilenet V1&#xff08;到conv5_5&#xff09;&#xff0c;后者使用的是Vgg19&#xff08;前10…

哈希表——C语言

哈希表&#xff08;Hash Table&#xff09;是一种高效的数据结构&#xff0c;能够在平均情况下实现常数时间的查找、插入和删除操作。 哈希表的核心是哈希函数&#xff0c;哈希函数是一个将输入数据&#xff08;通常称为“键”或“key”&#xff09;转换为固定长度的整数的函数…

Efficient Contrastive Learning for Fast and Accurate Inference on Graphs

发表于:ICML24 推荐指数: #paper/⭐⭐⭐ 创新点一颗星,证明三颗星(证明的不错,值得借鉴,但是思路只能说还行吧) 如图, 本文采取的创新点就是MLP用原始节点,GCN用邻居节点的对比学习.这样,可以加快运算速度 L E C L − 1 ∣ V ∣ ∑ v ∈ V 1 ∣ N ( v ) ∣ ∑ u ∈ N ( v )…