unity实现回旋镖函数
最近学习unity2D,想实现一个回旋镖武器,发出后就可以在角色周围回旋。
一、目标
1.不是一次性的,扔出去、返回、没有了;而是扔出去,返回到角色后方相同距离,再次返回;再次返回,永远不停止。
2.销毁的时机,是这个武器与角色再次重合的时候,相当于回收回旋镖;如果不回收(例如跳跃躲开),那就一直转。
3.角色的位置会移动,回旋镖得多次判断下一个目标点的位置。
4.回旋镖的速度,需要从最大速度开始,到接近目标点的时候逐渐减速;返回时也要从最大速度开始,到接近目标点的时候减速。
总的来说,就是类似《忍者龙剑传3》里,那个十字回旋镖武器的效果,如果跳跃躲开,就会一直在身边转。
二、问题
实际写代码实现的时候,才发现有一堆坑。
1.回旋镖的坐标,不能完全到达目标点,因为unity是按帧算的,每帧移动多少速度的话,可能会超过目标点,或者没有到达目标点,有误差。
2.如果只以接近目标点判断的话,会丢失距离,每次回旋的距离逐渐变近,最后停留原地不动了。
3.如果角色坐标移动,回旋镖计算目标点并重新移动时,经常速度变为0,卡在原地不动(不确定哪里出bug了)。
三、代码部分
//这部分代码,在武器代码cs部分float weaponRange = 3;float weaponSpeed = 15;//当前已飞行的距离float distanceTravelled = 0f;//当前武器位置到目标点的总距离float distanceToTarget;//目标点在哪边bool targetIsRight = false;[SerializeField] Transform weaponPos;Func<Vector2> weaponPosFunc;Vector2 targetPos;Vector2 nowSpeed;Animator animator;Rigidbody2D rb2d;SpriteRenderer sprite;CircleCollider2D cc2d;void Awake(){animator = GetComponent<Animator>();cc2d = GetComponent<CircleCollider2D>();rb2d = GetComponent<Rigidbody2D>();sprite = GetComponent<SpriteRenderer>();}//发射武器方法,其他类调用public void Shoot(bool isFaceingRight) {Vector2 newTarget;//其他类传来的,一开始武器起点坐标Vector2 v = weaponPosFunc();//bool类型,武器图片,如果角色面朝右边就是true,就翻转图片,否则不翻转sprite.flipX = isFaceingRight;//bool类型,武器的目标点方向,后面会用targetIsRight = isFaceingRight;//赋值,刚开始武器到目标点的距离distanceToTarget = Vector2.Distance(weaponPos.position, targetPos);//首次武器目标点,直线,看是角色面前还是背后//targetPos就是武器目标点if (!isFaceingRight) { newTarget = new Vector2(v.x - weaponRange, v.y);targetPos = newTarget;}else{newTarget = new Vector2(v.x + weaponRange, v.y);targetPos = newTarget;}}//更新方法,系统会每帧调用void Update(){// 向目标位置飞行,并逐步减速,到达目标点要掉头,反复重复MoveTowardsTarget();}void MoveTowardsTarget(){//已经走过的距离/物体到目标的距离float dPercent = distanceTravelled / distanceToTarget;if(dPercent < 0){dPercent = -dPercent;}if(dPercent > 1){dPercent = 1;}// 计算当前的速度因子,使物体从快到慢;weaponSpeed是初始武器速度//Lerp方法,就是dPercent为0时,返回第一个参数;为1时返回第二个参数;0-1之间时就返回第一个参数到第二个参数之间的值float speedFactor = Mathf.Lerp(weaponSpeed, 0f, dPercent);//确定一个最慢速度,否则速度因子接近0,越来越慢,很难到目标if(speedFactor < 2f){speedFactor = 2f;}// 计算朝目标位置的方向,方向向量Vector2 direction = (targetPos - (Vector2)weaponPos.position).normalized;//如果方向向量变为0,就没办法移动了,此时要指定一个默认方向向量if(direction.x == 0 && direction.y == 0){//如果目标点在右边,方向向量就是右边;否则左边if (targetIsRight){direction = new Vector2(1,0);}else{direction = new Vector2(-1, 0);}}//设置物体的速度,方向向量*速度因子//设置了这个,武器就会开始移动rb2d.velocity = direction*speedFactor;//保存当前速度,后续可能用nowSpeed = direction * speedFactor;// 更新已飞行的距离,刚开始是0;每一帧移动速度*每一帧时间=路程,然后累加distanceTravelled += rb2d.velocity.magnitude * Time.deltaTime;//打印日志,武器到目标点的距离//Debug.Log("distanceToTarget"+ distanceToTarget);// 如果 (超过目标点 或者 接近目标点) 并且 至少走够了武器路程//需要分左右,才能知道是没到目标点还是超过目标点,需要超过目标点;是否超过目标点就先用x判断了;y又复杂了,还得分上下//防止没到目标点就卡住,又加了接近目标点if (targetIsRight){if ( ((targetPos.x <= weaponPos.position.x) || distanceToTarget<=0.1) && distanceTravelled >= weaponRange){//重置目标点FreshTargetPos();}}else{if ( ((targetPos.x >= weaponPos.position.x) || distanceToTarget<=0.1) && distanceTravelled >= weaponRange){//重置目标点FreshTargetPos();}}}void FreshTargetPos() {//玩家当前坐标,实时获取(玩家的武器发射点的坐标)Vector2 p = weaponPosFunc();//武器当前坐标Vector2 w = weaponPos.position;//w点关于p点的对称点//targetPos = new Vector2( 2*p.x -w.x , 2*p.y -w.y );// 计算朝目标位置的方向,方向向量,扩大武器范围倍数Vector2 direction = (p - (Vector2)w).normalized * weaponRange;//算出下一个目标点targetPos = new Vector2(direction.x+p.x, direction.y+p.y);//看目标点到底在哪里,然后判断有没有超过目标点if (targetPos.x > weaponPos.position.x){targetIsRight = true;}else{targetIsRight = false;}//已走过的路程归零distanceTravelled = 0;// 重新计算物体到目标的距离,weaponPos是当前武器坐标,targetPos是目标点坐标;得到的是距离distanceToTarget = Vector2.Distance(weaponPos.position, targetPos);}
四、备注
unity代码比较多,就贴重要部分了,关于坐标的计算;
目前代码就是这个版本了,大概实现了需求;
武器当前速度处理还可能有些问题,但是可以在玩家周围回旋了;
如果玩家静止或者直线移动,武器就在x轴上回旋;
如果玩家跳跃,武器就会斜方向回旋到玩家背后;
感觉情况有些复杂,可能哪里还有bug,欢迎留言指正。
五、效果图片




