Unity 繩子插件 ObjRope 使用簡記

Unity 繩子插件,是一個基于物理的、高度逼真且可交互的繩索模擬解決方案。

其性能良好,能夠運行在小游戲平臺。

一、插件基本

插件資源商店地址:

Obi Rope | Physics | Unity Asset Store

官方文檔(手冊):

Obi Physics for Unity - Rope Setup

官方文檔(API):

Obi - Unified Particle Physics for Unity 3D

1、導入插件

2、按照URP和插件文檔說明,修復材質為URP材質

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.1/manual/upgrading-your-shaders.html

3、安裝Burst?、Collections?、Mathematics?包(unity2021.3.42f1c1)

二、ObiSolver 及相關設置

可以添加到任何GameObject上;

在同一個場景中可以有多個解算器同時工作;

每個Actor都必須在一個 ObiSolver?層級之下才能工作

每個ObiSolver獨立,由不同 ObiSolver更新的 Actor 不會產生相互影響/碰撞。

Solver 設置

Backends

使用哪個模擬后端。Brust性能更好,如果任何給定的后端不可用,Obi 將嘗試回退到 Oni 后端。

Mode

2D 模式通常與 2D 碰撞器一起使用。

Interpolation

用于渲染粒子的插值模式。None計算速度更快,而插值將提供更美觀的結果.插值會引入 1 幀延遲。

模擬設置

Gravity Space

如果設置為“Self”,重力方向將與解算器一起旋轉。

Gravity

應用于此ObiSolver中粒子的重力方向和大小,以ObiSolver的局部空間表示。

Sleep threshold都將凍結

任何動能低于此值的粒子在原地。(忽略微小抖動)

注意,休眠粒子并不會從模擬中移除,也不會節省性能。

Damping

應用于粒子速度的速度阻尼。增加速度阻尼可降低粒子的動能

World linear inertia scale

應用于粒子的世界空間線性(移動)慣性,范圍0~1

控制 運動時突然停止/減速;停止時突然運動或加速的表現

World angular inertia scale

應用于粒子的世界空間角慣性(旋轉),范圍0~1

Max Anisotropy

最大各向異性

Obi 中的流體粒子可以是橢圓形,而不是完美的球形。這用于更好地使其形狀適應它們所代表的物體的表面,從而實現更準確的碰撞檢測和更平滑的渲染。最大各向異性可讓您確定橢圓半徑之間的最大比率:值為 1 將強制所有粒子為球形(停用各向異性),大于 1 的值將允許粒子變得更橢圓,最大各向異性越高。

Simulate when invisible

隱藏時模擬?

當所有相機都看不到該ObiSolver時,該ObiSolver是否應保持模擬繼續進行?

如果您的模擬需要始終更新,請保持啟用此功能;

當場景中存在多個ObiSolver但它們并非始終可見時,請禁用此功能以提高性能。

平流設置平流粒子(泡沫)的全局設置)(暫跳過)

碰撞設置

Collider CCD(Continuous collision detection)

連續碰撞檢測

在碰撞檢測期間用于擴展碰撞體邊界框的剛體速度百分比。值為 1 將使用 100% 的速度,從而產生完全的連續碰撞檢測。值為 0 將導致純靜態碰撞檢測。

Particle CCD (Continuous collision detection)

粒子連續碰撞檢測

在碰撞檢測期間用于擴展其邊界框的粒子速度百分比。值為 1 將使用 100% 的速度,從而產生完全的連續碰撞檢測。值為 0 將導致純靜態碰撞檢測。

Collision margin??Collision margin

碰撞邊距

添加到粒子邊界框的邊距(CCD 擴展后),在生成觸點時使用。粒子邊界框內的任何碰撞體/粒子都將被考慮用于接觸生成。此值應保持相對較低。較大的值將生成更多的接觸,這可以提高非常復雜場景中的穩定性,但會對性能產生負面影響。

Max depenetration??

最大穿透力

使粒子脫離碰撞盒的最大速度(以米/秒為單位)。

Shock propagation??沖擊傳播

較高的值將人為地增加支持其他粒子的粒子的質量。

使用它來獲得更好的堆疊穩定性。

Surface collision iterations
表面碰撞迭代

為優化表面碰撞而執行的最大迭代次數。

Surface collision tolerance
曲面碰撞容差

容差閾值,低于該閾值時,曲面碰撞優化將停止。

稍微增加它有助于獲得與平面更穩定的表面碰撞。

約束設置

