当前位置: 首页 > news >正文

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&#xff0c;想实现一个回旋镖武器&#xff0c;发出后就可以在角色周围回旋。 一、目标 1.不是一次性的&#xff0c;扔出去、返回、没有了&#xff1b;而是扔出去&#xff0c;返回到角色后方相同距离&#xff0c;再次返回&#xff1b;再次返回&#xff0c;永远…...

想品客老师的第九天:原型和继承

原型与继承前置看这里 原型 原型都了解了&#xff0c;但是不是所有对象都有对象原型 let obj1 {}console.log(obj1)let obj2 Object.create(null, {name: {value: 荷叶饭}})console.log(obj2) obj2为什么没有对象原型&#xff1f;obj2是完全的数据字典对象&#xff0c;没有…...

力扣【416. 分割等和子集】详细Java题解(背包问题)

首先我们可以求出数组和&#xff0c;当我们找到一个子集中元素的和为数组和的一半时&#xff0c;该就说明可以分割等和子集。 对于该问题我们可以转换成背包问题&#xff0c;求 数组里的元素 装入 数组和的一半大小的背包 能取得的最大值。 然后注意可以剪枝的地方。 代码&…...

2025年AI手机集中上市,三星Galaxy S25系列上市

2025年被认为是AI手机集中爆发的一年&#xff0c;各大厂商都会推出搭载人工智能的智能手机。三星Galaxy S25系列全球上市了。 三星Galaxy S25系列包含S25、S25和S25 Ultra三款机型&#xff0c;起售价为800美元&#xff08;约合人民币5800元&#xff09;。全系搭载骁龙8 Elite芯…...

为AI聊天工具添加一个知识系统 之79 详细设计之20 正则表达式 之7

本文要点 Q750、今天我们继续聊 本中的正则表达式。 在本项目&#xff08;为AI聊天工具添加一个知识系统&#xff09;中&#xff0c;将“正则表达式” 本来是计算机科学计算机科学的一个概念&#xff0c; 推广&#xff08;扩张&#xff09;到认知科学的“认知范畴”概念&#…...

理解PLT表和GOT表

1 简介 现代操作系统都是通过库来进行代码复用&#xff0c;降低开发成本提升系统整体效率。而库主要分为两种&#xff0c;一种是静态库&#xff0c;比如windows的.lib文件&#xff0c;macos的.a&#xff0c;linux的.a&#xff0c;另一种是动态库&#xff0c;比如windows的dll文…...

6 年没回老家过年了

今天是 2025 年的第一天&#xff0c;我们一家三口去了地坛庙会玩了会儿。 不是说过年的北京是空城吗&#xff1f;我愣是没抢到大年初一的门票&#xff0c;只好在咸鱼上溢价 40 买了两张票。 坐了一个小时的地坛终于到了&#xff0c;谁知迎来的是人山人海&#xff0c;同时小白牙…...

【原创改进】SCI级改进算法,一种多策略改进Alpha进化算法(IAE)

目录 1.前言2.CEC2017指标3.效果展示4.探索开发比5.定性分析6.附件材料7.代码获取 1.前言 本期推出一期原创改进——一种多策略改进Alpha进化算法&#xff08;IAE&#xff09;~ 选择CEC2017测试集低维&#xff08;30dim&#xff09;和高维&#xff08;100dim&#xff09;进行测…...

如何把一个python文件打包成一步一步安装的可执行程序

将一个 Python 文件打包成可执行程序&#xff08;如 .exe 文件&#xff09;&#xff0c;并实现一步一步的安装过程&#xff0c;通常需要以下步骤&#xff1a; 1. 将 Python 文件打包成可执行文件 使用工具将 Python 脚本打包成可执行文件&#xff08;如 .exe&#xff09;。常用…...

防火墙安全策略部署

目录&#xff1a; 一、实验拓扑&#xff1a; 二、实验要求&#xff1a; 三、需求分析&#xff1a; 四、详细设计&#xff1a; 五、实验步骤&#xff1a; 1.进行vlan划分&#xff1a; 2.IP配置&#xff1a; 3.云端服务配置&#xff1a; 4.划分子网&#xff1a; 5.防火墙…...

c++ map/multimap容器 学习笔记

1 map的基本概念 简介&#xff1a; map中所有的元素都是pair pair中第一个元素是key&#xff08;键&#xff09;&#xff0c;第二个元素是value&#xff08;值&#xff09; 所有元素都会根据元素的键值自动排序。本质&#xff1a; map/multimap 属于关联式容器&#xff0c;底…...

【解决方案】MuMu模拟器移植系统进度条卡住98%无法打开

之前在Vmware虚拟机里配置了mumu模拟器&#xff0c;现在想要移植到宿主机中 1、虚拟机中的MuMu模拟器12-1是目标系统&#xff0c;对应的目录如下 C:\Program Files\Netease\MuMu Player 12\vms\MuMuPlayer-12.0-1 2、Vmware-虚拟机-设置-选项&#xff0c;启用共享文件夹 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

桥接&#xff08;Bridging&#xff09;和NAT&#xff08;网络地址转换&#xff0c;Network Address Translation&#xff09;是网络中的两种不同技术&#xff0c;主要用于数据包的处理和转发。以下是它们的主要区别&#xff1a; 1. 工作原理 桥接&#xff1a; 桥接工作在数据链…...

人工智能 - 1

深度强化学习&#xff08;Deep Reinforcement Learning&#xff09; 图神经网络&#xff08;Graph Neural Networks, GNNs&#xff09; Transformer 一种深度学习模型 大语言模型&#xff08;Large Language Models, LLMs&#xff09; 人工智能 • 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)

题目来源 信息学奥赛一本通&#xff08;C版&#xff09;在线评测系统 题目描述 1144&#xff1a;单词翻转 时间限制: 1000 ms 内存限制: 65536 KB 提交数:60098 通过数: 26099 【题目描述】 输入一个句子(一行)&#xff0c;将句子中的每一个单词翻转后输出。 【输入…...

DeepSeek 模型全览:探索不同类别的模型

DeepSeek 是近年来备受关注的 AI 研究团队&#xff0c;推出了一系列先进的深度学习模型&#xff0c;涵盖了大语言模型&#xff08;LLM&#xff09;、代码生成模型、多模态模型等多个领域。本文将大概介绍 DeepSeek 旗下的不同类别的模型&#xff0c;帮助你更好地理解它们的特点…...

我的2024年年度总结

序言 在前不久&#xff08;应该是上周&#xff09;的博客之星入围赛中铩羽而归了。虽然心中颇为不甘&#xff0c;觉得这一年兢兢业业&#xff0c;每天都在发文章&#xff0c;不应该是这样的结果&#xff08;连前300名都进不了&#xff09;。但人不能总抱怨&#xff0c;总要向前…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...