เอ็นจินการชนกันทำงานอย่างไร


78

เอ็นจิ้นการชนทำงานอย่างไร

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

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

ดังนั้นอะไรคือสิ่งที่ทำให้เอ็นจิ้นการชนเกิดขึ้น


3
คุณสามารถโกงกับกล่อง bounding และ spheres, จุดตัดที่รวดเร็วในการตรวจสอบ. จากนั้นคุณสามารถตรวจสอบได้อย่างใกล้ชิดยิ่งขึ้น cs.unc.edu/~dm/collision.html en.wikipedia.org/wiki/Collision_detection คุณสามารถทำสิ่งนี้ได้อย่างช้า ๆ ด้วยอัลกอริธึมไร้เดียงสา คอมโพสิตเรขาคณิตมีเทคนิคบางอย่างที่ใช้ประโยชน์จากลักษณะทางเรขาคณิตของปัญหาและทำให้อัลกอริทึมเร็วขึ้น นี่เป็นบทความที่ดีมาก: cs.hku.hk/research/techreps/document/TR-2005-01.pdf

เอ็นจิ้นการชนคืออะไร?

4
@gnat เอ็นจิ้นการชนกันนั้นเป็นเอ็นจิ้นที่ใช้ในเกม (โดยทั่วไป) เพื่อให้ผู้เล่นของคุณ (เรียกเขาว่าบ๊อบ) เมื่อใดก็ตามที่บ๊อบเคลื่อนที่เข้ามาในกำแพงบ๊อบก็หยุดบ๊อบไม่เดินทะลุกำแพง พวกเขามักจะจัดการกับแรงโน้มถ่วงในเกมและสิ่งต่าง ๆ เช่นนั้น
JXPheonix

คำตอบ:


172

มีความแตกต่างอย่างมากระหว่างกลไกการชนกับเครื่องยนต์ฟิสิกส์ พวกเขาไม่ได้ทำสิ่งเดียวกันแม้ว่าโดยทั่วไปแล้วเครื่องมือฟิสิกส์จะอาศัยกลไกการชน

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

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

ตรวจจับการชนกัน

การตรวจจับการชนนั้นค่อนข้างง่าย วัตถุทุกชิ้นมีการแปลงและรูปร่าง (อาจมีหลายรูปร่าง) แนวทางไร้เดียงสาจะมีเอ็นจินการชนกันทำลูป O (n ^ 2) ผ่านคู่วัตถุทั้งหมดและทดสอบว่ามีการทับซ้อนกันระหว่างคู่ ในแนวทางที่ชาญฉลาดจะมีโครงสร้างข้อมูลเชิงพื้นที่จำนวนมาก (เช่นสำหรับวัตถุคงที่เทียบกับวัตถุแบบไดนามิก) รูปร่างที่มีขอบเขตสำหรับแต่ละวัตถุและรูปร่างย่อยส่วนนูนหลายส่วนสำหรับแต่ละวัตถุ

โครงสร้างข้อมูลเชิงพื้นที่ประกอบด้วยสิ่งต่าง ๆ เช่น KD-Trees, Dynamic AABB trees, Octrees / Quadtrees, Binary Space Partitioning tree และอื่น ๆ แต่ละอันมีข้อดีและข้อเสียซึ่งเป็นสาเหตุที่เอ็นจิ้นเอนด์ที่สูงกว่าบางอันใช้มากกว่าหนึ่ง ยกตัวอย่างเช่นต้นไม้ AABB แบบไดนามิกนั้นเร็วและดีจริง ๆ สำหรับการจัดการกับวัตถุที่เคลื่อนไหวจำนวนมากในขณะที่ KD-Tree อาจเหมาะสมกว่าสำหรับรูปทรงเรขาคณิตระดับคงที่ที่วัตถุชนกัน มีตัวเลือกอื่น ๆ เช่นกัน

ระยะกว้างใช้โครงสร้างข้อมูลเชิงพื้นที่และปริมาณขอบเขตนามธรรมสำหรับแต่ละวัตถุ ไดรฟ์ข้อมูลขอบเขตเป็นรูปร่างง่าย ๆ ที่ล้อมรอบวัตถุทั้งหมดโดยทั่วไปโดยมีเป้าหมายในการล้อมรอบวัตถุนั้นว่า "แน่น" ที่สุดเท่าที่จะเป็นไปได้ในขณะที่เหลือราคาถูกเพื่อทำการทดสอบการชน รูปร่างที่ถูกล้อมรอบที่พบมากที่สุดคือกล่องที่ถูกจัดแนวตามแนวแกน, กล่องที่ถูกจัดแนวตามวัตถุ, ทรงกลมและแคปซูล โดยทั่วไปแล้ว AABBs จะถือว่าเร็วที่สุดและง่ายที่สุด (Spheres นั้นง่ายกว่าและเร็วกว่าในบางกรณี แต่โครงสร้างข้อมูลเชิงพื้นที่จำนวนมากนั้นต้องการการเปลี่ยนทรงกลมเป็น AABB ต่อไป) แต่ก็มีแนวโน้มที่จะบรรจุวัตถุจำนวนมากได้ไม่ดี แคปซูลเป็นที่นิยมในเอนจิ้น 3 มิติสำหรับการจัดการการชนระดับตัวละคร เครื่องมือบางอย่างจะใช้รูปร่างสองขอบเขต

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