您可以為解算器管理的所有角色全局啟用/禁用每種約束類型。以這種方式禁用約束(與禁用單個角色的約束組件相反)將允許解算器完全跳過與該特定約束類型相關的任何計算。

例如,如果禁用碰撞約束和粒子碰撞約束,則會跳過整個碰撞檢測管道。這使您可以自定義在后臺執行的作,并消除不必要的開銷。

默認情況下,所有約束類型都處于啟用狀態,盡管這很少是生產就緒模擬所需的。您應該禁用任何對模擬的最終外觀不重要的約束。

Iterations??

迭代
每個子步驟應該評估這些約束多少次?高迭代計數將使模擬更接近真實解決方案。如果這些約束對于您的特定目的不是很重要,并且您希望獲得更好的性能,請保持較低的值。默認值為 3。

Evaluation mode??

評估模式

在?Sequential (順序) 模式下,所有約束都按照它們的創建順序 (由每個特定的 ObiActor 確定) 進行評估,并且每個約束 “看到” 所有先前的約束所做的調整。這確保了快速收斂,因此您的約束只需要很少的迭代即可看起來不錯。但是,當多個約束爭奪控制權時,它不是很穩定 - 它會引入抖動 - 因此在某些用例中,這種模式不是一個好的選擇。它與順序相關,因此在低預算情況下(少量粒子、少量迭代和/或大時間步長),這可能會導致粒子排列中出現可見的圖案。對于那些稍微懂技術的人來說,這是一個?Gauss-Seidel?類型的求解器。

在?Parallel?模式下,將評估所有約束,但不會立即將其調整應用于粒子。相反,它們被存儲、平均,然后使用最終結果來調整粒子位置。即使同時應用了大量約束,這也能產生非常穩定的模擬,但是“硬”約束需要更多的迭代,因為它的收斂速度更慢。它也是與階次無關的,因此可以確保顆粒的平滑排列。如果您想用性能(高迭代次數)或質量(低迭代次數)來換取穩定性和平滑度,請使用此模式。同樣,對于技術用戶來說:這是類似?Jacobi?的求解。

Relaxation Factor??

松弛因子

連續過度弛豫 (SOR) 因子。當嘗試滿足約束時,提高收斂性的一種方法是 “過度放寬” 約束。也就是說,如果將粒子向左移動 2 個單位現在就滿足約束,為什么不將其移動 3 個單位呢?這正是這個因子的用途。1 是默認值,它根本不執行過度松弛。2 是最大值,它允許您對約束執行兩倍 (200%) 的松弛。高值可用于幫助加快兩種模式(順序或并行)中的任何一種的收斂速度,但請記住,仿真穩定性可能會降低。小于 1 的值將僅部分強制執行約束。例如,當松弛因子為 0.25 時,約束將僅具有其正常效果的 25%。

一塊布、一根繩子、一個流體發射器或一個軟體,它們都是Actor。

所有 Actor 都以藍圖作為輸入。

Actor 將實例化藍圖中包含的信息(粒子和約束),以便解算器可以對其進行模擬。

您可以在多個 Actor 之間重復使用同一個藍圖

如果希望將 Actor 包含在模擬中,則Actor 必須是Resolver的子項

三、原理

本質:

模擬原理,重要!!!

若自己有手寫碰撞需求,亦可參考其實現原理

Obi 的工作原理

物理更新循環

Obi 將萬物建模為一組粒子和約束。

約束,即為:預測后的校正

注意點:

????????順序模式和并行模式

????????更高次數的迭代

????????時間步長

????????較重的物體不會下落得更快

????????物體的絕對質量并不重要,它們的相對質量才是關鍵,通常稱為質量比。

????????警惕較大的質量比,需要增加解算器的預算(迭代/子步)以確保滿足約束。

約束類型一覽

Obi Physics for Unity - Scripting Particles

注意:每個ObiSolver都有一個數組用于這些屬性中的每一個,該數組存儲由解算器管理的任何參與者正在使用的所有粒子的當前數據。所有空間屬性(位置、方向、速度、渦度等)都在解算器的局部空間中表示。

即:繩子的位置基于Solver,會跟著Solver移動,不會受中間層父物體位置的影響

四、具體操作或功能

繩子編輯

Obi Physics for Unity - Rope Setup

將繩子固定在某個點

動態設置繩子位置(移動后同步粒子)

