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,歡迎留言指正。

五、效果圖片

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

如圖,可以在角色周圍水平回旋,斜方向也可以。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/894496.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/894496.shtml
英文地址,請注明出處:http://en.pswp.cn/news/894496.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++基礎】字符串/字符讀取函數解析

最近在學C以及STL&#xff0c;打個基礎 參考&#xff1a; c中的char[] ,char* ,string三種字符串變量轉化的兼容原則 c讀取字符串和字符的6種函數 字符串結構 首先明確三種字符串結構的兼容關系&#xff1a;string>char*>char [] string最靈活&#xff0c;內置增刪查改…

求一個數的數根(高精度)

上一期我們講的是求一個數的數根&#xff0c;和本期唯一不同的是&#xff0c;數據范圍不同了&#xff0c;上一期這個數是小于等于10的18次方的&#xff0c;這一期是小于等于10的1000次方的&#xff0c;開一個變量&#xff1f;肯定不行&#xff0c;我們需要再開一個數組&#xf…

SpringBoot源碼解析(九):Bean定義接口體系

SpringBoot源碼系列文章 SpringBoot源碼解析(一)&#xff1a;SpringApplication構造方法 SpringBoot源碼解析(二)&#xff1a;引導上下文DefaultBootstrapContext SpringBoot源碼解析(三)&#xff1a;啟動開始階段 SpringBoot源碼解析(四)&#xff1a;解析應用參數args Sp…

Vue 3 30天精進之旅:Day 13 - 路由守衛

在構建單頁面應用時&#xff0c;路由守衛是一個非常重要的概念。它允許我們在路由進入或離開時執行一些操作&#xff0c;比如驗證用戶權限、處理數據加載、執行導航確認等。Vue Router提供了多種類型的路由守衛&#xff0c;使我們能夠靈活地控制路由的行為。在今天的學習中&…

【TypeScript】基礎:數據類型

文章目錄 TypeScript一、簡介二、類型聲明三、數據類型anyunknownnervervoidobjecttupleenumType一些特殊情況 TypeScript 是JavaScript的超集&#xff0c;代碼量比JavaScript復雜、繁多&#xff1b;但是結構更清晰 一、簡介 為什么需要TypeScript&#xff1f; JavaScript的…

C++模板編程——可變參函數模板

目錄 1. 可變參函數模板基本介紹 2. 參數包展開——通過遞歸函數 3. 參數包展開——通過編譯期間if語句(constexpr if) 4. 重載 5. 后記 進來看的小伙伴們應該對C中的模板有了一定了解&#xff0c;下面給大家介紹一下可變參函數模板。過于基礎的概念將不仔細介紹。 1. 可變…

ChatGPT-4o和ChatGPT-4o mini的差異點

在人工智能領域&#xff0c;OpenAI再次引領創新潮流&#xff0c;近日正式發布了其最新模型——ChatGPT-4o及其經濟實惠的小型版本ChatGPT-4o Mini。這兩款模型雖同屬于ChatGPT系列&#xff0c;但在性能、應用場景及成本上展現出顯著的差異。本文將通過圖文并茂的方式&#xff0…

三數之和(15)

15. 三數之和 - 力扣&#xff08;LeetCode&#xff09; 可以一起總結的題目&#xff1a;三角形的最大周長&#xff08;976&#xff09;-CSDN博客 解法&#xff1a; class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {vector…

2025最新源支付V7全套開源版+Mac云端+五合一云端

2025最新源支付V7全套開源版Mac云端五合一云端 官方1999元&#xff0c; 最新非網上那種功能不全帶BUG開源版&#xff0c;可以自己增加授權或二開 擁有卓越的性能和豐富的功能。它采用全新輕量化的界面UI&#xff0c;讓您能更方便快捷地解決知識付費和運營贊助的難題 它基于…

9 點結構模塊(point.rs)

