ทำไม OnCollisionEnter ของ Unity ถึงไม่ให้ค่ามาตรฐานกับฉันและวิธีที่เชื่อถือได้ที่สุดในการรับมันคืออะไร


11

Unity's on collision event ให้การชนวัตถุที่ให้ข้อมูลเกี่ยวกับการชนที่เกิดขึ้นกับคุณ (รวมถึงรายการContactPointsพร้อม hit normals)

แต่สิ่งที่คุณไม่ได้รับคือพื้นผิวมาตรฐานสำหรับคอลไลเดอร์ที่คุณยิง นี่คือภาพหน้าจอเพื่ออธิบาย เส้นสีแดงจากและสายสีฟ้าจากContactPoint.normalRaycastHit.normal

ป้อนคำอธิบายรูปภาพที่นี่

นี่เป็นตัวอย่างของ Unity ที่ซ่อนข้อมูลเพื่อให้ API ที่ง่ายขึ้นหรือไม่ หรือเทคนิคการตรวจจับการชนกันแบบเรียลไทม์มาตรฐาน 3 มิติไม่เพียงรวบรวมข้อมูลนี้หรือไม่

และในส่วนที่สองของคำถามอะไรคือวิธีที่แน่นอนและค่อนข้างมีประสิทธิภาพในการทำให้พื้นผิวเป็นปกติสำหรับการชน

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

วิธีการปัจจุบันของฉัน:

  1. สำรองข้อมูลCollision.contacts[0].pointตามปกติของมันตี

  2. Raycast ตามปกติเมื่อตะกี้สำหรับfloat.MaxValueบนCollision.collider

  3. หากล้มเหลวให้ทำซ้ำขั้นตอนที่ 1 และ 2 โดยไม่ใช้วิธีปกติ

  4. หากล้มเหลวให้ลองขั้นตอนที่ 1 ถึง 3 ด้วย Collision.contacts[1]

  5. ทำซ้ำ 4 จนสำเร็จหรือจนกว่าจะหมดคะแนนการติดต่อ

  6. Vector3.zeroให้ขึ้นผลตอบแทน

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

แก้ไข หากนี่เป็นเพียงสิ่งที่เกิดขึ้นจริงกับการชนกันของภาพ 3 มิติภาพรวมของสาเหตุในกรณีทั่วไปจะได้รับการต้อนรับเหมือนกับสิ่งที่เฉพาะเจาะจงกับ Unity


นี่เป็นเพียงแค่ความอยากรู้หรือคุณพยายามทำบางสิ่งบางอย่างและติดขัดหรือไม่? นั่นคือเหตุใดคุณคิดว่าคุณต้องการพื้นผิวตามปกติ ถามคำถามเกี่ยวกับผลกระทบที่คุณพยายามจะทำได้แทนที่จะทำอย่างไร "แก้ไข" วิธีแก้ไขปัญหาที่ไม่ได้ระบุและบางคนอาจช่วยคุณแก้ไขได้ :)
Sean Middleditch

@SeanMiddleditch ฉันไม่เห็นด้วย คำถามถูกวางไว้อย่างดีและเป็นสิ่งที่ฉันกำลังมองหา คำถามและคำตอบนี้ช่วยให้ฉันแก้ไขสิ่งที่ฉันทำผิด
SteakOverflow

คำตอบ:


12

นี่เป็นเพียงวิธีการปะทะกัน ไม่ใช่แค่ 3D แต่เป็น 2D นำตัวอย่างต่อไปนี้:

AABB ที่ทับซ้อนกัน

AABB สีเขียวและสีแดงปะทะกันและหน้าสัมผัสเป็นพื้นที่สีน้ำเงิน จุดสัมผัสจะอยู่ในพื้นที่สีน้ำเงินที่ใดที่หนึ่ง (ซึ่งสามารถแตกต่างกันไปตามอัลกอริทึม แต่มุมที่สีฟ้า / แดง / เขียวตรงตามอุดมคติ - ish)

