ความสามัคคี: วิธีการตรวจจับการชนที่เกิดขึ้นกับวัตถุลูกจากสคริปต์แม่?


12

ฉันเป็นศัตรูด้วยโครงสร้างนี้

  • ศัตรู
    • ร่างกาย
      • ศีรษะ
      • แขนซ้าย
      • แขนขวา

และอื่น ๆ

ฉันยังมี collider สำหรับแต่ละส่วนของร่างกาย ในวัตถุ "ศัตรู" ของฉันฉันได้แนบสคริปต์และในสคริปต์นั้นฉันต้องการที่จะสกัดกั้นการชนกันที่เป็นไปได้ (กระสุน) สำหรับร่างกายหัวแขนซ้าย ฯลฯ

มีวิธีทำเช่นนี้หรือไม่?

คำตอบ:


16

หากคุณใช้ Rigidbody กับตัวละครคุณสามารถเอามันออกจากกล่องได้ :)

ดังนั้นลำดับชั้นของคุณอาจมีลักษณะเช่นนี้:

  • ตัวละคร (มี Rigidbody และสคริปต์ควบคุม)
    • เด็ก (อาจมี colliders)
      • หลาน (อาจมี colliders)

ข้อความ OnCollisionEnter จะทำงานกับ GameObject ที่มี Rigidbody ถึงสคริปต์ควบคุมของผู้ปกครองโดยไม่จำเป็นต้องเขียนสคริปต์รีเลย์เพิ่มเติมเพื่อติดกับแต่ละ collider

หากคุณต้องการทราบว่าลูกของคุณคนไหนที่มีส่วนร่วมในการปะทะกันคุณสามารถทำได้ดังนี้:

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

วิธีหนึ่งในการแก้ไขปัญหานี้คือการมีสองสคริปต์: หนึ่งสำหรับวัตถุศัตรูและอีกหนึ่งสำหรับเด็ก (ที่คุณต้องกำหนดให้กับเด็ก ๆ ของศัตรู obj)

สคริปต์ผู้ปกครอง

using UnityEngine;

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

สคริปต์เด็ก

using UnityEngine;

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

วิธีนี้คุณควรได้รับการแจ้งเตือนทุกครั้งที่มีการชนเกิดขึ้นกับเด็ก


2
หากคุณใช้วิธีแก้ปัญหาเช่นนี้และการชนเหล่านี้เกิดขึ้นบ่อยครั้งฉันขอแนะนำให้เด็ก ๆ ทำแคช GameObject ของผู้ปกครอง มันเป็นนิสัยที่ดีทุกครั้งที่คุณจะเรียกใช้ GetComponent เดียวกันและช่วยให้คุณทำสิ่งที่ยุ่งยากกว่า "การค้นหาว่าผู้ปกครองคนใดที่ส่งลูกโซ่ไปยัง" ลอจิกจะต้องเกิดขึ้นเพียงครั้งเดียว ยังจำได้ว่า transform.parent จะได้รับผู้ปกครองทันที
Lunin

2

คุณสามารถส่งวัตถุยอดนิยมไปยังเด็ก ๆ และเรียกใช้ฟังก์ชันโดยตรง สิ่งนี้รับประกันได้ว่าคุณไม่จำเป็นต้องพึ่งพาการแพร่กระจายของผู้ปกครอง ดังนั้นคุณไม่ต้องทำอะไรที่โง่เขลาtransform.parent.parent

แต่คุณสามารถทำให้กระบวนการนี้กับGetComponentInParent สิ่งนี้จะดึงสคริปต์แรกที่พบ จากนั้นแคชในวัตถุที่มีการชนกันของคุณเรียกใช้ฟังก์ชันโดยตรงบนวัตถุที่ถูกแคช

อีกทางหนึ่งคุณสามารถใช้UnityEvents (ไม่ใช้ Messages) เพื่อผูกฟังก์ชันกับวัตถุลูก ด้วยเหตุการณ์ความสามัคคีคุณสามารถเพิ่มผู้ฟังใดก็ได้เพื่อให้คุณสามารถทำได้มากกว่าเพียงแค่แจ้งวัตถุระดับบนสุดของวัตถุลูกที่กำลังถูกโจมตี


1

อ้างโดยตรงจาก Unity Answers (เขียนโดยAshish Dwivedi ):

เพิ่มสคริปต์ให้กับลูกและภายในมีการอ้างอิงของสคริปต์ของวัตถุแม่ ตอนนี้เขียน 3 วิธีในสคริปต์หลักเช่น (OnCollisionEnter2DChild, OnCollisionStay2DChild, OnCollisionExit2DChild) และเรียกวิธีการตามลำดับจากวิธีการ (OnCollisionEnter2D, OnCollisionExit2D) ซึ่งอยู่ในวัตถุของลูก


1

คุณสามารถตรวจสอบการชนกันของข้อมูลและดูว่ามีการเข้าชมช่องใดและได้รับผลกระทบหากจำเป็น

หมายเหตุ: rigidbody ถูกวางไว้บนวัตถุเดียวกันที่มีสคริปต์ตรวจสอบการชนกัน

ตัวอย่างนี้กำลังตรวจสอบว่า Hitbox ใดที่ 'กระสุนปืน' เข้าเป้า

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    
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.