public void SyncParticlesToTransform()
{// 計算當前 GameObject 位置與繩子實際位置的偏移量Vector3 positionOffset = transform.position - m_ObiRope.transform.position;// 遍歷所有粒子并應用偏移for (int i = 0; i < m_ObiRope.particleCount; i++){m_ObiRope.solver.positions.SetVector3(i, m_ObiRope.solver.positions.GetVector3(i) + positionOffset);}// 更新粒子位置并重置物理狀態m_ObiRope.UpdateParticleProperties();m_ObiRope.ResetParticles();
}

繩子撕裂/剪斷

Obi Physics for Unity - Cloth Tearing

Obi Physics for Unity - Scripting Ropes

//從鼠標點擊處切斷
public void Cut(Vector2 mousePosition)
{//不再允許點擊到m_BoxCollider2D.enabled = false;float minDistance = float.MaxValue;int nearestSegmentIndex = -1;// 遍歷所有線段尋找最近點for (int i = 0; i < m_ObiRope.elements.Count; i++){var element = m_ObiRope.elements[i];// 獲取當前元素的兩個粒子的索引int particleIndex1 = element.particle1;int particleIndex2 = element.particle2;// 獲取兩個粒子的世界坐標Vector3 worldPos1 = m_ObiRope.solver.positions.GetVector3(particleIndex1);Vector3 worldPos2 = m_ObiRope.solver.positions.GetVector3(particleIndex2);worldPos1 = m_ObiRope.transform.TransformPoint(worldPos1);worldPos2 = m_ObiRope.transform.TransformPoint(worldPos2);if (!Mathf.Approximately(worldPos1.z, worldPos2.z)) { continue; }   //忽略非XY平面的線段// 計算點擊點與線段的最近點Vector2 clickScreenPos = mousePosition;Vector2 screenPos1 = Camera.main.WorldToScreenPoint(worldPos1);Vector2 screenPos2 = Camera.main.WorldToScreenPoint(worldPos2);Vector2 closestPoint = ClosestPointOnLineSegment(screenPos1, screenPos2, clickScreenPos);float distance = Vector2.Distance(clickScreenPos, closestPoint);// 更新最近記錄if (distance < minDistance){minDistance = distance;nearestSegmentIndex = i;}//繩子線段位置調試//GameObject go1 = new GameObject($"Test{i}_1");//go1.transform.position = worldPos1;//GameObject go2 = new GameObject($"Test{i}_2");//go2.transform.position = worldPos1;}// 獲取控制點 start 和 end 的索引//限制(即:不允許從兩頭斷開)int startIndex = 2;int endIndex = m_ObiRope.elements.Count - 2;int cutIndex = Mathf.Clamp(nearestSegmentIndex, startIndex, endIndex);// 執行切割m_ObiRope.Tear(m_ObiRope.elements[cutIndex]);m_ObiRope.RebuildConstraintsFromElements();//光標設為切割處m_CursorMu = CalculateCursorMu(cutIndex);// 獲取剪開處的2個粒子int particle1_1 = m_ObiRope.elements[cutIndex - 1].particle2;int particle2_1 = m_ObiRope.elements[cutIndex].particle1;// 施加一個指向繩子左側/右側的力(使搖擺)// 施加一個指向屏幕外的力(使看起來像向外崩開)// 施加一個沿著軸向兩端的力(使看起來像扯開)//todo:考慮受 m_CursorMu 的影響float sideForce = 50f;float backForce = 50f;float axisForce = 100f;Axis axis = m_RopeData.GetAxis();float xForce = axis == Axis.Horizontal ? axisForce : -sideForce;float yForce = axis == Axis.Horizontal ? 0 : axisForce;m_ObiRope.solver.velocities[particle1_1] += new Vector4(xForce, yForce, -backForce, 0);m_ObiRope.solver.velocities[particle2_1] += new Vector4(-xForce, -yForce, -backForce, 0);
}private Vector2 ClosestPointOnLineSegment(Vector2 A, Vector2 B, Vector2 P)
{Vector2 AP = P - A;Vector2 AB = B - A;float magnitudeAB = AB.sqrMagnitude;float ABAPproduct = Vector2.Dot(AP, AB);float distance = ABAPproduct / magnitudeAB;if (distance < 0) return A;else if (distance > 1) return B;else return A + AB * distance;
}

繩子收縮

