ฉันสับสนเกี่ยวกับสองวิธีนี้ใน Unity framework ทั้งทำให้ผู้เล่นย้ายวัตถุหยุดเปลี่ยนทิศทางและอื่น ๆ เมื่อใดควรใช้อีกอันหนึ่งและอีกอันหนึ่งเหมาะสมหรือไม่
ฉันสับสนเกี่ยวกับสองวิธีนี้ใน Unity framework ทั้งทำให้ผู้เล่นย้ายวัตถุหยุดเปลี่ยนทิศทางและอื่น ๆ เมื่อใดควรใช้อีกอันหนึ่งและอีกอันหนึ่งเหมาะสมหรือไม่
คำตอบ:
คุณจะใช้velocity
เพื่อย้ายวัตถุในอัตราคงที่ (เช่นสัญลักษณ์แสดงหัวข้อย่อย) และAddForce()
เพื่อเพิ่มการเคลื่อนไหว (ตัวอย่างเช่น thruster ยานอวกาศ) โปรดทราบว่ามี "การเคลื่อนไหว" สองประเภท แรงและแรงกระตุ้น สำหรับยานอวกาศทรัสเตอร์คุณต้องใช้แรงกระตุ้น
แม้ว่าจะมีคำตอบที่ยอมรับแล้ว แต่ฉันคิดว่ามีรายละเอียดเพิ่มเติมที่คุ้มค่า
ใช้ Velocity
เมื่อคุณตั้งค่าความเร็วคุณจะเอาชนะทุกสิ่งที่อาจส่งผลต่อการเคลื่อนไหวของวัตถุนั้นอย่างแน่นอน ในบางสถานการณ์สิ่งนี้เป็นที่น่าพอใจเช่นการตั้งค่าความเร็วเริ่มต้นของกระสุนหนึ่งครั้งในขณะที่มันถูกไล่ออกเช่นเดียวกับในตัวอย่างของโทรจัน เพียงระวังเพราะเมื่อใช้ในสถานการณ์ที่ไม่ถูกต้องอาจทำให้เกิดปัญหา:
หากหลายแหล่ง / สคริปต์พยายามที่จะปรับเปลี่ยนความเร็วของ Rigidbody เดียวกันโดยการตั้งค่าโดยตรง (เช่น. body.velocity = foo
) ดังนั้นสิ่งใดก็ตามที่ชนะครั้งสุดท้ายและอีกอันหนึ่งไม่มีผลกระทบใด ๆ สิ่งนี้สามารถนำไปสู่ลำดับของการอัพเดทบั๊กโดยเฉพาะอย่างยิ่งทำให้เอนทิตี้ของเลื่อนหรือตกลงช้า (เนื่องจากการเร่งลงเนื่องจากแรงโน้มถ่วงถูกแทนที่ก่อนที่มันจะสะสม)
หากคุณตั้งค่าความเร็วทุกเฟรมการชนกับวัตถุอื่นอาจแปลกไปบ้าง ราวกับว่าวัตถุของคุณถูกขับเคลื่อนด้วยเครื่องยนต์ที่มีแรงบิดไม่ จำกัด ไม่ว่าความเร็วจะลดลงแค่ไหนมันก็กลับไปที่ความเร็วสูงสุดในขั้นตอนฟิสิกส์ถัดไปและความเร็วจะไม่เบี่ยงเบนไปจากแรงกระแทก . สิ่งนี้สามารถนำไปสู่การเปิดตัววัตถุที่คุณชนหรือวัตถุขนาดเล็กที่สามารถผลักวัตถุขนาดใหญ่ได้ง่ายกว่าที่ควรจะเป็นหรือวัตถุที่เลื่อนอย่างช้าๆไปตามสิ่งกีดขวางแบบคงที่แทนที่จะเบี่ยงเบนออกไป
บางครั้งอาจต้องการเอฟเฟกต์เหล่านี้ ตัวอย่างเช่นเมื่อฉันสร้างเกม Kinect และฉันต้องการแขนขาเสมือนจริงของผู้เล่นเพื่อให้สามารถโต้ตอบกับฉากฟิสิกส์ฉันมักจะย้ายร่างกายเหล่านั้นโดยใช้การตั้งค่าความเร็วโดยตรง เนื่องจากมือที่แท้จริงของผู้เล่นอยู่ในสถานที่ที่รู้จักและไม่ได้ช้าลงจากการชนกับวัตถุเสมือนนั้นมือเสมือนจริงของพวกเขาต้องทำแบบเดียวกันเพื่อให้อยู่ในแนวเดียวกันดังนั้นในกรณีนี้เราต้องการแทนที่ลักษณะพิเศษทางฟิสิกส์อื่น ๆ ทั้งหมด ไปถึงที่นั่น
เพิ่มและบังคับเพื่อน
AddForceและฟังก์ชั่นผู้ช่วยที่คล้ายกันได้ถูกสร้างขึ้นเพื่อให้ความร่วมมือกับทุกสิ่งที่เกิดขึ้นในโลกฟิสิกส์ หากมีหลายแหล่งที่มา / สคริปต์ AddForce ไปยัง Rigidbody เอฟเฟกต์ทั้งหมดเหล่านี้จะถูกรวมเข้าด้วยกันเพื่อสร้างการเปลี่ยนแปลงสุทธิในการเคลื่อนไหวของวัตถุ (ซึ่งขึ้นอยู่กับวิธีการคำนวณ สิ่งนี้จะช่วยหลีกเลี่ยงสคริปต์ตัวเดียวที่ทำให้เกิดเอฟเฟกต์ฟิสิกส์อื่น ๆ
AddForce มาในสี่รสชาติโดยการระบุพารามิเตอร์ ForceModeซึ่งเป็นประโยชน์สำหรับสิ่งต่าง ๆ :
ForceMode | Use
-----------------------------------------------------------------------
Force (default) | Accelerate an object over 1 time step, based on its mass.
| Units: Newtons = kg * m/s^2
|
Acceleration | Accelerate an object over 1 time step, ignoring its mass. (like gravity)
| Units: m/s^2
|
Impulse | Instantaneously propel an object, based on its mass
| Units: N * s = kg * m/s
|
VelocityChange | Instantaneously propel an object, ignoring its mass
| (like body.velocity = foo, except multiple scripts can stack)
| Units: m/s
หากคุณกำลังพยายามที่จะสร้างแบบจำลองการผลักดันอย่างต่อเนื่องในช่วงเวลา (เช่นสิ่งที่คุณใช้ทุกคงที่ UpdateUpdate) เช่นการขับรถหรือการเผาไหม้จรวดหรือแรงโน้มถ่วงดึงดีคุณต้องการแรงหรือการเร่งความเร็ว (ขึ้นอยู่กับว่าคุณต้องการให้วัตถุหนักเร่งความเร็วช้าลงหรือไม่)
หากคุณกำลังสร้างแบบจำลองการเคลื่อนไหวที่ฉับพลันและเฉียบแหลมอย่างเช่นการยิงกระสุนปืนถอยกลับจากการระเบิดหรือกระเด้งออกมาจากสิ่งกีดขวางคุณก็จะต้องการ Impulse หรือ VelocityChange มากขึ้น
การใช้ AddForce ช่วยให้คุณได้รับความสมจริงทางกายภาพมากขึ้น แต่ก็อาจต้องการให้คุณใช้เวลาในการคิดผ่านฟิสิกส์ของพฤติกรรมของคุณมากขึ้น ตัวอย่างเช่นหากคุณต้องการให้ร่างกายของคุณมีการเร่งความเร็วสูงสุดถึงความเร็วเป้าหมายเพื่อให้ตอบสนองต่อการชนได้สมจริงกว่าการตั้งค่าความเร็วทุกเฟรมคุณอาจต้องการการคำนวณที่คล้ายกับฟังก์ชันตัวช่วยนี้:
public static void AccelerateTo(this Rigidbody body, Vector3 targetVelocity, float maxAccel)
{
Vector3 deltaV = targetVelocity - body.velocity;
Vector3 accel = deltaV/Time.deltaTime;
if(accel.sqrMagnitude > maxAccel * maxAccel)
accel = accel.normalized * maxAccel;
body.AddForce(accel, ForceMode.Acceleration);
}
เหตุผลที่ฉันเรียกสิ่งเหล่านี้ว่า "ฟังก์ชั่นผู้ช่วย" คือในทางเทคนิคคุณสามารถบรรลุจุดสิ้นสุดเดียวกันทั้งหมดด้วย:
body.velocity += suitablyCalculatedDeltaV;
( ฉันคิดว่ามันเป็นไปได้ที่นักฟิสิกส์ฟิสิกส์ที่ใช้ PhysX / Box2D จะเปลี่ยนบัฟเฟอร์ผ่าน AddForce แยกจากกัน แต่ฉันไม่เห็นผลที่ชัดเจนจากสิ่งนี้)
ดังนั้นในตอนท้ายของวันที่สิ่งที่ฟังก์ชั่นเหล่านี้จะได้รับจริงๆเราก็คือความชัดเจนของความตั้งใจ เมื่อฉันต้องการใช้แรงแบบค่อยเป็นค่อยไปฉันไม่จำเป็นต้องจำเพิ่ม deltaV ของฉันด้วย Time.deltaTime และหารด้วยมวลฉันแค่บอกว่าฉันต้องการ ForceMode.Force และจัดการอย่างถูกต้องและสอดคล้องกัน และเมื่อฉันหรือคนอื่นมาทำซ้ำในรหัสของฉันในภายหลังมันชัดเจนในสิ่งที่ฉันหมายถึงโดยไม่จำเป็นต้องถอดรหัสเวลาและการคำนวณจำนวนมากเพื่อคิดออก
นอกจากคำตอบของ trojanfoeแล้ว Angry Birds vs Car Racing ตัวอย่างที่สำคัญและแตกต่างกันสองวิธี ( AddForce
และvelocity
ตามลำดับ) ตัวอย่างเช่นใน Angry Birds การใช้ความเร็วนั้นยากขึ้นอีกเล็กน้อยเนื่องจากคุณต้องตั้งวิถีกระสุนด้วยตนเองเช่น
เมื่อฉันใช้ AddForce ใน Angry Birds ฉันจะใช้
_birdRigidbody.AddForce(new Vector2(5,5));
ในขณะที่เมื่อฉันใช้ความเร็วฉันจะจัดการวิถีการใช้
x = v*t*Cos(theta)
y = v*t*Sin(theta) - 0.5 * g * t *t
หรืออะไรทำนองนี้
ในขณะที่อยู่ในเกม Car Racing คุณจะต้องควบคุมความเร็วตลอดเวลาไม่เหมือน Angry Birds เช่น Shoot และ all ดังนั้นในที่จับสถานการณ์จะเป็นประโยชน์มากกว่าvelocity
AddForce
หวังว่าคุณจะเข้าใจ. อย่างน้อยก็น้อย
Rigidbody Velocity และ Rigidbody Addforce เป็นฟังก์ชั่นสองอย่างที่สับสนใน Unity 3D และผู้เริ่มต้นมักจะไม่เข้าใจถึงความแตกต่าง ในบทความนี้เราจะพูดถึงความแตกต่างระหว่าง RigidBody.velocity และ RigidBody.addforce
ในทั้งสองกรณีไม่ว่าจะเป็นฟังก์ชันเสริมหรือความเร็วเราจะใช้คำว่าแรงเพื่ออธิบาย
เมื่อเราใช้ Rigidbody.velocity ดังนั้นในกรณีนี้เรากำลังเพิ่มแรงให้กับวัตถุของเรา แต่แรงนี้จะเคลื่อนย้ายวัตถุเท่านั้นเว้นแต่และจนกว่าเราจะใช้กำลังต่อไป
ตัวอย่างเช่น
body.velocity = Vector3 ใหม่ (0,0,5);
สมมติว่าคุณเพิ่มตำแหน่ง 5f ในตำแหน่ง z และแรงนั้นจะถูกเพิ่มเมื่อคุณกดปุ่ม W ดังนั้นเมื่อคุณจะกดปุ่ม W วัตถุจะเริ่มต้นด้วยความเร็ว 5 ทันทีมันก็เหมือนกันถ้าคุณเพิ่มแรงโดยใช้ฟังก์ชั่นนี้กับรถยนต์รถคันนั้นจะเริ่มที่ความเร็ว 5
body.velocity = Vector3 ใหม่ (0,0,200);
และถ้าคุณบอกว่าเปลี่ยนค่าเป็น 200 แล้วหลังจากบันทึกกด W. Car จะเริ่มทำงานด้วยความเร็ว 200 จากการเริ่มต้นซึ่งเป็นไปไม่ได้ในโลกแห่งความจริง
ตอนนี้ถ้าคุณพูดถึง Rigidbody.addforce
โดยดำเนินการต่อตัวอย่างรถยนต์ของเรา ถ้าคุณเพิ่มแรง 200 ลงในรถ
body.addforce (0,0,200);
รถจะไม่เริ่มเคลื่อนที่ด้วยความเร็ว 200 ถ้าเรากด W แต่เริ่มจากช้าแล้วเพิ่มความเร็วและหยุดตามค่าของ Drag
Rigidbody.addforce เริ่มช้าแล้วเร่งความเร็วเหมือนกับที่คุณลากโต๊ะหนักก่อนอื่นคุณจะเริ่มดันโต๊ะนั้นโต๊ะจะขยับจากตำแหน่งเดิมเล็กน้อย แต่ถ้าคุณดันโต๊ะนั้นมันจะเริ่มเคลื่อนที่ & ถ้าคุณออกจากตารางนั้นมันจะครอบคลุมระยะทางบางอย่างขึ้นอยู่กับพื้นผิวและนั่นก็เป็นสิ่งเดียวกัน
คุณสามารถใช้ Rigidbody.velocity ที่คุณต้องการย้ายวัตถุของคุณเพื่อตอบสนองทันทีเช่นผู้เล่นกระโดดและผลของแรงนั้นจะหายไปหลังจากการกระโดดและคุณสามารถใช้ Rigidbody.addforce ที่คุณต้องการเริ่มต้นช้าและจากนั้นการเคลื่อนไหวอย่างต่อเนื่องเช่น จรวด หากคุณใช้ Rigidbody.addforce ในการกระโดด Player / Object จะยังคงอยู่ในอวกาศสักครู่แล้วจะกลับมาสู่พื้นดิน