พื้นผิวปกติแบบใดที่ควรคืน? ขอบด้านบนของ AABB สีแดงหรือขอบซ้าย? หากกล่องสีเขียวตกลงมาบางทีเราอาจเดาได้ว่าขอบบนสุด ถ้ามันเลื่อนไปทางขวาบางทีเราอาจเดาได้ว่าขอบซ้าย เกิดอะไรขึ้นถ้ามันเคลื่อนลงและถูกต้อง? เราใช้แกนของการเจาะน้อยที่สุดหรือไม่? แกนความเร็วของความเร็วที่ยิ่งใหญ่ที่สุด? ฮิวริสติกของทั้งคู่? เกิดอะไรขึ้นถ้ากล่องจะชนกันตรงมุม?

ขยายสิ่งนี้ไปยังพื้นผิว 3 มิติที่ซับซ้อนซึ่งอาจประกอบด้วย 100 tris / ใบหน้า คุณยังคงมีจุดติดต่อในอุดมคติที่มีจำนวนน้อย พื้นผิวปกติแบบใดที่ควรคืน? พื้นผิวโดยเฉลี่ยทั่วทั้งไตรตาข่าย (ซึ่งไม่เข้าท่ากับวัตถุส่วนใหญ่)? มีจุดใดที่ "ใต้" ตรงมุมกล่องของการชนกัน (ซึ่งไม่ได้กำหนดไว้อย่างดีสำหรับรูปร่างอื่น ๆ ส่วนใหญ่) คุณพยายามค้นหาใบหน้าที่ใกล้เคียงที่สุดกับจุดติดต่อที่สร้างขึ้น (ซึ่งจะต้องผ่านสองเพราะจุดติดต่อไม่ได้คำนวณโดยตรงจากใบหน้าตาข่ายใด ๆ )? หากคุณพบใบหน้าที่ใกล้ที่สุดคุณใช้ใบหน้าปกติหรือคุณแก้ไขจุดยอดของใบหน้า ณ จุดที่ติดต่อเพื่อให้ได้ภาพปกติสำหรับวัตถุ "เรียบ" ที่ถูกต้องหรือไม่?

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

แน่นอนว่าด้วยข้อ จำกัด และข้อ จำกัด เฉพาะเกี่ยวกับวัตถุโลกและการเคลื่อนไหวคุณสามารถสร้างอัลกอริธึมการชนกันทางเลือกที่สามารถบอกคุณเกี่ยวกับพื้นผิวปกติ ในกรณี 2D ด้านบนหากเราสมมติว่ากล่องไม่หมุนและเรารู้ความเร็วสัมพัทธ์และตำแหน่งสุดท้ายของแต่ละกล่องจะสามารถใช้การตรวจสอบการชนอย่างต่อเนื่องเพื่อหาว่าเมื่อใดที่พวกเขาจะชนกันและมีการชนกัน คุณสมบัติที่แน่นอนที่เกิดการชนซึ่งสามารถนำไปใช้เป็นแบบสัมผัส / การชน / พื้นผิวได้ตามปกติ เกม Platformer สร้างขึ้นบนสมมติฐานและกลวิธีพิเศษทั้งหมด (ซึ่งเป็นเหตุผลว่าทำไมการใช้ไลบรารี่ฟิสิกส์ทั่วไปเช่น Box2D หรือ Havok หรือแสงไม่เคยสร้างการควบคุมที่แม่นยำและแม่นยำที่คุณพบใน platformers คลาสสิกอย่าง Mario หรือ Sonic; อยากบอกว่า '

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


นี่คือคำตอบที่ยอดเยี่ยมและสิ่งที่ฉันกำลังมองหาขอบคุณ ปัญหาที่เฉพาะเจาะจงคือการได้รับเวกเตอร์การสะท้อนที่น่าเชื่อถือบนตัวแข็งแบบจลนศาสตร์เมื่อเกิดการชน เป็นวิธีการปกติหรือไม่หากคุณต้องการให้ข้อมูลประเภทนี้เลือกว่าคุณต้องการ raycast หรือคว้า 3 จุดติดต่อ (ถ้ามี) และนำผลิตภัณฑ์ข้ามมาใช้หรือไม่
michael.bartnett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.