Xử lý va chạm với Vật lý tiêu chuẩn (2D)
Môi trường xác minh
- Windows
-
- cửa sổ 11
- Biên tập viên Unity
-
- 2021.3.3F1
- Gói hệ thống đầu vào
-
- 1.3.0
Điều kiện tiên quyết cho mẹo này
Các cài đặt sau đây đã được thực hiện trước làm tiền đề cho mô tả về mẹo này.
Lúc đầu
Mẹo này đặt hai đối tượng để bạn có thể thực hiện hành vi thao tác với một đối tượng và sử dụng vật lý tiêu chuẩn của Unity để đẩy đối tượng kia khi nó tiếp xúc với đối tượng kia.
Nhân tiện, hầu hết các cài đặt đều giống như quy trình được mô tả trong bài viết trước "Xác định xem các vật thể có va chạm với nhau hay không (2D)".
Chuẩn bị
Thủ tục ở đây gần giống như các mẹo trước , vì vậy hãy trôi chảy nó.
Sau khi tạo dự án, chuẩn bị hai hình ảnh sprite sẽ là đối tượng và thêm chúng. Tên lần lượt là "UnityTips" và "UnityTips_2".
Thêm hai tệp hình ảnh bằng cách thả chúng vào chế độ xem.
Thêm tập lệnh để di chuyển đối tượng bên trái bằng bàn phím. Tên Player
tập lệnh là .
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
// 一定時間ごとに呼ばれます
void FixedUpdate()
{
// キーボードの情報を取得
var keyboard = Keyboard.current;
// スプライトの移動処理
if (keyboard.leftArrowKey.isPressed)
{
transform.Translate(-0.1f, 0, 0, Space.World);
}
if (keyboard.rightArrowKey.isPressed)
{
transform.Translate(0.1f, 0, 0, Space.World);
}
if (keyboard.upArrowKey.isPressed)
{
transform.Translate(0, 0.1f, 0, Space.World);
}
if (keyboard.downArrowKey.isPressed)
{
transform.Translate(0, -0.1f, 0, Space.World);
}
}
}
Đính kèm vào đối tượng mà bạn muốn chạy tập lệnh.
Chạy trò chơi và kiểm tra xem nó có hoạt động với các phím con trỏ trên bàn phím của bạn không.
Cuối cùng, đặt một đối tượng văn bản để hiển thị trạng thái phát hiện va chạm.
Tên TextState
đối tượng là .
Cài đặt xử lý va chạm
Từ đây, bạn có thể định cấu hình các cài đặt liên quan đến va chạm.
Đầu tiên, chọn đối tượng bạn muốn di chuyển, "UnityTips" và nhấp vào "Thêm thành phần" từ trình kiểm tra.
Chọn từ Physics 2D
danh sách. Physics
là một đối tượng 3D, vì vậy đừng nhầm lẫn.
Physics 2D
Box Collider 2D
Chọn từ . Vì sprite này là hình chữ nhật, Box được chọn, nhưng nếu nó có hình tròn, ví dụ, hãy chọn các hình dạng khác như Hình tròn.
Lần trước, tôi chỉ muốn lấy thông tin về việc tôi có đánh nó hay không, vì vậy tôi đã kiểm tra "Làm cho nó kích hoạt", nhưng lần này tôi sẽ không. Điều này cho phép xử lý va chạm trong vật lý.
Rigidbody 2D
Sau đó thêm các thành phần của . Bạn có thể thêm nó từ "Vật lý 2D -> Rigidbody 2D".
Rigidbody
cung cấp thông tinCollider
vật lý cho đối tượng và cũng có thể xác định va chạm với các vật thể có .
Đặt Thang trọng lực thành 0 để tránh rơi tự do bên dưới.
Tương tự, thêm một thành phần vào đối tượng khác "UnityTips_2" để đánh dấu Box Collider 2D
các lần truy cập.
Ngoài ra, lần này cần phải di chuyển với lực của đối thủ,Rigidbody 2D
vì vậy hãy thêm . Thang đo trọng lực phải là 0.
Đó là tất cả những gì cần có. Không có chương trình được yêu cầu tại thời điểm này. Chạy trò chơi và cố gắng chạm vào một đối tượng khác.
Tôi nghĩ bạn có thể khẳng định rằng nếu bạn đẩy đối thủ vào như thế này, đối thủ sẽ cư xử như thể anh ta bị đẩy. Nó rất dễ dàng để sử dụng vật lý của hàm tiêu chuẩn vì không cần chương trình.
Ngăn không cho các đối tượng xoay
Bạn có thể nhìn thấy khi bạn chạm vào nó, nhưng nếu điểm nhấn dịch chuyển dù chỉ một chút, mỗi đối tượng sẽ xoay. Là một trò chơi, nó thường trở nên không tự nhiên, vì vậy bạn cần đặt nó để nó không xoay.
Rigidbody 2D
Thành phần có một mục gọi là "Vòng quay cố định" trong "Ràng buộc", vì vậy hãy kiểm tra Z.
Bây giờ bạn có thể làm việc để nó không xoay. Hãy thử đặt nó thành hai đối tượng và chạy trò chơi để kiểm tra nó.
Tôi nghĩ bạn có thể chắc chắn rằng nó không xoay cho dù bạn đẩy nó từ góc độ nào.
Làm điều gì đó khi các vật thể va vào nhau
Ví dụ, bạn có thể muốn thực hiện một viên đạn bắn trúng kẻ thù trong khi đẩy đối thủ trong khi làm giảm sức khỏe của kẻ thù. Điều này cũng giống như các mẹo trước , vì sự kiện sẽ xảy ra, vì vậy bạn có thể đối phó với nó.
Player
Mở script và thêm từng trường, phương thức sử dụng như sau:
using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class Player : MonoBehaviour
{
<summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;
// 中略
<summary>衝突した瞬間に呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionEnter2D(Collision2D partner)
{
TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
}
Vì chúng tôi muốn hiển thị thông tin về việc nó có bị bắn trúng hay không, chúng tôi sẽ làm cho nó có thể hiển thị nó trong một đối tượng văn bản như sau.
<summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;
Quá trình phát hiện va chạm được mô tả như sau.
<summary>衝突した瞬間に呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionEnter2D(Collision2D partner)
{
TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
Tương tự như các mẹo trước------, nhưng tên phương thức bây giờ là "OnCollision------2D" thay vì "OnTrigger2D".
Rigidbody 2D
Mỗi sự kiện trên xảy ra khi một vật thể đã va chạm với một vật thể Collider 2D
khác có .
Điều này sẽ cho phép bạn xác định và xử lý xem nó có đúng hay không.
Có ba sự kiện, mỗi sự kiện được gọi vào thời điểm sau.
OnCollisionEnter2D | Khi các vật thể va vào nhau |
OnCollisionStay2D | Trong khi các vật thể đang va vào nhau |
OnCollisionExit2D | Khi các vật thể rời khỏi trạng thái va chạm |
Trong cả hai trường hợp, đối tượng đối thủ nhận đối tượng của đối thủ làm đối số, vì vậy bạn có thể lấy đối tượng của Collision2D
đối thủ bằng cách tra cứu Collider2D.gameObject
loại mục tiêu bị bắn trúng (kẻ thù, vật phẩm, Collider2D.collider.tag
v.v.).
Trong OnCollisionEnter2D
ba sự kiện trên, và OnCollisionExit2D
được gọi một lần cho mỗi vụ va chạm.
OnCollisionStay2D
được gọi là mọi khung hình trong vụ va chạm, nhưng sự kiện không còn được gọi sau một khoảng thời gian nhất định đã trôi qua kể từ khi cả hai vật thể dừng lại.
Điều này là do nó được coi là đã đi vào trạng thái ngủ và nó được coi là lãng phí xử lý để tính toán va chạm mọi khung hình với thứ gì đó không chuyển động.
Nếu bạn Rigidbody 2D
không muốn nó ngủ, hãy thay đổi chế độ ngủ của tham số thành "Không ngủ".
Sau khi thay đổi mã, hãy đặt văn bản để hiển thị thông tin.
Chạy trò chơi và di chuyển đối tượng bằng bàn phím để chạm vào một sprite khác. Bạn có thể thấy rằng ba hàm được gọi cho mỗi.
Nhân tiện, nếu bạn chạm vào một vật thể và sau đó ngừng di chuyển, phương thức sẽ được gọi trong OnCollisionStay2D
một thời gian ngắn.
Bạn sẽ có thể thấy rằng phương thức không còn được gọi sau OnCollisionStay2D
một khoảng thời gian nhất định.
Điều này cho biết rằng bạn đã nhập trạng thái ngủ, nhưng nếu bạn muốn thay đổi thời gian cho đến khi vào giấc ngủ này, bạn có thể thay đổi nó bằng cách chọn "Vật lý 2D" từ cài đặt dự án và chỉ định tham số "Thời gian ngủ" tính bằng giây.
Nó không thể được đặt thành 0, nhưng nếu nó OnCollisionStay2D
được đặt thành nhỏ vô hạn, bản thân phương thức sẽ không được gọi.