ติดต่อ Manifold Generation

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

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

การตอบสนองทางกายภาพ

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

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

การตอบสนองทางฟิสิกส์ขั้นสูงมากขึ้นซับซ้อนขึ้นอย่างรวดเร็ว วิธีการข้างต้นจะพังทลายลงในหลาย ๆ สถานการณ์รวมถึงวัตถุหนึ่งวางอยู่บนอีกสองคน การจัดการกับแต่ละคู่ด้วยตัวเองจะทำให้ "กระวนกระวายใจ" และวัตถุจะเด้งไปรอบ ๆ เทคนิคพื้นฐานที่สุดคือการทำซ้ำการแก้ไขความเร็วจำนวนคู่ของวัตถุที่ชนกัน ตัวอย่างเช่นเมื่อมีกล่อง "A" นั่งอยู่ด้านบนของอีกสองกล่อง "B" และ "C" การชนกันของข้อมูล AB จะได้รับการจัดการก่อนทำให้กล่อง A เอียงต่อไปในกล่อง C จากนั้นจัดการกับการชน AC ตอนเย็น ออกกล่องบ้าง แต่ดึง A ลงไปและ B จากนั้นทำซ้ำอีกครั้งดังนั้นข้อผิดพลาด AB ที่เกิดจากการแก้ไข AC จะได้รับการแก้ไขเล็กน้อยทำให้เกิดข้อผิดพลาดเล็กน้อยในการตอบสนอง AC ซึ่งจัดการเมื่อ AC ถูกประมวลผลอีกครั้ง จำนวนการวนซ้ำที่ทำขึ้นนั้นไม่คงที่และไม่มีจุดใดที่จะกลายเป็น "สมบูรณ์แบบ" แต่จะวนซ้ำทุกครั้งที่หยุดให้ผลลัพธ์ที่มีความหมาย การวนซ้ำ 10 ครั้งเป็นครั้งแรกโดยทั่วไป แต่ต้องใช้การปรับแต่งตัวเลขที่ดีที่สุดสำหรับเอ็นจิ้นเฉพาะและความต้องการของเกม

ติดต่อแคช

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

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

นอนหลับ

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

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

วัตถุเป็นตัวเลือกในการนอนหลับเมื่อมันมีความเร็วใกล้ศูนย์มากกว่าหนึ่งเฟรม โปรดทราบว่า epsilon ที่คุณใช้สำหรับทดสอบความเร็วใกล้ศูนย์นี้อาจจะสูงกว่า epsilon เปรียบเทียบกับจุดลอยตามปกติเล็กน้อยเนื่องจากคุณควรคาดหวังว่า jitter ที่มีวัตถุซ้อนกันและคุณต้องการให้วัตถุทั้งกองนอนหลับหากพวกเขา ' กำลังพัก "ใกล้พอ" ถึงมั่นคง แน่นอนว่าเกณฑ์จะต้องมีการปรับแต่งและการทดลอง

ข้อ จำกัด

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

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


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

1
@ gardian06: มันเป็นภาพรวมที่เขียนได้อย่างรวดเร็วทำให้แน่ใจว่ามันจะขยายออกไปได้เล็กน้อย ฉันลืมพูดถึงการนอนวัตถุเช่นซึ่งเป็นประโยชน์สวย สำหรับการวนซ้ำฉันวนซ้ำทุกคู่และแม้จะมีจำนวนการทำซ้ำที่ค่อนข้างใหญ่ (20+) ฉันไม่เคยสังเกตเห็นปัญหาด้านประสิทธิภาพ (แต่อีกครั้งนั่นคือการนอนหลับของวัตถุดังนั้นการชนที่ใช้งานค่อนข้างน้อยในการแก้ไข )
Sean Middleditch

1
คำตอบที่ยอดเยี่ยม +1 การอ่านสิ่งนี้ทำให้ฉันต้องการนำอัลกอริทึมเหล่านี้ไปใช้จริง ๆ
Miles Rout

3

ปัญหาทั่วไป: ตรวจสอบว่าชุดค่าผสมใดของวัตถุที่เป็นไปได้มีปริมาตรจุดตัดที่ไม่ใช่ศูนย์

วิธีการทั่วไปที่ไร้เดียงสานั้นง่าย: สำหรับแต่ละคู่ของวัตถุที่เป็นไปได้ให้คำนวณปริมาตรของจุดตัด โดยทั่วไปจะไม่สามารถใช้งานได้เนื่องจากต้องใช้การดำเนินการตัดกัน O (n ^ 2) ค่อนข้างแพง

