Khi nào tôi nên sử dụng vận tốc so với addForce khi giao dịch với các đối tượng người chơi?


18

Tôi bối rối về hai phương pháp này trong khung Unity. Cả hai đều làm cho đối tượng người chơi di chuyển, dừng lại, thay đổi hướng, v.v ... Khi nào nên sử dụng cái này hơn cái kia và khi nào thì phù hợp?



@ Byte56 cả hai câu hỏi đều hỏi về những điều khác nhau
Robert

1
Khác nhau, nhưng liên quan. Đó là lý do tại sao chúng chỉ được liên kết và không trùng lặp. Hiển thị nó hiển thị trong cột được liên kết ở bên phải.
MichaelHouse

Câu trả lời:


13

Bạn sẽ sử dụng velocityđể di chuyển đối tượng với tốc độ không đổi (ví dụ như một viên đạn) và AddForce()để thêm chuyển động (ví dụ như một bộ đẩy tàu vũ trụ). Cũng lưu ý rằng có hai "loại" chuyển động; lực và xung lực. Đối với một bộ đẩy tàu vũ trụ, bạn sử dụng xung.


4
Bạn có thể mô tả lý do tại sao bạn thích các xung cho một bộ đẩy tàu vũ trụ? Đây thực sự có thể là một sự phù hợp không lý tưởng nếu bạn đang áp dụng gia tốc dần dần theo thời gian, thay vì thay đổi động lượng tức thời do những thứ như tác động của vũ khí. Áp dụng theo cửa sổ thời gian, thông thường bạn sẽ muốn có lực (hoặc gia tốc nếu bạn không muốn khối lượng là một yếu tố) trong khi ngay lập tức bạn sẽ sử dụng xung (hoặc, tương ứng, velocityChange)
DMGregory

@DMGregory Vâng, nó phụ thuộc vào loại lực bạn muốn thêm. Trong ví dụ của tôi về máy đẩy tàu vũ trụ, đó là một sự bùng nổ năng lượng nhất thời thì xung lực là sự lựa chọn chính xác.
trojanfoe

2
Vẫn chưa rõ liệu bạn có nghĩa là bắn một tia phản lực ngắn hay đốt cháy liên tục một động cơ chính ("thruster" được sử dụng một chút chung chung trong khoa học viễn tưởng), vì vậy tôi nghĩ tôi nên làm rõ kẻo thử sử dụng các xung cho một tên lửa đẩy. ;)
DMGregory

@DMGregory Thật vậy; Thuật ngữ công nghệ vũ trụ của tôi chủ yếu dựa trên phim :)
trojanfoe

@trojanfoe Đi chơi KSP. Giống như, ngay bây giờ.
user253751

21

Mặc dù đã có một câu trả lời được chấp nhận, tôi nghĩ có một số chi tiết bổ sung đáng để đề cập.

Sử dụng vận tốc

Khi bạn đặt vận tốc, bạn sẽ ghi đè hoàn toàn mọi thứ khác có thể ảnh hưởng đến chuyển động của vật thể đó. Trong một số tình huống, điều này là mong muốn, chẳng hạn như thiết lập vận tốc ban đầu của viên đạn một lần tại thời điểm nó bắn, như trong ví dụ của trojanfoe. Hãy cảnh giác, bởi vì khi sử dụng trong các tình huống sai, nó có thể gây ra vấn đề:

  • Nếu nhiều nguồn / tập lệnh cố gắng sửa đổi cùng một vận tốc của Rigidbody bằng cách đặt trực tiếp (tức là body.velocity = foo), thì cái nào chạy được lần cuối sẽ thắng và những cái khác không có hiệu lực. Điều này có thể dẫn đến thứ tự các lỗi cập nhật, đặc biệt là làm cho các thực thể bay lơ lửng hoặc rơi chậm (vì gia tốc đi xuống do trọng lực bị ghi đè trước khi nó có thể tích lũy)

  • Nếu bạn đang đặt vận tốc mọi khung hình, va chạm với các vật thể khác có thể hơi lạ. Dường như vật thể của bạn đang được đẩy bởi một động cơ có mô-men xoắn vô hạn - cho dù nó có mất bao nhiêu vận tốc khi va chạm, nó sẽ quay trở lại tốc độ tối đa ở bước vật lý tiếp theo và vận tốc của nó không bị lệch khỏi tác động . Điều này có thể dẫn đến việc phóng các vật thể bạn va chạm hoặc các vật thể nhỏ có thể đẩy những vật thể lớn dễ dàng hơn nhiều so với những gì chúng có thể hoặc các vật thể trượt chậm dọc theo các rào chắn tĩnh thay vì làm chệch hướng / dọc theo chúng.

