Unity: làm thế nào để phát hiện va chạm xảy ra trên đối tượng con, từ tập lệnh cha?


12

Tôi là kẻ thù, với cấu trúc này

  • Kẻ thù
    • Thân hình
      • Cái đầu
      • Cánh tay trái
      • Cánh tay phải

Và như thế.

Tôi cũng có một máy va chạm cho từng bộ phận của cơ thể. Trong đối tượng "Kẻ thù" của tôi, tôi đã đính kèm một tập lệnh và trong kịch bản đó, tôi muốn chặn các va chạm có thể xảy ra (một viên đạn) cho cơ thể, đầu, cánh tay, bên trái, v.v.

Có cách nào để làm việc này không?

Câu trả lời:


16

Nếu bạn đang sử dụng Rigidbody với nhân vật, bạn có thể lấy cái này ra khỏi hộp. :)

Vì vậy, hệ thống phân cấp của bạn có thể trông như thế này:

  • Nhân vật (có Rigidbody và kịch bản điều khiển)
    • con (có thể có máy va chạm)
      • cháu (có thể có máy va chạm)

Các thông báo OnCollision Entry sẽ kích hoạt trên GameObject chứa Rigidbody, tiếp cận tập lệnh kiểm soát cha mẹ của bạn mà không cần phải viết một tập lệnh chuyển tiếp bổ sung để dán trên mỗi máy va chạm.

Nếu bạn cần tìm ra máy va chạm con nào có liên quan đến vụ va chạm, bạn có thể làm như vậy:

void OnCollisionEnter(Collision collision) {
    Collider myCollider = collision.contacts[0].thisCollider;
    // Now do whatever you need with myCollider.
    // (If multiple colliders were involved in the collision, 
    // you can find them all by iterating through the contacts)
}

5

Một cách để giải quyết điều này là có hai kịch bản: một cho đối tượng Kẻ thù và một kịch bản khác cho trẻ em (mà bạn cần gán cho trẻ em của Kẻ thù obj)

Kịch bản phụ huynh

using UnityEngine;

 public class ParentScript : MonoBehaviour 
 {
     public void CollisionDetected(ChildScript childScript)
     {
         Debug.Log("child collided");
     } 
 }

Kịch bản con

using UnityEngine;

public class ChildScript : MonoBehaviour 
{
     void OnCollisionEnter(Collision collision)
     {
         transform.parent.GetComponent<ParentScript>().CollisionDetected(this);
     }
 }

Bằng cách này, bạn sẽ được thông báo mỗi khi xảy ra va chạm với trẻ


2
Nếu bạn sử dụng một giải pháp như thế này và những va chạm này xảy ra rất nhiều, tôi khuyên bạn nên để trẻ lưu trữ bộ đệm GameObject của cha mẹ chúng. Đó là một thói quen tốt bất cứ khi nào bạn sẽ gọi cùng một GetComponent rất nhiều và cho phép bạn thực hiện bất kỳ câu hỏi khó nào "tìm cha mẹ lên chuỗi để gửi" logic chỉ cần xảy ra một lần. Cũng nên nhớ rằng Transform.parent sẽ chỉ nhận được cha mẹ ngay lập tức .
Âm lịch

2

Bạn có thể chỉ cần truyền đối tượng trên cùng cho trẻ em và gọi một hàm trực tiếp trên nó. Điều này đảm bảo rằng bạn không phải dựa vào sự truyền bá của cha mẹ. Vì vậy, cuối cùng bạn không làm những điều ngớ ngẩn nhưtransform.parent.parent

Tuy nhiên, bạn có thể tự động hóa quá trình này với GetComponentInParent . Điều này lấy kịch bản đầu tiên nó tìm thấy. Sau đó lưu vào bộ đệm trong đối tượng va chạm của bạn, gọi trực tiếp các hàm trên đối tượng đã lưu.

Ngoài ra, bạn có thể sử dụng UnityEvents (không sử dụng Tin nhắn) để liên kết các chức năng với đối tượng con. Với các sự kiện thống nhất, bạn có thể thêm bất kỳ trình nghe tùy ý nào để bạn có thể làm nhiều hơn là chỉ thông báo cho đối tượng cấp cao nhất của đối tượng con bị tấn công.


1

Trích dẫn trực tiếp từ câu trả lời của Unity (được viết bởi Ashish Dwivingi ):

Thêm một tập lệnh cho con và bên trong nó có một tham chiếu tập lệnh của đối tượng cha. Bây giờ hãy viết 3 phương thức trong tập lệnh cha mẹ như (OnCollision Entry2DChild, OnCollisionStay2DChild, OnCollisionExit2DChild) và gọi phương thức tương ứng từ các phương thức (OnCollision Entry2D, OnCollisionStay2D, OnCollisionExit2D)


1

Bạn có thể thực hiện kiểm tra va chạm và xem hộp hit nào bị bắn trúng và cũng có thể nhận được điểm tác động nếu cần.

lưu ý: người cứng nhắc được đặt trên cùng một đối tượng có tập lệnh Kiểm tra va chạm.

Ví dụ này đang kiểm tra xem hitbox 'hitile' nào nhắm vào mục tiêu.

private void OnCollisionEnter(Collision collision)
{                 
    if (collision.contacts[0].otherCollider.transform.gameObject.name == "HeadShot")                
       //DO STUFF            

    if (collision.contacts[0].otherCollider.transform.gameObject.name == "BodyShot")
       //DO STUFF    
}
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.