ดังนั้นการใช้งานในทางปฏิบัติมักจะมีความเชี่ยวชาญทำให้มีข้อสมมติฐานบางอย่างที่จะช่วยให้หลีกเลี่ยงการตรวจสอบตัดกันหรือลดค่าใช้จ่าย การแบ่งเชิงพื้นที่ใช้ประโยชน์จากความจริงที่ว่าวัตถุนั้นมักจะมีขนาดเล็กเมื่อเทียบกับปริมาณรวมและโดยทั่วไปจะลดจำนวนการเปรียบเทียบกับ O (n log n) กล่องขอบที่มีการจัดแนวแกนและทรงกลมที่มีขอบเขตให้การตรวจสอบแบบตัดกันแบบหยาบราคาไม่แพงตราบใดที่วัตถุปฏิบัติตามสมมติฐานความกะทัดรัด และอื่น ๆ


2

"เครื่องมือการชน" หนึ่งที่ฉันใช้รู้สึกง่ายมากที่จะเข้าใจ

โดยทั่วไปแล้ว API ให้วัตถุชนิดหนึ่งที่มีวิธีการcollidesWithดังกล่าว

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

ในแอปพลิเคชันของฉันฉันเพิ่งเรียกใช้เป็นระยะcollidesWithเพื่อค้นหาว่าเกิดการชนหรือไม่

สวยง่ายใช่มั้ย


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

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

  • ผู้ใช้เพียงแค่ไม่สนใจว่ามีวัตถุกี่ชิ้นที่อยู่เบื้องหลัง พวกเขามีความสุขตราบใดที่ผลลัพธ์นั้นให้ความรู้สึกเหมือนที่พวกเขาคาดหวังเช่นบ้านที่มีรั้วหลังบ้านล้อมรอบ:

    http://i.stack.imgur.com/4Wn5B.jpg


2

ฉันคิดว่าคุณสับสนเล็กน้อยในสิ่งที่คุณกำลังพูดถึงและกำลังพูดถึงสิ่งที่แตกต่างกันเล็กน้อย

ความสามารถในการบอกว่ารายการนี้ถูกย้ายจากตำแหน่ง X ไปยังตำแหน่ง Y ขึ้นอยู่กับฟิสิกส์ (สิ่งนี้จะโจมตีวิธีที่พวกเขาเคลื่อนไหว

วิธีการที่ใช้สำหรับการตรวจจับการชนกันจะพิจารณาจากโครงสร้างของเกมของคุณ ถ้าเกมของคุณเป็นโลกเปิดที่มีขนาดใหญ่คุณควรพิจารณาแบ่งพาร์ติชั่นเป็นอย่างมาก (quad-tree [oct-tree สำหรับ 3D], BSP, Grid ดั้งเดิมหรือการทดสอบแบบเก่าทุกอย่างที่เข้าใกล้)

วิธีที่ดีที่สุดในการใช้ระบบตรวจจับการชนคือทำตามขั้นตอน

  1. วางวัตถุทั้งหมดลงในไดรฟ์ข้อมูล / รูปร่างขอบเขตทั่วไปจากนั้นทดสอบวัตถุเหล่านั้น

  2. หากผ่านไป 1 ครั้งให้ทำซ้ำโดยทำซ้ำปริมาณ / รูปร่างที่ซับซ้อนมากขึ้นจนกระทั่งพร้อมที่จะทดสอบรูปทรงเรขาคณิตที่แน่นอน

  3. ทดสอบเรขาคณิตสัมบูรณ์จำนวนเวลาที่คุณทำซ้ำขั้นตอนที่ 2 นั้นจะพิจารณาจากความซับซ้อนของรูปร่างของคุณและความแม่นยำของรูปร่างเหล่านั้น

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

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

ห่วงแบบดั้งเดิมมีลักษณะเช่นนี้:

receive input
update physics
collision detection
collision resolution
render
repeat

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

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

@ seanmiddleditch ที่ฉันตั้งใจมากขึ้นคือการประมาณจะถูกทดสอบโดยปกติจะพยายามหลีกเลี่ยงการทดสอบรูปหลายเหลี่ยมเว้า / โพลี
gardian06

@ktodisco มันขึ้นอยู่กับความเป็นรูปเป็นร่างและความแม่นยำที่จะต้องมีและสิ่งที่จะต้องส่งกลับสำหรับระบบฟิสิกส์เพื่อแก้ไขปัญหาการชนเนื่องจากสิ่งนี้อาจแตกต่างกันไปขึ้นอยู่กับเครื่องยนต์ฟิสิกส์และความถูกต้องที่ตั้งใจของ การตอบสนอง
gardian06

@ Guardian06 คำอธิบายของ seanmiddleditch มีความเป็นไปได้มากขึ้นแม้ว่าการทดสอบจุดตัดกันระหว่างตัวละครที่ประกอบด้วยรูปหลายเหลี่ยมหลายพันก็ยังคงเป็นความคิดที่ดี
kevintodisco

1

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

ดูต้นไม้ BSP และ Kd สำหรับข้อมูลเพิ่มเติม นอกจากนี้ยังมีวิธีการแบ่งพาร์ติชันอื่น ๆ


0

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

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

ประการที่สามใช้วิธีที่มีประสิทธิภาพ / เหมาะสมที่สุดในการตรวจสอบ

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