ดูรายละเอียดการชนกับวัตถุบางอย่างในบริบทบางอย่าง


14

ฉันสร้างเกมแข่งรถด้วยรถยนต์ใน Unity รถมีพลังเพิ่ม / nitro ในขณะที่เพิ่มระดับฉันไม่ต้องการเบี่ยงเบนเมื่อปะทะกับซอมบี้ แต่ฉันอยากเบี่ยงเบนเมื่อชนกับกำแพง

ในทางกลับกันฉันไม่ต้องการเพิกเฉยต่อการปะทะกับซอมบี้เพราะฉันยังต้องการตีพวกมันด้วยการกระแทก

ฉันควรจัดการกับสิ่งนี้อย่างไร โดยพื้นฐานแล้วสิ่งที่ฉันต้องการคือรถจะไม่หมุนเมื่อชนกับวัตถุบางอย่าง

คำตอบ:


7

ลองพิจารณาเลเยอร์ของคุณตอนรันไทม์

การเปิด / ปิดการชนสำหรับวัตถุบางอย่างที่มีทั้งชั้น

Physics.IgnoreCollisionและPhysics.IgnoreLayerCollisionอนุญาตให้คุณปิดการชนระหว่างสอง colliders และระหว่างสอง layer ตามลำดับ

หากคุณต้องการแยก collider ที่เฉพาะเจาะจงออกจากการชนไม่มีวิธีการดังกล่าวในตัว หากคุณกำลังใช้อุปกรณ์ที่ไม่ใช่จลนศาสตร์กับ colliders ที่ไม่มีทริกเกอร์ก็จะมีการตอบสนองแม้ว่าคุณจะพยายามกรองการตอบสนองด้วยแท็ก

วิธีที่เราทำสิ่งนี้ให้สำเร็จในโครงการของเราคือการสร้างเลเยอร์ชื่อว่า "Void" โมฆะไม่ชนอะไรเลย

ตอนนี้คุณสามารถปิดใช้งานการชนของ collider ได้ชั่วคราวโดยการตั้งค่าเลเยอร์เป็น "Void" และเปิดใช้งานอีกครั้งโดยเรียกคืนเลเยอร์เก่า

นี่คือส่วนสำคัญ:

int oldLayer = -1;
int voidLayer;

void Start()
{
    voidLayer = LayerMask.NameToLayer("Void");
}

void DisableCollider(Collider col)
{
    oldLayer = col.gameObject.layer;
    col.gameObject.layer = voidLayer;
}

void EnableCollider(Collider col)
{
    col.gameObject.layer = oldLayer;
}

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

ตอนนี้สถานการณ์เฉพาะของคุณ

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

คุณสามารถเปลี่ยนเป็นเลเยอร์ที่ไม่ชนกับรถ

คุณสามารถใส่ collider อีกตัวลงบนซอมบี้ที่เปิดใช้งานบนทางวิ่งได้ วิธีนี้คุณสามารถใช้แรงกระแทกกับ OnTriggerEnter ได้ คุณไม่สามารถแม่นยำได้ แต่คุณสามารถประมาณได้ว่าบรรทัดฐานการติดต่ออาจจะดีพอที่จะทำให้ซอมบี้สนุก

คุณต้องถามตัวเอง:

  • ฉันต้องการที่จะเคาะซอมบี้ที่วิ่งข้ามไปรอบ ๆ ด้วยรถของฉันหรือว่าพวกเขาควรจะเล่นแอนิเมชั่นความตายหรือไม่?

  • ฉันจะสนใจไหมว่าความเร็วของรถและความเร็วเชิงมุมได้รับผลกระทบจากการชนซอมบี้หรือไม่?


1

Call Physics.IgnoreCollisionกับซอมบี้ทุกตัวผ่านฟังก์ชั่นของวัตถุผู้เล่นเช่นกันเมื่อรถเริ่มเร่ง สิ่งนี้จะทำให้ Unity ไม่ตอบสนองต่อการชนใด ๆ ระหว่างผู้เล่นและซอมบี้ เมื่อรถเพิ่มเสร็จแล้วให้โทรPhysics.IgnoreCollisionหาซอมบี้แต่ละตัวอีกครั้งส่งผ่านวัตถุของผู้เล่นและfalseทำให้การตอบสนองการปะทะเริ่มขึ้นอีกครั้ง