Cả hai hiệu ứng này có thể được mong muốn đôi khi. Ví dụ, khi tôi tạo trò chơi Kinect và tôi muốn các chi của avatar ảo của người chơi có thể tương tác với cảnh vật lý, tôi thường di chuyển các cơ thể đó bằng cách sử dụng cài đặt vận tốc trực tiếp. Vì bàn tay thực sự của người chơi đang ở một nơi đã biết và không bị chậm khi va chạm với vật thể ảo đó, nên bàn tay ảo của họ cần phải làm như vậy để giữ thẳng hàng, vì vậy trong trường hợp này chúng tôi thực sự muốn ghi đè tất cả các hiệu ứng vật lý khác vào đến đó

AddForce và bạn bè

Ngược lại, AddForce và các chức năng trợ giúp tương tự được tạo ra để hợp tác với mọi thứ khác đang diễn ra trong thế giới vật lý. Nếu nhiều nguồn / tập lệnh AddForce cho Rigidbody, tất cả các hiệu ứng đó được cộng lại với nhau để tạo ra sự thay đổi thuần trong chuyển động của đối tượng (tùy theo cách tính của nó, cũng có thể không phụ thuộc vào thứ tự). Điều này giúp tránh một tập lệnh hoàn toàn dậm chân một số hiệu ứng vật lý khác.

AddForce có bốn hương vị bằng cách chỉ định tham số ForceMode tùy chọn , hữu ích cho những thứ khác nhau:

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

Nếu bạn đang cố gắng tạo mô hình đẩy liên tục theo thời gian (ví dụ: thứ gì đó bạn đang áp dụng mỗi FixedUpdate), như lái xe hơi hoặc đốt tên lửa hoặc kéo trọng lực, bạn muốn Lực hoặc Tăng tốc. (Tùy thuộc vào việc bạn muốn các vật nặng tăng tốc chậm hơn)

Nếu bạn đang mô hình hóa một sự thay đổi đột ngột, đột ngột trong chuyển động, như bắn một viên đạn, hồi phục sau vụ nổ hoặc bật ra khỏi một rào chắn, thì nhiều khả năng bạn muốn Impulse hoặc VelocityChange.

Sử dụng AddForce giúp bạn đạt được nhiều hiện thực vật lý hơn, nhưng nó cũng có thể yêu cầu bạn dành nhiều thời gian hơn để suy nghĩ thông qua vật lý của hành vi của bạn. Chẳng hạn, nếu bạn muốn cơ thể của mình có gia tốc hữu hạn lên tới tốc độ mục tiêu, để nó phản ứng thực tế hơn với các va chạm hơn là đặt vận tốc mỗi khung hình, có thể bạn sẽ muốn một phép tính tương tự như chức năng trợ giúp này:

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);
}

Lý do tôi gọi tất cả các "hàm trợ giúp" này là về mặt kỹ thuật bạn có thể đạt được tất cả các kết thúc tương tự với:

 body.velocity += suitablyCalculatedDeltaV;

( Tôi nghĩ . Có thể bộ giải vật lý dựa trên PhysX / Box2D của Unity có thể thay đổi bộ đệm thông qua AddForce, nhưng tôi chưa thấy hậu quả rõ ràng của việc này)

Vì vậy, vào cuối ngày, những chức năng này thực sự mang lại cho chúng ta là sự rõ ràng về ý định . Khi tôi muốn áp dụng một lực dần dần, tôi không cần phải nhớ nhân deltaV của mình với Time.deltaTime và chia theo khối lượng, tôi chỉ nói rằng tôi muốn ForceMode.Force và nó được xử lý theo cách chính xác và nhất quán. Và khi tôi hoặc người khác lặp lại mã của mình sau đó, tôi sẽ ngay lập tức hiểu ý tôi, mà không cần phải giải mã thời gian và tính toán hàng loạt để tìm ra mã.


6

Ngoài câu trả lời của trojanfoe , Angry Birds vs Car Racing. Hai ví dụ chính và khác nhau của các phương thức này ( AddForcevelocitytương ứng). Ví dụ, trong Angry Birds, việc sử dụng vận tốc khó khăn hơn một chút vì bạn sẽ phải thiết lập quỹ đạo Projectile theo cách của mình, như,

Khi tôi sử dụng AddForce trong Angry Birds, tôi sẽ sử dụng,

_birdRigidbody.AddForce(new Vector2(5,5));

Trong khi tôi sử dụng vận tốc thì tôi sẽ xử lý quỹ đạo bằng cách sử dụng