//從光標處收縮(每幀更新)
private void UpdateToShrink()
{float minLength = 0.2f;//修改長度float newLength = m_ObiRope.restLength - ShowConfig.kRopeShrinkSpeed * Time.deltaTime * m_RopeData.GetLength();float safeNewLength = Mathf.Max(newLength, minLength);m_ObiRopeCursor.cursorMu = m_CursorMu;m_ObiRopeCursor.ChangeLength(safeNewLength);if (newLength < minLength) {m_OnShrinkCompleted();}
}

五、性能相關

1、繩子的解算器應開啟 Burst。

2、繩子的解算器,可分為全局大量靜止時(極低消耗設置),剪斷收縮動態表現時(流暢表現設置)

3、繩子的解算器,要關閉不必要的項,數值設置夠用即可。

4、可減少繩子 截面N邊型繩子PathSmooting(縱向網格密),以減少模型面數

5、繩子在2D視角大量靜止時,其?Render Face 可使用 Front(Cull Front) 而非 Both(Cull Off)僅當剪斷收縮表現時,改為Both。

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

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

相關文章

demo 通訊錄 + 城市選擇器 (字母索引左右聯動 ListItemGroup+AlphabetIndexer)筆記

一、城市選擇器實現筆記1. 雙層 for 循環渲染數據結構interface BKCityContent {initial: string; // 字母索引cityNameList: string[]; // 城市列表 }核心實現// 外層循環&#xff1a;字母分組 - 遍歷城市數據&#xff0c;按字母分組顯示 ForEach(this.cityContentList, (item…

【總結型】c語言中的位運算

位運算包括 & | ^ ~ << >>按位與 將某些變量中的某些位清0同時保持其他位不變。也可以用來獲取變量中的某一位。 例如&#xff1a;將int型變量n低8位全置為0&#xff0c;其余位保持不變。 n n & 0xffffff00 如何判斷一個int型變量n的第七位。 n & 0x8…

如何在FastAPI中玩轉APScheduler,實現動態定時任務的魔法?

url: /posts/4fb9e30bb20956319c783e21897a667a/ title: 如何在FastAPI中玩轉APScheduler,實現動態定時任務的魔法? date: 2025-08-16T01:14:26+08:00 lastmod: 2025-08-16T01:14:26+08:00 author: cmdragon summary: APScheduler是Python中強大的任務調度庫,支持任務持久化…

GitHub的簡單使用方法----(5)

最后一篇簡單講講git管理遠程倉庫 1.目的 備份&#xff0c;實現代碼共享集中化管理 &#xff08;將本地倉庫同步到git遠程倉庫中&#xff09; git clone 倉庫地址 以下圖為示例&#xff0c;我打開了一個別人的項目倉庫&#xff0c;點擊code能看到倉庫地址 等待完成即可 如…

C++ STL-string類底層實現

摘要&#xff1a; 本文實現了一個簡易的string類&#xff0c;主要包含以下功能&#xff1a; 1. 默認成員函數&#xff1a;構造函數&#xff08;默認/參數化&#xff09;、拷貝構造、賦值重載和析構函數&#xff0c;采用深拷貝避免內存問題&#xff1b; 2. 迭代器支持&#xff1…

【LeetCode每日一題】

每日一題3. 無重復字符的最長子串題目總體思路代碼1.兩數之和題目總體思路代碼15. 三數之和題目總體思路代碼2025.8.153. 無重復字符的最長子串 題目 給定一個字符串 s &#xff0c;請你找出其中不含有重復字符的 最長 子串 的長度。 示例 1: 輸入: s “abcabcbb” 輸出: 3…

sharding-jdbc讀寫分離配置

一主兩從&#xff0c;爆紅是正常的&#xff0c;不知為啥 spring:shardingsphere:datasource:names: ds_master,ds_s1,ds_s2ds_master:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://192.168.135.100:3306/gmall_produ…

【大模型核心技術】Dify 入門教程

文章目錄一、Dify 是什么二、安裝與部署2.1 云端 SaaS 版&#xff08;快速入門&#xff09;2.2 私有化部署&#xff08;企業級方案&#xff09;三、界面導航與核心模塊3.1 控制臺概覽3.2 核心功能模塊詳解3.2.1 知識庫&#xff08;RAG 引擎&#xff09;3.2.2 工作流編排3.2.3 模…

homebrew 1

文章目錄brew(1) – macOS&#xff08;或 Linux&#xff09;上缺失的包管理器概要描述術語表基本命令install *formula*uninstall *formula*listsearch \[*text*|/*text*/]命令alias \[--edit] \[*alias*|*alias**command*]analytics \[*subcommand*]autoremove \[--dry-run]bu…

設計索引的原則有哪些?

MySQL 索引設計的核心原則是 在查詢性能與存儲成本之間取得平衡。以下是經過實踐驗證的 10 大設計原則及具體實現策略&#xff1a;一、基礎原則原則說明示例/反例1. 高頻查詢優先為 WHERE、JOIN、ORDER BY、GROUP BY 頻繁出現的列建索引? SELECT * FROM orders WHERE user_id1…

使用影刀RPA實現快遞信息抓取

最近公司項目有個需求&#xff0c;要求抓取快遞單號快遞信息&#xff0c;比如簽收地點、簽收日期等。該項目對應的快遞查詢網站是一個國外的網站&#xff0c;他們有專門的快遞平臺可以用于查詢。該平臺提供了快遞接口進行查詢&#xff0c;但需要付費。同時也提供了免費的查詢窗…

蟻劍--安裝、使用

用途限制聲明&#xff0c;本文僅用于網絡安全技術研究、教育與知識分享。文中涉及的滲透測試方法與工具&#xff0c;嚴禁用于未經授權的網絡攻擊、數據竊取或任何違法活動。任何因不當使用本文內容導致的法律后果&#xff0c;作者及發布平臺不承擔任何責任。滲透測試涉及復雜技…

Varjo XR虛擬現實軍用車輛駕駛與操作培訓

Patria基于混合現實的模擬器提供了根據現代車輛乘員需求定制的培訓&#xff0c;與傳統顯示設置相比&#xff0c;全新的模擬解決方案具有更好的沉浸感和更小的物理空間需求。Patria是芬蘭領先的國防、安全和航空解決方案提供商。提供尖端技術和全面的培訓系統&#xff0c;以支持…

Java 10 新特性及具體應用

目錄 1. 局部變量類型推斷&#xff08;JEP 286&#xff09; 2. 不可修改集合&#xff08;JEP 269&#xff09; 3. 并行全垃圾回收&#xff08;JEP 307&#xff09; 4. 應用類數據共享&#xff08;JEP 310&#xff09; 5. 線程局部管控&#xff08;JEP 312&#xff09; 總結…

【力扣 Hot100】刷題日記

D8 全排列(非回溯法) 全排列原題鏈接 在刷leetcode的時候&#xff0c;看到這道題目并沒法使用像STL的next_permutation方法&#xff0c;感嘆C便利的同時&#xff0c;又惋惜Java并沒有類似的API&#xff0c;那我們只能從原理入手了&#xff0c;仿寫此算法。 其實回溯法更應該…

JetPack系列教程(七):Palette——讓你的APP色彩“飛”起來!

JetPack系列教程&#xff08;七&#xff09;&#xff1a;Palette——讓你的APP色彩“飛”起來&#xff01; 各位開發小伙伴們&#xff0c;還在為APP的配色發愁嗎&#xff1f;別擔心&#xff0c;今天咱們就來聊聊JetPack家族里的“色彩魔法師”——Palette&#xff01;這個神奇的…

力扣hot100 | 矩陣 | 73. 矩陣置零、54. 螺旋矩陣、48. 旋轉圖像、240. 搜索二維矩陣 II

73. 矩陣置零 力扣題目鏈接 給定一個 m x n 的矩陣&#xff0c;如果一個元素為 0 &#xff0c;則將其所在行和列的所有元素都設為 0 。請使用 原地 算法。 示例 1&#xff1a; 輸入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 輸出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]…

ARC與eARC是什么?主要用在哪?

在家庭影音設備不斷升級的今天&#xff0c;人們對音視頻體驗的要求越來越高。無論是追劇、玩游戲還是觀看電影大片&#xff0c;很多用戶不再滿足于電視自帶的揚聲器&#xff0c;而是希望借助回音壁、功放或家庭影院系統&#xff0c;獲得更加震撼的沉浸式聲音體驗。一、ARC是什么…

解鎖JavaScript性能優化:從理論到實戰

文章目錄 前言 一、常見性能瓶頸剖析 二、實戰案例與優化方案 (一)DOM 操作優化案例? (二)事件綁定優化案例? (三)循環與遞歸優化案例? (四)內存管理優化案例? 三、性能優化工具介紹 總結 前言 性能優化的重要性 在當今數字化時代,Web 應用已成為人們生活和工作…

結構化記憶、知識圖譜與動態遺忘機制在醫療AI中的應用探析(上)

往期相關內容推薦: 基于Python的多元醫療知識圖譜構建與應用研究(上)