แต่นั่นหมายความว่าพวกเขาจะไม่ชนกับสิ่งอื่นใด
พอล Manta

ฉันจะทำวิจัยเพิ่มเติม สิ่งเดียวที่ฉันคิดได้คือ: บางทีคุณสามารถเพิกเฉยต่อการชนกันโดยการคืนค่าเท็จจาก OnCollisionEnter
Wackidev

@Wackidev นี่ไม่ใช่กรณี
Rhys van der Waerden

@ พอลฉันได้แก้ไขคำตอบของฉัน
Wackidev

0

ฉันคาดเดาว่าคุณสามารถตรวจสอบชื่อของวัตถุหรือเพิ่มมูลค่าชื่อให้กับคลาสของวัตถุแล้วตรวจสอบได้หรือไม่

bool boosting = false; //need a trigger in the game to set this to true.

function OnCollisionEnter(theCollision : Collision)
{   
    if (boosting == true)
    {
        if(theCollision.gameObject.name == "Zombie")
        {
              Debug.Log("Zombie hit during boost");              
        }
        else if(theCollision.gameObject.name == "Wall")
        {
              Debug.Log("Wall hit during boost");            
        }
    }
    else 
    {
        if(theCollision.gameObject.name == "Zombie")
        {
              Debug.Log("Zombie hit not in boost");              
        }
        else if(theCollision.gameObject.name == "Wall")
        {
              Debug.Log("Wall hit not in boost");                
        }
    }
}

จากนั้นมีตัวแปรอื่นที่คุณสามารถใช้เพื่อตรวจสอบการเพิ่มและเพิ่มเข้าไปในการตรวจสอบ

แก้ไข: เพิ่มตัวแปรนี้ใน


เขารู้วิธีได้รับแจ้งการชน เขาไม่ต้องการให้มีการกระทำใด ๆ เขาต้องการปิดการตอบสนองการชนภายในในบางกรณี
Wackidev

แน่นอนว่าเกิดอะไรขึ้นเมื่อมีการชนกันระหว่างวงเล็บ ฉันไม่เคยใช้ความสามัคคีมาก่อนดังนั้นฉันไม่รู้ แต่ใน cocos2d และ XNA มันทำแบบนั้น
ลูอิส

ที่จริงแล้ว Unity จัดการการชนกันของตัวเองผ่าน PhysX OnCollisionEnter เป็นเพียงวิธีการแจ้งเตือน ไม่ได้ออกแบบมาเพื่อจัดการกับการตอบสนองการชนจริง
Wackidev

0

ฉันคิดว่าคุณกำลังใช้เอ็นจิ้นฟิสิกส์เพื่อทำการ 'เบี่ยงเบน' โดยอัตโนมัติตามรูปร่าง / มวลเมื่อสิ่งต่าง ๆ ปะทะกัน? หากเป็นเช่นนั้นให้เปลี่ยนมวลของซอมบี้เป็นค่าที่น้อยมากและจะไม่ส่งผลกระทบต่อรถ


0

มีคำตอบสองคลาสที่นี่:

  1. ละเว้นหรือปิดใช้งานการชน
    • การแก้ปัญหาเหล่านี้จะไม่แก้ปัญหาเขาต้องการให้ซอมบี้บินได้เมื่อถูกโจมตี
  2. เปลี่ยนมวล:
    • นี่เป็นวิธีการที่ดี อย่าลืมเปลี่ยนความเฉื่อยด้วย
      • คุณสามารถเปลี่ยนรถยนต์ Mass และ Inertia เมื่อทำการเร่ง (เราทำเช่นนี้เพื่อลดผลกระทบของวัตถุที่ไม่ใช่จลนศาสตร์ทั้งหมดบนรถเมื่อทำการเร่ง)
      • สิ่งนี้ไม่ควรส่งผลกระทบต่อถนนหรือกำแพงโดยถือว่าเป็นภาพเคลื่อนไหว

หวังว่านี่จะช่วยได้!


คำตอบที่มีอยู่สองคำตอบจากหกปีที่ผ่านมาแนะนำวิธีการแบบอิงมวลชนที่คุณแนะนำมาแล้ว มีกลยุทธ์ใหม่ที่คุณต้องการเพิ่มหรือไม่?
DMGregory

ฉันขอโทษฉันยังไม่สามารถ upvote และฉันต้องการให้แน่ใจว่า Paul Manta ไม่ได้หลงทาง
dwuLive
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.