x = v*t*Cos(theta) y = v*t*Sin(theta) - 0.5 * g * t *t

Hoặc thứ gì đó giống thế này.

Trong khi trong trò chơi Car Racing, bạn sẽ phải kiểm soát tốc độ mọi lúc, không như Angry Birds tức là Shoot và tất cả. Vì vậy, trong kịch bản xử lý velocitylà hữu ích hơn AddForce.

Mong là bạn hiểu. Ít nhất một chút.


1
Ví dụ AngryBirds của bạn có thể nên sử dụng thay đổi động lượng tức thời (ví dụ: Impulse hoặc VelocityChange) khi súng cao su được phát hành, thay vì ForceMode.Force mặc định mô phỏng hiệu ứng của nó qua cửa sổ thời gian. Bạn có thể điều chỉnh các số để có hành vi tương đương theo một trong hai cách tiếp cận, nhưng nếu bạn thay đổi bước thời gian cố định, giải pháp lực sẽ có đầu ra khác (vì nó tích hợp lực trong khoảng thời gian dài hơn hoặc ngắn hơn) trong khi xung vẫn nhất quán như mong muốn, bởi vì nó chỉ đại diện cho thời điểm phát hành.
DMGregory

0

Rigidbody Velocity và Rigidbody Addforce là hai chức năng khó hiểu trong Unity 3D và thường người mới bắt đầu không hiểu được sự khác biệt của chúng. Trong bài viết này, chúng ta sẽ thảo luận về sự khác biệt giữa RigidBody.velocity và RigidBody.addforce.

Trong cả hai trường hợp, cho dù đó là hàm Addforce hay hàm vận tốc, chúng ta sẽ sử dụng thuật ngữ lực để giải thích chúng.

Khi chúng ta đang sử dụng Rigidbody.velocity, thì trong trường hợp đó, chúng ta sẽ thêm lực vào đối tượng của mình nhưng lực này sẽ chỉ di chuyển đối tượng trừ khi và cho đến khi chúng ta tiếp tục tác dụng lực.

Ví dụ

body.velocity = new Vector3 (0,0,5);

Giả sử bạn đã thêm 5f ở vị trí z và lực đó sẽ được thêm khi bạn nhấn phím W. Vì vậy, khi bạn nhấn phím W, đối tượng sẽ ngay lập tức khởi động ở tốc độ 5. Cũng giống như vậy nếu bạn thêm lực bằng chức năng này trên xe, chiếc xe đó sẽ khởi động ở tốc độ 5.

body.velocity = new Vector3 (0,0,200);

Và nếu bạn nói thay đổi giá trị thành 200 và sau khi lưu, nhấn W. Xe sẽ bắt đầu chạy ở tốc độ 200 từ khi bắt đầu, điều này là không thể trong thế giới thực.

Bây giờ Nếu bạn nói về Rigidbody.addforce

Bằng cách tiếp tục ví dụ xe của chúng tôi. nếu bạn thêm lực 200 vào xe

body.addforce (0,0,200);

Xe sẽ không bắt đầu di chuyển ở tốc độ 200 nếu chúng ta nhấn W nhưng nó bắt đầu từ chậm và sau đó tăng tốc độ và dừng theo giá trị của Kéo.

Rigidbody.addforce bắt đầu chậm và sau đó tăng tốc, giống như bạn đang kéo một cái bàn nặng, đầu tiên bạn sẽ bắt đầu đẩy cái bàn đó, cái bàn sẽ di chuyển một chút khỏi vị trí của nó nhưng nếu bạn tiếp tục đẩy cái bàn đó thì nó sẽ bắt đầu di chuyển & nếu bạn rời khỏi bảng đó, nó sẽ bao phủ một số khoảng cách tùy thuộc vào bề mặt và đó cũng là điều cứng nhắc.

Bạn có thể sử dụng Rigidbody.velocity nơi bạn chỉ muốn di chuyển đối tượng của mình để phản ứng ngay lập tức như nhảy người chơi và kết quả của lực đó sẽ biến mất ngay sau khi nhảy và bạn có thể sử dụng Rigidbody.addforce khi bạn cần khởi động chậm và sau đó chuyển động liên tục như một tên lửa. Nếu bạn sử dụng Rigidbody.addforce khi nhảy, Người chơi / Đối tượng sẽ ở lại trong không gian một lúc và sau đó sẽ quay trở lại mặt đất.

(nguồn)


Ít nhất bạn nên thử và điều chỉnh bài đăng của mình theo định dạng của câu trả lời Stack Exchange :)
Vaillancourt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.