一、point.rs源碼 use super::UnknownUnit; use crate::approxeq::ApproxEq; use crate::approxord::{max, min}; use crate::length::Length; use crate::num::*; use crate::scale::Scale; use crate::size::{Size2D, Size3D}; use crate::vector::{vec2, vec3, Vector2D, V…

數據分析系列--[12] RapidMiner辨別分析(含數據集)

一、數據準備 二、導入數據 三、數據預處理 四、建模辨別分析 五、導入測試集進行辨別分析 一、數據準備 點擊下載數據集 二、導入數據 三、數據預處理 四、建模辨別分析 五、導入測試集進行辨別分析 Ending, congratulations, youre done.

Day33【AI思考】-函數求導過程 的優質工具和網站

文章目錄 **函數求導過程** 的優質工具和網站**一、動態圖形工具**1. **Desmos&#xff08;網頁端&#xff09;**2. **GeoGebra&#xff08;全平臺&#xff09;** **二、分步推導工具**3. **Wolfram Alpha&#xff08;網頁/App&#xff09;**4. **Symbolab&#xff08;網頁/App…

個人筆記(很沒營養,純備忘錄)

1.輸入電阻和輸出電阻指在一個可劃分為3部分的電路中&#xff0c;中間部分電路相當于前面電路的負載有輸入端電阻&#xff0c;稱輸入電阻&#xff0c;相對于后面部分等效為電源有輸出端內阻&#xff0c;稱輸出電阻 理所當然的希望輸出電阻對負載影響小&#xff0c;輸入電阻能完…

當卷積神經網絡遇上AI編譯器:TVM自動調優深度解析

從銅線到指令&#xff1a;硬件如何"消化"卷積 在深度學習的世界里&#xff0c;卷積層就像人體中的毛細血管——數量龐大且至關重要。但鮮有人知&#xff0c;一個簡單的3x3卷積在CPU上的執行路徑&#xff0c;堪比北京地鐵線路圖般復雜。 卷積的數學本質 對于輸入張…

51單片機 02 獨立按鍵

一、獨立按鍵控制LED亮滅 輕觸按鍵&#xff1a;相當于是一種電子開關&#xff0c;按下時開關接通&#xff0c;松開時開關斷開&#xff0c;實現原理是通過輕觸按鍵內部的金屬彈片受力彈動來實現接通和斷開。 #include <STC89C5xRC.H> void main() { // P20xFE;while(1){…

系統URL整合系列視頻二(界面原型)

視頻 系統URL整合系列視頻二&#xff08;界面原型&#xff09; 視頻介紹 &#xff08;全國&#xff09;大型分布式系統Web資源URL整合需求界面原型講解。當今社會各行各業對軟件系統的web資源訪問權限控制越來越嚴格&#xff0c;控制粒度也越來越細。安全級別提高的同時也增加…

vscode命令面板輸入 CMake:build不執行提示輸入

CMake&#xff1a;build或rebuild不編譯了&#xff0c;彈出:> [Add a new preset] , 提示輸入發現settings.jsons設置有問題 { "workbench.colorTheme": "Default Light", "cmake.pinnedCommands": [ "workbench.action.tasks.configu…

wax到底是什么意思

在很久很久以前&#xff0c;人類還沒有誕生文字之前&#xff0c;人類就產生了語言&#xff1b;在誕生文字之前&#xff0c;人類就已經使用了語言很久很久。 沒有文字之前&#xff0c;人們的語言其實是相對比較簡單的&#xff0c;因為人類的生產和生活水平非常低下&#xff0c;…

SSRF 漏洞利用 Redis 實戰全解析:原理、攻擊與防范

目錄 前言 SSRF 漏洞深度剖析 Redis&#xff1a;強大的內存數據庫 Redis 產生漏洞的原因 SSRF 漏洞利用 Redis 實戰步驟 準備環境 下載安裝 Redis 配置漏洞環境 啟動 Redis 攻擊機遠程連接 Redis 利用 Redis 寫 Webshell 防范措施 前言 在網絡安全領域&#xff0…

【周易哲學】生辰八字入門講解(八)

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一個正在變禿、變強的文藝傾年。 &#x1f514;本文講解【周易哲學】生辰八字入門講解&#xff0c;期待與你一同探索、學習、進步&#xff0c;一起卷起來叭&#xff01; 目錄 一、六親女命六親星六親宮位相互關系 男命六親星…