前言
最近在開發一款大量使用到物體碰撞的遊戲,順便釐清了一下剛體AddForce和Velocity使用上的差異。
2018.04.24(二)
在2D的遊戲專案中,使物體移動的方式大致上有這幾種:
(1)直接更動gameObject.transform.position
(2)對物件加入RigidBody2D元件,使用AddForce
(3)對物件加入RigidBody2D元件,更改其Velocity
由於第1種方法只是單純更改位置,並沒有「施力」的概念,在撞到物體時也無法把「力」傳遞給對方,因此這裡就暫不討論。
簡單來說,AddForce和Velocity的差別就是:
AddForce的效果會受到施力時間、物體質量等特性影響
Velocity則是直接指定物體的速度
程式碼範例:
第20行:雖然Update()可以大致理解為「在專案執行時,不斷被呼叫的函式」,但是其實每一次呼叫的時間間隔是不一樣的(0.0185s, 0.0191s, 0.023s…..),因此在撰寫需要嚴謹計算時間的程式功能時,可以改使用FixedUpdate(),FixedUpdate()的預設時間間隔是0.02s ,會準時地每0.02s呼叫一次此Function。(時間間隔可以在Edit->Project Settings->Time->Fixed Timestep更改)
第27行:大家國高中應該都有學過牛頓第二定律F=ma (力=質量*加速度)吧XD,考量到在FixedUpdate裡每0.02秒被呼叫一次的規律,在FixedUpdate裡的施力公式可歸納為
v=f*t/m
v:速度、f:力、t:FixedTime的TimeStep、m:物體質量
因此,如果想要達到和第32行一樣velocity=(0f,15f)的效果,所需的力為
f=v/t*m=15/Time.fixedDeltaTime
(物體的mass預設為1,而Time.fixedDeltaTime會自動去抓取系統設定的Timestep值)
第32行:這裡就比較單純,直接賦予物體new Vector2(0f, 15f)的速度。
Velocity也可以用來限制物體的最小、最大速度,例如:
void FixedUpdate(){
if(rigid.velocity.y < 150f){
/*對物體持續施力*/
}
else{
rigid.velocity = new Vector2(0f, 150f);
}
}
在此剛體的y方向速度達到150f前不斷對它施力,在到達150f後把速度鎖死,不再增加。
p.s 當想要修改像rigid.velocity、gameObject.transform.position這種東西時,MonoBehaviour不接受直接更改單一軸向的做法(ex. rigid.velocity.y = 87f;),因此必須填入一個完整的Vector2或Vector3等等。
大量使用物理碰撞…可以的話還是盡量避免 不然吃的效能很可怕XD
LikeLike