如图,可以在角色周围水平回旋,斜方向也可以。
相关文章:
unity实现回旋镖函数
最近学习unity2D,想实现一个回旋镖武器,发出后就可以在角色周围回旋。 一、目标 1.不是一次性的,扔出去、返回、没有了;而是扔出去,返回到角色后方相同距离,再次返回;再次返回,永远…...
想品客老师的第九天:原型和继承
原型与继承前置看这里 原型 原型都了解了,但是不是所有对象都有对象原型 let obj1 {}console.log(obj1)let obj2 Object.create(null, {name: {value: 荷叶饭}})console.log(obj2) obj2为什么没有对象原型?obj2是完全的数据字典对象,没有…...
力扣【416. 分割等和子集】详细Java题解(背包问题)
首先我们可以求出数组和,当我们找到一个子集中元素的和为数组和的一半时,该就说明可以分割等和子集。 对于该问题我们可以转换成背包问题,求 数组里的元素 装入 数组和的一半大小的背包 能取得的最大值。 然后注意可以剪枝的地方。 代码&…...
2025年AI手机集中上市,三星Galaxy S25系列上市
2025年被认为是AI手机集中爆发的一年,各大厂商都会推出搭载人工智能的智能手机。三星Galaxy S25系列全球上市了。 三星Galaxy S25系列包含S25、S25和S25 Ultra三款机型,起售价为800美元(约合人民币5800元)。全系搭载骁龙8 Elite芯…...
为AI聊天工具添加一个知识系统 之79 详细设计之20 正则表达式 之7
本文要点 Q750、今天我们继续聊 本中的正则表达式。 在本项目(为AI聊天工具添加一个知识系统)中,将“正则表达式” 本来是计算机科学计算机科学的一个概念, 推广(扩张)到认知科学的“认知范畴”概念&#…...
理解PLT表和GOT表
1 简介 现代操作系统都是通过库来进行代码复用,降低开发成本提升系统整体效率。而库主要分为两种,一种是静态库,比如windows的.lib文件,macos的.a,linux的.a,另一种是动态库,比如windows的dll文…...
6 年没回老家过年了
今天是 2025 年的第一天,我们一家三口去了地坛庙会玩了会儿。 不是说过年的北京是空城吗?我愣是没抢到大年初一的门票,只好在咸鱼上溢价 40 买了两张票。 坐了一个小时的地坛终于到了,谁知迎来的是人山人海,同时小白牙…...
【原创改进】SCI级改进算法,一种多策略改进Alpha进化算法(IAE)
目录 1.前言2.CEC2017指标3.效果展示4.探索开发比5.定性分析6.附件材料7.代码获取 1.前言 本期推出一期原创改进——一种多策略改进Alpha进化算法(IAE)~ 选择CEC2017测试集低维(30dim)和高维(100dim)进行测…...
如何把一个python文件打包成一步一步安装的可执行程序
将一个 Python 文件打包成可执行程序(如 .exe 文件),并实现一步一步的安装过程,通常需要以下步骤: 1. 将 Python 文件打包成可执行文件 使用工具将 Python 脚本打包成可执行文件(如 .exe)。常用…...
防火墙安全策略部署
目录: 一、实验拓扑: 二、实验要求: 三、需求分析: 四、详细设计: 五、实验步骤: 1.进行vlan划分: 2.IP配置: 3.云端服务配置: 4.划分子网: 5.防火墙…...
c++ map/multimap容器 学习笔记
1 map的基本概念 简介: map中所有的元素都是pair pair中第一个元素是key(键),第二个元素是value(值) 所有元素都会根据元素的键值自动排序。本质: map/multimap 属于关联式容器,底…...
【解决方案】MuMu模拟器移植系统进度条卡住98%无法打开
之前在Vmware虚拟机里配置了mumu模拟器,现在想要移植到宿主机中 1、虚拟机中的MuMu模拟器12-1是目标系统,对应的目录如下 C:\Program Files\Netease\MuMu Player 12\vms\MuMuPlayer-12.0-1 2、Vmware-虚拟机-设置-选项,启用共享文件夹 3、复…...
日志收集Day007
1.配置ES集群TLS认证: (1)elk101节点生成证书文件 cd /usr/share/elasticsearch ./bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass "" --days 3650 (2)elk101节点为证书文件修改属主和属组 chown elasticsearch:elasticsearch con…...
虚拟机里网络设置-桥接与NAT
桥接(Bridging)和NAT(网络地址转换,Network Address Translation)是网络中的两种不同技术,主要用于数据包的处理和转发。以下是它们的主要区别: 1. 工作原理 桥接: 桥接工作在数据链…...
人工智能 - 1
深度强化学习(Deep Reinforcement Learning) 图神经网络(Graph Neural Networks, GNNs) Transformer 一种深度学习模型 大语言模型(Large Language Models, LLMs) 人工智能 • Marvin Minsky 将其定义…...
小程序-基础加强-自定义组件
前言 这次讲自定义组件 1. 准备今天要用到的项目 2. 初步创建并使用自定义组件 这样就成功在home中引入了test组件 在json中引用了这个组件才能用这个组件 现在我们来实现全局引用组件 在app.json这样使用就可以了 3. 自定义组件的样式 发现页面里面的文本和组件里面的文…...
Kafka 压缩算法详细介绍
文章目录 一 、Kafka 压缩算法概述二、Kafka 压缩的作用2.1 降低网络带宽消耗2.2 提高 Kafka 生产者和消费者吞吐量2.3 减少 Kafka 磁盘存储占用2.4 减少 Kafka Broker 负载2.5 降低跨数据中心同步成本 三、Kafka 压缩的原理3.1 Kafka 压缩的基本原理3.2. Kafka 压缩的工作流程…...
单词翻转(信息学奥赛一本通1144)
题目来源 信息学奥赛一本通(C版)在线评测系统 题目描述 1144:单词翻转 时间限制: 1000 ms 内存限制: 65536 KB 提交数:60098 通过数: 26099 【题目描述】 输入一个句子(一行),将句子中的每一个单词翻转后输出。 【输入…...
DeepSeek 模型全览:探索不同类别的模型
DeepSeek 是近年来备受关注的 AI 研究团队,推出了一系列先进的深度学习模型,涵盖了大语言模型(LLM)、代码生成模型、多模态模型等多个领域。本文将大概介绍 DeepSeek 旗下的不同类别的模型,帮助你更好地理解它们的特点…...
我的2024年年度总结
序言 在前不久(应该是上周)的博客之星入围赛中铩羽而归了。虽然心中颇为不甘,觉得这一年兢兢业业,每天都在发文章,不应该是这样的结果(连前300名都进不了)。但人不能总抱怨,总要向前…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
