教培參考
教育培訓(xùn)行業(yè)知識型媒體
發(fā)布時間: 2025年05月28日 02:49
https://docs.unity3d.com/cn/2019.4/scriptReference/Rigidbody.AddForce.html
https://docs.unity3d.com/cn/2019.4/scriptReference/ForceMode.html
Unity中關(guān)于作用力方式ForceMode的功能注解
功能注解:ForceMode為枚舉類型,用來控制力的作用方式,有4個枚舉成員,在以下舉例中均設(shè)剛體質(zhì)量為m=2.0f,力向量為f=(10.0f,0.0f,0.0f)。
默認方式,使用剛體的質(zhì)量計算,以每幀間隔時間為單位計算動量。設(shè)FixedUpdate()的執(zhí)行頻率采用系統(tǒng)默認值(即0.02s),,則由動量定理f?t=m?v可得:10*0.02=2*v1,從而可得v1=0.1,即每幀剛體在X軸上值增加0.1米,從而可計算得剛體的每秒移動速度為v2=(1/0.02)*v1=5m/s。
在此種作用方式下會忽略剛體的實際質(zhì)量而采用默認值1.0f,時間間隔以系統(tǒng)幀頻間隔計算(默認值為0.02s),即f?t=1.0?v即可得v1= f?t=10*0.02=0.2,即剛體每幀增加0.2米,從而可得剛體的每秒移動速度為v2=(1/0.02)*v1=10m/s。
此種方式采用瞬間力作用方式,即把t的值默認為1,不再采用系統(tǒng)的幀頻間隔,即f?1.0=m?v即可得v1=f/m=10.0/2.0=5.0,即剛體每幀增加5.0米,從而可得剛體每秒的速度為v2=(1/0.02)*5.0=250m/s。
此種作用方式下將忽略剛體的實際質(zhì)量,采用默認質(zhì)量1.0,同時也忽略系統(tǒng)的實際幀頻間隔,采用默認間隔1.0,即f?1.0=1.0?v即可得v1=f=10.0,即剛體每幀沿X軸移動距離為10米,從而可得剛體每秒的速度為v2=(1/0.02)*v1=500m/s。
https://docs.unity.cn/cn/2019.4/scriptReference/Rigidbody-velocity.html
剛體的速度矢量。它表示剛體位置的變化率。
在大多數(shù)情況下,不應(yīng)該直接修改速度,因為這可能導(dǎo)致行為失真 - 改用 AddForce
請勿在每個物理步驟中設(shè)置對象的速度,這將導(dǎo)致不真實的物理模擬。需要更改速度的一個典型用法是第一人稱射擊游戲中的跳躍動作設(shè)計,因為此時需要立即更改速度。
酷游戲的一些bug總結(jié)(濫用FixedUpdate的坑)
Unity3D中Rigidbody.velocity和Addforce的區(qū)別
假設(shè)我們想要做一個2D的跳躍游戲,在這個游戲里我希望我按下跳躍鍵的時候,游戲物體的跳躍高度是恒定的。
那么,如果此時我使用的是addForce顯然不會滿足我的效果,因為經(jīng)過測試,每按一下跳躍鍵,它會被施加一個恒定的力,它跳躍的初始速度會越變越大,每次跳躍的高度和前一次相較變得越來越大(在連續(xù)跳躍的情況下),也就是可以理解成,我現(xiàn)在被施加了一個大小為50的力,在重力作用下我的力的效果在減小,在正向速度還沒有完全消失的情況下,此時我又按了一下跳躍鍵,那么就會在這個力的基礎(chǔ)上再施加一次大小為50的力,物體會越跳越快,越跳越高。
而此時如果我們使用的是velocity方法 改變它的初始速度到我們希望的值和方向,那么當我們按下跳躍鍵的時候,無論此時物體減速到何種情況,也最多只會提升到我們規(guī)定的速度以及朝向我們規(guī)定的方向。初始速度不變的情況下,跳躍高度也是恒定的。
解決:
AddForce之前應(yīng)該清一下速率,因為是射線檢測是否碰到地面,而跳躍后不會立刻離地。如果不清,后面幾幀會累加AddForce。清除速率保證離地的一瞬間肯定是正常Force,而非累加Force。
我們常在Unity開發(fā)中直接使用Rigidbody.velocity屬性來獲取剛體的當前速度,這在大多數(shù)情況下是沒有問題的。但在某些情況下這么做就可能得不到我們想要的結(jié)果。比如通過transform.Translate(),transform.RotateAround(),rigidbody.MovePosition(),Vector3.MoveTowards() 等方法 “強制” 改變剛體的運動狀態(tài)時,此時物體速度的改變并不會引起Rigidbody.velocity的改變。
而當我們把所有球的剛體組件中的Is Kinematic屬性勾選上后,我們再來看看運行結(jié)果:
OMG!【僅移動】小球的Rigidbody.velocity居然又和真實速率一致了!
我并不了解Rigidbody.velocity這個屬性在內(nèi)部是如何被定義的,官方文檔沒有相關(guān)的說明,網(wǎng)上也沒有找到相關(guān)的資料,我個人只能根據(jù)這些現(xiàn)象做如下的一些推測。
當剛體的Is Kinematic沒有被勾選時,剛體的運動就被Unity的物理引擎所掌控,物體的運動和狀態(tài)都會遵循真實世界的物理定律。我們知道,在牛頓力學(xué)中,要改變一個物體的運動狀態(tài)必須要對其施加力,Unity也為我們提供了AddForce()方法。然而像MovePosition()這樣的方法似乎可以讓物體的運動隨心所欲,能夠以任意速度到達任意位置,可以讓物體瞬間加到一個非常大的速度。顯而易見,這種對運動狀態(tài)的 “ 強制 ” 改變必定不能通過加力的方式實現(xiàn),這就已經(jīng)脫離了真實世界的物理定律了。被物理引擎控制的物體擅自進行了不按套路的操作,Rigidbody.velocity就不會記錄這種 “非法” 操作帶來的速度改變,或者將這種非法操作對velocity的改變視為0。
反之,當剛體的Is Kinematic被勾選時,剛體的運動就脫離了Unity的物理引擎控制。風(fēng)水輪流轉(zhuǎn),天道好輪回,這種情況下MovePosition()成了合法操作,AddForce()成了非法操作了。想要報仇雪恨的MovePosition()積攢了多年的怨氣,對非法操作的限制變得更為嚴格,之前的情況還允許非法操作對物體運動狀態(tài)的改變,這次已經(jīng)完全屏蔽了AddForce()的作用。從上一張截圖就可看出,這次即便加力物體也始終保持靜止。此時此刻MovePosition()終于作為合法操作被Rigidbody.velocity認可,使其能夠反映物體真實速率。
總結(jié)
通過以上案例,我的想法就是最好不要對未勾選Is Kinematic的剛體使用 transform.Translate(),transform.RotateAround(),rigidbody.MovePosition(),Vector3.MoveTowards() 等等這些方法,畢竟這些非常規(guī)操作必定會對物理模擬的真實性產(chǎn)生影響。如果你不得不使用時,也請注意Rigidbody.velocity并不是物體在場景和游戲視圖中的真實速度,不要濫用這些方法和這個屬性而不小心掉入它的 “ 陷阱 ”。
https://docs.unity.cn/cn/2019.4/Manual/class-ConstantForce.html
恒定力 (Constant Force) 可用于快速向 剛體 添加恒定力。如果不希望某些一次性對象以較大的速度開始而是逐漸加速(比如火箭),則很適合使用恒定力。
要制作一個向前加速的火箭,請將 Relative Force 設(shè)定為沿正 z 軸。然后,使用剛體的 Drag 屬性使其不超過某個最大速度(阻力越高,最大速度越低)。在剛體中,還要確保關(guān)閉重力,以便火箭始終保持在其路徑上。
1.首先,打開自己的unity3d場景,如下所示。
2.然后創(chuàng)建一個基本的模型對象在該方案中,如下所示。
3.向?qū)ο筇砑覴igidbody屬性,如下圖。
4.創(chuàng)建兩個腳本,Add_script和力量,如下所示。
5.打開Add_script,通過內(nèi)表面的AddComponent將Forcescript添加到objectCapsule中,通過Destroy刪除script組件,分別設(shè)置space和delete按鈕。
UnityEngineInternal。APIUpdaterRuntimeServices。AddComponent (GameObject。查找(“膠囊”)、“添加力”、“力”);銷毀(GetComponent < Force >())。
6.將Add_script腳本添加到對象中,如下圖。
7.按空格鍵將force腳本添加到對象山中。
8.現(xiàn)在,您可以添加一個力對象移動的對象,所以腳本,如下所示。
9.然后按下刪除鍵,腳本對象將被刪除,讓您可以靈活地將刪除腳本添加到對象,如下所示。
以上就是小編整理的Unity 物理系列二 AddForce velocity相關(guān)信息。關(guān)注培訓(xùn)啦了解更多相關(guān)知識!(本文共7136字)
微信掃碼關(guān)注公眾號
獲取更多考試熱門資料