คำถามติดแท็ก entity-system

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

4
ฉันจะกำหนดรหัสเอนทิตีในวิธีที่แข็งแกร่งในเกมเครือข่ายได้อย่างไร
ฉันกำลังทำงานกับระบบเอนทิตีสำหรับเกมบนเครือข่ายและฉันกำหนดรหัสประจำตัวจำนวนเต็ม 32 บิตที่ไม่ซ้ำกันซึ่งฉันสามารถใช้เพื่ออ้างอิงการอ้างอิงไปยังเอนทิตีและเอนทิตีเองได้ ขณะนี้ฉันเพิ่งเพิ่มตัวนับทุกครั้งที่มีการสร้างเอนทิตี ฉันเดารหัสในที่สุดจะหมด แต่ฉันไม่คาดหวังว่าจะมี 4 พันล้านหน่วย นอกจากนี้สิ่งนี้จะช่วยหลีกเลี่ยงปัญหาหากเอนทิตี # 5 ถูกทำลายและเราได้รับ id 5 มันหมายถึงการอ้างถึง # 5 ใหม่หรือเก่าที่ถูกลบ # 5 หรือไม่ ปัญหาคือฉันไม่แน่ใจว่าจะจัดการ / หลีกเลี่ยงการชนได้อย่างไร ในปัจจุบันหากลูกค้าได้รับการอัปเดตสำหรับเอนทิตีที่มีรหัสสูงกว่า "ฟรีไอดี" ในปัจจุบันมันแค่กระแทกมันเป็นไอดีฟรีจนถึงอดีต แต่นั่นดูไม่แข็งแกร่งนัก ฉันคิดเกี่ยวกับการกำหนดช่วงให้กับลูกค้าแต่ละรายเพื่อให้พวกเขาสามารถจัดสรรเอนทิตีโดยไม่ขัดแย้งกัน (พูดว่า n บิตอันดับแรกคือหมายเลขผู้เล่น) แต่ฉันกังวลว่าจะเกิดอะไรขึ้นถ้าช่วงเริ่มทับซ้อนกันเมื่อเวลาผ่านไป มีวิธีจัดการที่ดีกว่านี้ไหม ฉันควรจะสนใจเกี่ยวกับรหัสล้นหรือจะผ่านจุดสิ้นสุดของช่วงที่อนุญาตหรือไม่ ฉันสามารถเพิ่มรหัสเพื่อตรวจสอบกรณีเหล่านี้ แต่จะทำอย่างไรถ้าเกิดขึ้นนอกเหนือจากความผิดพลาด อีกทางเลือกหนึ่งคือการใช้บางอย่างที่มีโอกาสสูงกว่าในการเป็นเอกลักษณ์เช่น 128- บิต GUID แต่ดูเหมือนว่าหนักมากสำหรับเกมที่พยายามลดปริมาณการใช้เครือข่าย นอกจากนี้ในความเป็นจริงฉันจะไม่ต้องการเอนทิตีเพิ่มเติมในคราวเดียวจากนั้นจะพอดีกับจำนวนเต็ม 32- บิตหรือ 24 บิต ขอบคุณ!

2
การจัดการสถานะของเกมและอินพุตในระบบเอนทิตีที่อิงองค์ประกอบ
คำถามของฉันคือ: ฉันจะจัดการกับสถานะของเกมในระบบเอนทิตีของฉันได้อย่างไรโดยไม่หันไปใช้การเก็บวัตถุสแต็คของเกมไว้รอบ ๆ ดังนั้นการออกแบบระบบเอนทิตีของฉันหมายความว่าเมื่อเอนทิตีต้องลงทะเบียนสำหรับเหตุการณ์อินพุทเช่นอินพุทคอมโพเนนต์จะเรียกระบบอินพุตและพูดว่า "ลงทะเบียนเอนทิตีนี้สำหรับอินพุตนี้" ทั้งหมดนี้เป็นสิ่งที่ดีและดีอย่างไรก็ตามหากคุณเพิ่มแนวคิดเรื่องสถานะเกม (กล่าวว่าหน้าจอหยุดชั่วคราว) มันจะกลายเป็นปัญหาในการทำงานถ้าเอนทิตีอยู่ในสถานะปัจจุบันและควรได้รับอินพุต ฉันสามารถเพิ่มองค์ประกอบอินพุต / ระบบเพื่อให้มันบอกว่า "ลงทะเบียนเอนทิตีนี้สำหรับอินพุตนี้ในขณะที่อยู่ในสถานะเกม" แต่สิ่งนี้ต้องการให้ทุกเอนทิตีรู้ว่าต้องใช้เอนทิตี้แบบใดและอาจไม่ชัดเจน นอกจากนี้การรักษารายการเกมรอบตัวต่ออินพุตที่ลงทะเบียนไว้ (และระบบอื่น ๆ ที่ใช้การโทรกลับ) นั้นไม่ได้มีประสิทธิภาพมากเกินไป ความคิดอื่นที่ฉันมีคือเนื่องจากจะมีเอนทิตีที่แสดงถึงสถานะของเกมทำเครื่องหมายว่าถูกปิดใช้งานจากนั้นเมื่อสร้างการตรวจสอบเหตุการณ์อินพุตให้แน่ใจว่าเอนทิตีไม่ใช่ทายาทของเอนทิตีของเกมที่ถูกปิดใช้งาน ดูเหมือนว่ามีราคาแพงในการทำงานจากผู้ปกครองสำหรับการโทรกลับทุกครั้ง อีกแนวคิดหนึ่งคือให้ระบบทั้งหมดเก็บข้อมูลของพวกเขากับสถานะปัจจุบันด้วยวิธีนี้เมื่อสร้างอินพุตข้อมูลเอนทิตีเป้าหมายจะไม่เป็นตัวเลือก อย่างไรก็ตามสิ่งนี้ทำให้ความสามารถในการสื่อสารระหว่างเอนทิตีในรัฐต่าง ๆ (ไม่เป็นปัญหามากนักสำหรับหน้าจอหยุดชั่วคราว แต่คิดว่าการเลือกล็อคในการหลงลืม / Skyrim) ความคิดอื่น ๆ ที่ฉันมีคือการให้ส่วนประกอบทั้งหมดจัดการกับเหตุการณ์การเปลี่ยนแปลงสถานะและสื่อสารกับระบบที่เกี่ยวข้องของพวกเขาเพื่อปิดการใช้งานสิ่งที่พวกเขาได้ลงทะเบียนไว้และเปิดใช้งานอีกครั้งเมื่อเปลี่ยนกลับเป็นสถานะนี้ ข้อที่สอง (ทำเครื่องหมายวัตถุว่าปิดใช้งาน) และไปข้างหน้า (ให้แต่ละองค์ประกอบจัดการกับการเปลี่ยนแปลงสถานะ) ดูเหมือนจะเป็นความคิดที่ดีที่สุดของฉัน แต่ไม่มีสิ่งใดที่กระโดดออกมาที่ฉันว่ายอดเยี่ยมเป็นพิเศษ ใครบ้างมีความคิดอื่น ๆ เกี่ยวกับวิธีการทำเช่นนี้? แก้ไขขณะที่ฉันพูดถึงอินพุตโดยเฉพาะในคำถามนี้อาจหมายถึงระบบใด ๆ ที่สามารถส่งข้อความ / กิจกรรมไปยังเอนทิตีเช่นการชนเหตุการณ์จับเวลา ฯลฯ ...

3
เหตุใดจึงเป็นความคิดที่ไม่ดีในการจัดเก็บวิธีการในเอนทิตีและส่วนประกอบ (พร้อมกับคำถามระบบ Entity อื่น ๆ )
นี่คือการติดตามคำถามนี้ซึ่งฉันตอบไป แต่สิ่งนี้จะจัดการกับหัวข้อที่เฉพาะเจาะจงมากขึ้น คำตอบนี้ช่วยให้ฉันเข้าใจระบบ Entity ได้ดีกว่าบทความ ฉันได้อ่าน(ใช่แล้ว) บทความเกี่ยวกับระบบ Entity และมันบอกฉันต่อไปนี้: เอนทิตีเป็นเพียง id และอาร์เรย์ของส่วนประกอบ (บทความบอกว่าการเก็บเอนทิตีในส่วนประกอบไม่ใช่วิธีที่ดีในการทำสิ่งต่าง ๆ แต่ไม่มีทางเลือกอื่น) ส่วนประกอบคือชิ้นส่วนของข้อมูลที่บ่งบอกถึงสิ่งที่สามารถทำได้กับเอนทิตีที่แน่นอน ระบบคือ "วิธีการ" พวกเขาทำการจัดการข้อมูลกับเอนทิตี ดูเหมือนว่าจะใช้งานได้จริงในหลาย ๆ สถานการณ์ แต่ส่วนที่เกี่ยวกับส่วนประกอบที่เป็นเพียงคลาสข้อมูลกำลังรบกวนฉัน ตัวอย่างเช่นฉันจะใช้คลาส Vector2D ของฉัน (ตำแหน่ง) ในระบบกิจการได้อย่างไร ชั้น Vector2D เก็บข้อมูล: พิกัด x และ y แต่ก็มีวิธีการซึ่งมีความสำคัญต่อความมีประโยชน์และแยกความแตกต่างของชั้นเรียนจากเพียงแค่องค์ประกอบสองแถว วิธีการตัวอย่างเช่น: add(), rotate(point, r, angle), substract(), normalize()และมาตรฐานอื่น ๆ ที่มีประโยชน์และจำเป็นอย่างยิ่งวิธีการที่ตำแหน่ง (ซึ่งเป็นกรณีของชั้น Vector2D) ควรจะมี หากองค์ประกอบนั้นเป็นเพียงตัวยึดข้อมูลมันจะไม่สามารถมีวิธีการเหล่านี้ได้! ทางออกหนึ่งที่อาจปรากฏขึ้นก็คือการใช้พวกเขาภายในระบบ …

1
วิธีการได้รับประโยชน์จาก cpu แคชในเอ็นจิ้นเกมเอนทิตีคอมโพเนนต์ระบบ?
ฉันมักจะอ่านในเอกสารประกอบเครื่องมือเกมของ ECS ซึ่งเป็นสถาปัตยกรรมที่ดีสำหรับการใช้แคช cpu อย่างชาญฉลาด แต่ฉันไม่สามารถคิดได้ว่าเราจะได้ประโยชน์จาก cpu cache ได้อย่างไร หากส่วนประกอบถูกบันทึกในอาร์เรย์ (หรือพูล) ในหน่วยความจำต่อเนื่องเป็นวิธีที่ดีในการใช้ cpu cache แต่ถ้าเราอ่านส่วนประกอบตามลำดับ เมื่อเราใช้ระบบพวกเขาต้องการรายการเอนทิตีซึ่งเป็นรายการเอนทิตีที่มีส่วนประกอบที่มีประเภทเฉพาะ แต่รายการเหล่านี้ให้ส่วนประกอบในวิธีการสุ่มไม่ใช่ตามลำดับ ดังนั้นวิธีการออกแบบ ECS เพื่อเพิ่มการเข้าชมแคชสูงสุด? แก้ไข: ตัวอย่างเช่นระบบ Physic ต้องการรายการเอนทิตีสำหรับเอนทิตีที่มีส่วนประกอบ RigidBody และ Transform (มีพูลสำหรับ RigidBody และพูลสำหรับคอมโพเนนต์การแปลง) ดังนั้นลูปสำหรับการอัพเดตเอนทิตีจะเป็นดังนี้: for (Entity eid in entitiesList) { // Get rigid body component RigidBody *rigidBody = entityManager.getComponentFromEntity<RigidBody>(eid); // Get transform component …

3
องค์ประกอบ OOP หนักเทียบกับระบบส่วนประกอบของเอนทิตีบริสุทธิ์? [ปิด]
ตามที่เป็นอยู่ในปัจจุบันคำถามนี้ไม่เหมาะสำหรับรูปแบบคำถาม & คำตอบของเรา เราคาดหวังคำตอบที่จะได้รับการสนับสนุนจากข้อเท็จจริงการอ้างอิงหรือความเชี่ยวชาญ แต่คำถามนี้มีแนวโน้มที่จะเรียกร้องให้มีการอภิปรายโต้แย้งโต้แย้งหรือการอภิปรายเพิ่มเติม หากคุณรู้สึกว่าคำถามนี้สามารถปรับปรุงและเปิดใหม่ได้โปรดไปที่ศูนย์ช่วยเหลือเพื่อขอคำแนะนำ ปิดให้บริการใน7 ปีที่ผ่านมา ฉันยอมรับว่าฉันได้ทำบาปมากเกินไปและแม้กระทั่งการละเมิดมรดก โครงการเกมแรก (ข้อความ) ที่ฉันทำเมื่อฉันเรียนหลักสูตร OOP ไปจนถึง "ล็อคประตู" และ "ปลดล็อคประตู" จาก "ประตู" และ "ห้องที่มีประตูเดียว", "ห้องที่มีสองประตู" และ ต่อจาก "ห้อง" ด้วยเกม (กราฟิก) ที่ฉันทำงานเมื่อเร็ว ๆ นี้ฉันคิดว่าฉันได้เรียนรู้บทเรียนและ จำกัด การใช้การสืบทอด อย่างไรก็ตามฉันสังเกตเห็นปัญหาเริ่มปรากฏขึ้นในไม่ช้า คลาสรูทของฉันเริ่มขยายตัวมากขึ้นเรื่อย ๆ และคลาสลีฟของฉันก็เต็มไปด้วยรหัสที่ซ้ำกัน ฉันคิดว่าฉันยังคงทำสิ่งผิดปกติและหลังจากค้นหาทางออนไลน์ฉันพบว่าฉันไม่ใช่คนเดียวที่มีปัญหานี้ มันเป็นวิธีการที่ฉันค้นพบระบบ Entity หลังจากการวิจัยอย่างละเอียด (อ่าน: googlefu) เมื่อฉันเริ่มอ่านมันฉันก็สามารถเห็นได้อย่างชัดเจนว่ามันสามารถแก้ปัญหาที่ฉันมีกับลำดับชั้นของ OOP ดั้งเดิมที่มีส่วนประกอบ สิ่งเหล่านี้อยู่ในการอ่านครั้งแรกอย่างไรก็ตาม เมื่อผมเจอมากขึ้น ... “รุนแรง” ES …

3
การจัดระเบียบระบบเอนทิตีด้วยตัวจัดการคอมโพเนนต์ภายนอก
ฉันออกแบบเอ็นจิ้นเกมสำหรับเกมยิง 2D แบบผู้เล่นหลายคนจากบนลงล่างซึ่งฉันต้องการใช้ซ้ำได้อย่างมีเหตุผลสำหรับเกมยิงจากบนลงล่างอื่น ๆ ในขณะนี้ฉันกำลังคิดว่าควรออกแบบระบบเอนทิตี้ของมันอย่างไร ครั้งแรกที่ฉันคิดเกี่ยวกับเรื่องนี้: ฉันมีคลาสชื่อ EntityManager ควรใช้วิธีการที่เรียกว่าการปรับปรุงและอีกวิธีหนึ่งที่เรียกว่าการวาด เหตุผลที่ฉันแยกลอจิกและการเรนเดอร์ก็เพราะฉันสามารถตัดเมธอด Draw ได้หากรันเซิร์ฟเวอร์สแตนด์อะโลน EntityManager เป็นเจ้าของรายการของวัตถุประเภท BaseEntity แต่ละเอนทิตีเป็นเจ้าของรายการของส่วนประกอบเช่น EntityModel (การนำเสนอที่เป็นไปได้ของเอนทิตี), EntityNetworkInterface และ EntityPhysicalBody EntityManager ยังเป็นเจ้าของรายชื่อผู้จัดการองค์ประกอบเช่น EntityRenderManager, EntityNetworkManager และ EntityPhysicsManager ตัวจัดการส่วนประกอบแต่ละตัวจะอ้างอิงถึงองค์ประกอบของเอนทิตี มีสาเหตุหลายประการในการย้ายรหัสนี้ออกจากคลาสของเอนทิตีและดำเนินการโดยรวมแทน ตัวอย่างเช่นฉันใช้ไลบรารีฟิสิกส์ภายนอก Box2D สำหรับเกม ใน Box2D คุณต้องเพิ่มเนื้อหาและรูปร่างให้กับโลก (เป็นเจ้าของโดย EntityPhysicsManager ในกรณีนี้) และเพิ่มการโทรกลับการชนกันของข้อมูล (ซึ่งจะถูกส่งไปยังวัตถุเอนทิตีในระบบของฉัน) จากนั้นคุณเรียกใช้ฟังก์ชันที่จำลองทุกอย่างในระบบ ฉันพบว่ามันยากที่จะหาทางออกที่ดีกว่าในการทำเช่นนี้ในการจัดการส่วนประกอบภายนอกเช่นนี้ การสร้างเอนทิตีทำเช่นนี้: EntityManager ใช้เมธอด RegisterEntity (entityClass, factory) ซึ่งลงทะเบียนวิธีสร้างเอนทิตีของคลาสนั้น นอกจากนี้ยังใช้เมธอด …

1
วิธีจัดการกับวัสดุในระบบ Entity / Component
การปรับใช้ E / C ของฉันเป็นสิ่งพื้นฐานที่หน่วยงานเป็นเพียง ID ของคอมโพเนนต์คือข้อมูลและระบบดำเนินการกับข้อมูล ตอนนี้ฉันมีปัญหากับวัสดุวัตถุและการแสดงผลโดยทั่วไป สำหรับ objetcs ธรรมดาที่ฉันมี a ModelComponent, เชื่อมโยงกับ a RenderSystem, ModelComponentจะมีรหัสจุดสุดยอดบัฟเฟอร์ที่ระบบการเรนเดอร์ใช้ ง่ายMaterialComponentอาจจะมีสีหรือความแข็งแรง specular ฯลฯ แต่ผมอยากให้มันเป็นพอมีความยืดหยุ่นเพื่อให้สามารถมากกว่าหนึ่งทำให้ผ่านและ "ผลกระทบ" MaterialComponentทั่วไปที่ไม่ได้เป็นเรื่องง่ายเป็นตัวแปรที่เรียบง่ายใน พยายามแก้ไขปัญหาเหล่านี้ฉันหาวิธีแก้ไขสองวิธี: 1 - ส่วนประกอบวัสดุที่มีความพิเศษมาก บางสิ่งเช่นนี้ struct Material : public Component { ShaderData* shader; std::vector<std::pair<std::string, boost::any>> uniforms; [...] }; และในระบบเรนเดอร์ฉันจะวนซ้ำและส่งชุดไปที่ shader ฉันคิดว่านี่จะช้า แต่เร็วพอสำหรับจุดประสงค์ของฉัน 2 - อีกชั้นหนึ่งของนามธรรม, MaterialData การมีคลาสเพื่อห่อวัสดุเฉพาะที่สามารถสืบทอดได้โดยวัสดุพิเศษอะไรก็ตามคลาสพื้นฐานจะมีบางอย่างเช่นvoid …

2
การตรวจจับการชนกันและการตอบสนองใน Entity System
สนุกยิ่งขึ้นด้วย ES ... ปัจจุบันฉันมีระบบน้อย: Renderer (แอตทริบิวต์ Renderable, แอตทริบิวต์การแปลง) การเคลื่อนไหว (แอตทริบิวต์ที่เคลื่อนย้ายได้, การแปลงแอตทริบิวต์, แอตทริบิวต์ที่แสดงผลได้ [สำหรับกล่องขอบ ฯลฯ ]) อินพุต (แอตทริบิวต์ InputReceiver) เป็นต้น ฉันกำลังเพิ่มการตรวจจับการชน ความคิดแรกของฉันคือการเพิ่มระบบใหม่ที่ดำเนินการชนกัน มันสมเหตุสมผลสำหรับฉันที่จะแยกสิ่งนี้ออกจากMotionระบบเนื่องจากไม่ใช่ทุกสิ่งที่เคลื่อนไหวหรือเป็นภาพเคลื่อนไหวจำเป็นต้องมีส่วนร่วมในการตรวจจับการชนกัน - กล้องหมอก ฯลฯ - แต่ดูเหมือนว่าCollisionและMotionมันพึ่งพาซึ่งกันและกัน เมื่อไหร่ Motionย้ายเอนทิตีการแปลงจะต้องได้รับการตรวจสอบความถูกต้องCollisionและการเคลื่อนไหวจะถูกยกเลิกหรือปรับ (การกระดอนหยุดที่ผนัง ฯลฯ ) อีกทางเลือกหนึ่งคือการสร้างแอตทริบิวต์ Collidable ที่รักษาการอ้างอิงไปยังวัตถุการชน - kd-tree, octree เป็นต้นที่ใช้ร่วมกันระหว่างเอนทิตีที่สามารถชนกัน Motionระบบแล้วจะตรวจสอบสำหรับแอตทริบิวต์นั้นและใช้มันในการตรวจสอบหรือปรับการเคลื่อนไหว จากมุมมองของรหัสนั่นเป็นทางออกที่ยอมรับได้ อย่างไรก็ตามจากมุมมองสถาปัตยกรรมของ ECS ดูเหมือนว่ามันเป็นการผลักตรรกะในMotionระบบที่ไม่สามารถใช้กับเอนทิตีทั้งหมดที่มีMovableแอตทริบิวต์ ฉันยังสามารถจัดเก็บเวคเตอร์แบบเคลื่อนไหวในMovableแอตทริบิวต์และColliderปรับระบบTransformตามต้องการ แต่จะเกี่ยวข้องกับการทำซ้ำการทำงานระหว่างMotionและColliderหรือการโทรกลับจากColliderไปยังMotionด้วยข้อมูลบางอย่างเกี่ยวกับตำแหน่งการชนและข้อมูลพื้นผิวสำหรับการตีกลับ / การสะท้อน ฯลฯ . …

2
ไทล์แม็พใน Entity System Framework
ฉันอ่านกรอบ Entity System เป็นพิเศษโดยเฉพาะอาร์ทิมิส ฉันพยายามตัดสินใจว่ามันเหมาะสมกับฉันหรือไม่ ฉันทำงานบนเกมอาร์ตพิกเซล 2d อย่างเคร่งครัดและฉันไม่คิดว่าพวกเขาจะต้องใช้ทรัพยากรมากนัก ฉันเคยใช้ OOP มาตรฐานมาแล้วและมีมรดกมากมายในอดีต ความเข้าใจของฉันเกี่ยวกับ Entity System Framework ตอนนี้ (ฉันไม่แน่ใจว่าฉันเข้าใจทั้งหมดหรือไม่) คือ: เอนทิตีเป็นอะไรนอกจาก ID ส่วนประกอบคืออะไร แต่ข้อมูลที่เป็นใบ้เพิ่มไปยังกลุ่มส่วนประกอบเอนทิตี ระบบคือฟังก์ชั่นอัปเดตที่เชื่อมต่อกับโลกเพื่อจัดการทุกเอนทิตีที่ตรงกับลายเซ็นองค์ประกอบของระบบ หากความเข้าใจของฉันถูกต้องฉันก็มีปัญหานิดหน่อยที่จะเพิ่มแนวความคิดในการเพิ่ม tilemaps และ AI Behavioral Trees ในกรอบนี้ ฉันจะถามเกี่ยวกับ AI ในอนาคต ควรมีการสร้าง tilemap ในเฟรมเวิร์กนี้หรือไม่? หรือควรแยกไว้ต่างหากเพื่อให้ง่ายต่อการสร้างด้วยโปรแกรมแก้ไข tilemap? ถ้า tilemap ควรสร้างไว้ในเฟรมเวิร์กนี้แต่ละไทล์เป็นเอนทิตีที่แตกต่างกันหรือไม่? และ tilemap เป็นระบบ? หรือเป็น tilemap เองเอนทิตีเดียวที่มีการสืบทอดสร้างขึ้นจากมัน? หาก tilemap กระจายตัวอะไรจะเป็นวิธีที่ดีที่สุดในการตรวจจับการชนกันของเอนทิตีเทียบกับ …

3
การจัดการอินพุตในการออกแบบตามส่วนประกอบ
ฉันรู้ว่าคำถามนี้ถูกถามหลายครั้ง แต่ฉันยังไม่แน่ใจว่าจะใช้การจัดการอินพุตในเอนจินที่ใช้ส่วนประกอบได้อย่างไร การออกแบบที่ใช้ส่วนประกอบที่ฉันใช้นั้นเป็นไปตามชุดบล็อกของT = MachineและArtemisซึ่ง Entities เป็นแค่รหัส มีสามแนวคิดหลักที่ฉันมีในการใช้การจัดการอินพุต: องค์ประกอบอินพุตจะจัดกิจกรรมที่สนใจ ระบบอินพุตจะแปลเหตุการณ์ของคีย์และเมาส์เป็นเหตุการณ์ของเกมและวนลูปผ่านเอนทิตีที่มีองค์ประกอบอินพุตและหากพวกเขาสนใจในเหตุการณ์ระบบจะดำเนินการที่เหมาะสม การกระทำนี้จะถูกเข้ารหัสอย่างหนักในระบบอินพุต ไม่มีองค์ประกอบอินพุต คุณจะลงทะเบียนเอนทิตีที่มีเหตุการณ์เฉพาะไปยังระบบอินพุต จากนั้นระบบอินพุตจะส่งข้อความ (พร้อมรหัสเอนทิตีและประเภทเหตุการณ์) ไปยังระบบอื่นเพื่อให้สามารถดำเนินการที่เหมาะสมได้ หรือในกรณีแรกการกระทำจะถูกกำหนดค่าตายตัวในระบบอินพุต คล้ายกับวิธีแรก แต่แทนที่จะเขียนโค้ดการดำเนินการกับระบบอินพุตอย่างหนักส่วนประกอบจะมีแผนที่ของเหตุการณ์ไปยังฟังก์ชั่น (เช่นstd::map<std::function>) ซึ่งจะถูกเรียกโดยระบบอินพุต สิ่งนี้มีผลกระทบเพิ่มเติมจากความสามารถในการจับคู่เหตุการณ์เดียวกันกับการกระทำที่แตกต่างกัน คุณจะแนะนำวิธีการใด ๆ ข้างต้นหรือคุณมีข้อเสนอแนะใด ๆ ที่จะช่วยให้ฉันใช้ระบบจัดการอินพุตที่ยืดหยุ่นได้หรือไม่? นอกจากนี้ฉันยังไม่คุ้นเคยกับหลายเธรด แต่ข้อเสนอแนะใด ๆ ที่จะทำให้การใช้เธรดเป็นมิตรก็ยินดีด้วย หมายเหตุ: ข้อกำหนดเพิ่มเติมหนึ่งข้อที่ฉันต้องการให้มีการนำไปใช้เพื่อเติมเต็มคือฉันสามารถส่งผ่านอินพุตเดียวกันไปยังเอนทิตีหลาย ๆ อย่างเช่นการย้ายเอนทิตีกล้องและผู้เล่นในเวลาเดียวกัน

3
การจัดกลุ่มเอนทิตีของส่วนประกอบเดียวกันที่กำหนดไว้ในหน่วยความจำเชิงเส้น
เราเริ่มต้นจากขั้นพื้นฐานวิธีการระบบส่วนประกอบที่มีหน่วยงาน ขอสร้างassemblages (ระยะที่ได้มาจากนี้บทความ) เพียงออกของข้อมูลเกี่ยวกับชนิดของชิ้นส่วน มันจะทำแบบไดนามิกที่รันไทม์เช่นเดียวกับที่เราจะเพิ่ม / ลบส่วนประกอบไปยังเอนทิตีทีละคน แต่ขอเพียงแค่ตั้งชื่อได้อย่างแม่นยำมากขึ้นเพราะมันเป็นเพียงเกี่ยวกับข้อมูลประเภท แล้วเราจะสร้างหน่วยงานที่ระบุการชุมนุมทุกครั้งของพวกเขา เมื่อเราสร้างเอนทิตีแล้วชุดประกอบของมันจะไม่เปลี่ยนรูปซึ่งหมายความว่าเราไม่สามารถแก้ไขได้โดยตรง แต่ก็ยังสามารถรับลายเซ็นของเอนทิตีที่มีอยู่ไปยังสำเนาภายในเครื่อง (พร้อมกับเนื้อหา) ทำการเปลี่ยนแปลงที่เหมาะสมและสร้างเอนทิตีใหม่ ของมัน ตอนนี้สำหรับแนวคิดหลัก: เมื่อใดก็ตามที่มีการสร้างเอนทิตีมันจะถูกกำหนดให้กับวัตถุที่เรียกว่าbucket bucketlageซึ่งหมายความว่าเอนทิตีทั้งหมดของลายเซ็นเดียวกันจะอยู่ในคอนเทนเนอร์เดียวกัน (เช่นใน std :: vector) ตอนนี้ระบบเพียงทำซ้ำผ่านทุกกลุ่มที่สนใจและทำงานของพวกเขา วิธีนี้มีข้อดีดังนี้ ส่วนประกอบถูกเก็บไว้ในหน่วยความจำที่ต่อเนื่องกันสองสามชิ้น (แม่นยำ: จำนวนถัง) - ช่วยเพิ่มความเป็นมิตรกับหน่วยความจำและง่ายต่อการทิ้งสถานะเกมทั้งหมด ระบบประมวลผลองค์ประกอบในลักษณะเชิงเส้นซึ่งหมายถึงการปรับปรุงการเชื่อมโยงกันแคช - ลาก่อนพจนานุกรมและหน่วยความจำแบบสุ่มกระโดด การสร้างเอนทิตีใหม่นั้นง่ายเหมือนการทำแผนที่ชุดประกอบเพื่อฝากข้อมูลและผลักดันส่วนประกอบที่ต้องการกลับไปยังเวกเตอร์ การลบเอนทิตีเป็นเรื่องง่ายเหมือนกับการเรียก std :: move เพื่อสลับองค์ประกอบสุดท้ายกับอันที่ถูกลบเพราะลำดับไม่สำคัญในตอนนี้ หากเรามีเอนทิตีจำนวนมากที่มีลายเซ็นที่แตกต่างกันโดยสิ้นเชิงประโยชน์ของการเชื่อมโยงกันของแคชลดน้อยลง แต่ฉันไม่คิดว่ามันจะเกิดขึ้นในแอปพลิเคชันส่วนใหญ่ นอกจากนี้ยังมีปัญหาเกี่ยวกับการทำให้ตัวชี้ใช้ไม่ได้เมื่อมีการจัดสรรเวกเตอร์ใหม่ซึ่งสามารถแก้ไขได้โดยการแนะนำโครงสร้างเช่น: struct assemblage_bucket { struct entity_watcher { assemblage_bucket* owner; entity_id real_index_in_vector; …

1
ระบบส่วนประกอบของเอนทิตี - วิธีการใช้การแปลงของวัตถุ?
ในการออกแบบระบบเอนทิตีส่วนประกอบสำหรับเครื่องยนต์ของฉันฉันเจออุปสรรคเล็กน้อยในการจัดเก็บและดึงส่วนประกอบบางประเภท ก่อนอื่นให้ฉันตั้งคำศัพท์เล็กน้อยที่ฉันจะใช้ในคำถามนี้: ฉันเรียกว่า " ส่วนประกอบ " โครงสร้างข้อมูลที่เก็บข้อมูลที่เกี่ยวข้องสำหรับระบบเฉพาะ ฉันเรียกว่า " ระบบ " การรวมวิธีการและโครงสร้างข้อมูลที่ใช้ประโยชน์จากส่วนประกอบเพื่ออัปเดตสถานะเกม / อินเตอร์เฟสกับผู้ใช้ " เอนทิตี " นั้นเป็นเพียง ID ที่ใช้เพื่อดึงส่วนประกอบเฉพาะและแก้ไขข้อมูลในตรรกะของเกม แต่ละระบบมีอาร์เรย์ (ID-mapped) ของประเภทส่วนประกอบ (เช่น Physics-> PhysicsComponent, AI-> AIComponent, Rendering-> RenderingComponent) เพื่อให้สามารถทำซ้ำข้อมูลได้อย่างมีประสิทธิภาพ อย่างไรก็ตามส่วนประกอบทั้งหมดไม่ได้เป็นของระบบโดยเฉพาะ ตัวอย่างเช่นองค์ประกอบการแปลงเก็บตำแหน่งการหมุนและขนาดของวัตถุ เป็นหนึ่งในส่วนที่สำคัญที่สุดของเอนทิตี (Unity ทำให้เป็นข้อบังคับ) แม้จะถูกใช้โดยระบบจำนวนมากเช่น Physics, AI, Rendering เป็นต้น นี่เป็นปัญหาที่ฉันเผชิญอยู่มาก เนื่องจากระบบอื่น ๆ ใช้การแปลงเป็นจำนวนมากฉันจะต้องเรียกใช้เพื่อใช้สำหรับแต่ละคอมโพเนนต์อย่างไร ทางออกหนึ่งที่เป็นไปได้ที่ฉันเห็นคือการทำให้แต่ละ Component เก็บรหัสเอนทิตีของตัวเอง มันจะง่ายต่อการดึงองค์ประกอบใด ๆ …

3
แยกการอ่าน / การคำนวณ / การเขียนอย่างมีประสิทธิภาพสำหรับการประมวลผลพร้อมกันของเอนทิตีในระบบ Entity / Component
ติดตั้ง ฉันมีสถาปัตยกรรมเอนทิตีคอมโพเนนต์ที่เอนทิตีสามารถมีชุดของคุณลักษณะ (ซึ่งเป็นข้อมูลที่บริสุทธิ์โดยไม่มีพฤติกรรม) และมีระบบที่ใช้ตรรกะเอนทิตีซึ่งทำงานกับข้อมูลนั้น เป็นหลักในรหัสหลอกบ้าง: Entity { id; map<id_type, Attribute> attributes; } System { update(); vector<Entity> entities; } ระบบที่เพิ่งเคลื่อนที่ไปตามเอนทิตีทั้งหมดในอัตราคงที่อาจเป็น MovementSystem extends System { update() { for each entity in entities position = entity.attributes["position"]; position += vec3(1,1,1); } } เป็นหลักฉันพยายามขนาน update () อย่างมีประสิทธิภาพที่สุด สิ่งนี้สามารถทำได้โดยการรันทั้งระบบในแบบคู่ขนานหรือโดยการให้แต่ละการอัปเดต () ของระบบหนึ่งมีส่วนประกอบสองส่วนเพื่อให้เธรดที่แตกต่างกันสามารถดำเนินการอัปเดตระบบเดียวกันได้ แต่สำหรับชุดย่อยอื่น ปัญหา ในกรณีของระบบการเคลื่อนไหวที่แสดงการขนานกันนั้นเป็นเรื่องเล็กน้อย เนื่องจากเอนทิตีไม่ได้พึ่งพาซึ่งกันและกันและไม่แก้ไขข้อมูลที่แชร์เราจึงสามารถย้ายเอนทิตีทั้งหมดในแบบคู่ขนาน อย่างไรก็ตามบางครั้งระบบเหล่านี้ต้องการให้เอนทิตีโต้ตอบกับ …

2
การจัดการส่วนประกอบที่เขียนสคริปต์และ "ดั้งเดิม" ในระบบเอนทิตีที่อิงองค์ประกอบ
ขณะนี้ฉันกำลังพยายามใช้ระบบเอนทิตีที่อิงองค์ประกอบเป็นหลักโดยที่เอนทิตีนั้นเป็นเพียง ID และวิธีการช่วยเหลือบางอย่างที่ผูกส่วนประกอบหลายอย่างเข้าด้วยกันเพื่อสร้างวัตถุเกม เป้าหมายบางประการของที่รวมถึง: ส่วนประกอบประกอบด้วยสถานะ (เช่นตำแหน่งสุขภาพจำนวนกระสุน) => ตรรกะเข้าสู่ "ระบบ" ซึ่งดำเนินการส่วนประกอบเหล่านี้และสถานะของพวกเขา (เช่น PhysicsSystem, RenderSystem ฯลฯ ) ฉันต้องการใช้ส่วนประกอบและระบบทั้งใน C # และผ่านการเขียนสคริปต์ (Lua) โดยทั่วไปฉันต้องการที่จะสามารถกำหนดส่วนประกอบและระบบใหม่ทั้งหมดใน Lua ได้โดยตรงโดยไม่ต้องคอมไพล์ต้นฉบับ C # ของฉันอีกครั้ง ตอนนี้ฉันกำลังมองหาแนวคิดเกี่ยวกับวิธีจัดการสิ่งนี้อย่างมีประสิทธิภาพและไม่สม่ำเสมอดังนั้นฉันไม่จำเป็นต้องใช้ไวยากรณ์ที่แตกต่างเพื่อเข้าถึงคอมโพเนนต์ C # หรือส่วนประกอบ Lua ตัวอย่างเช่น แนวทางปัจจุบันของฉันคือการใช้ส่วนประกอบ C # โดยใช้คุณสมบัติสาธารณะทั่วไปอาจตกแต่งด้วยแอตทริบิวต์บางอย่างที่บอกบรรณาธิการเกี่ยวกับค่าเริ่มต้นและเนื้อหา จากนั้นฉันจะมี "ScriptComponent" ระดับ C ซึ่งเพิ่งล้อมตาราง Lua ภายในด้วยตารางนี้ถูกสร้างขึ้นโดยสคริปต์และเก็บสถานะทั้งหมดของประเภทองค์ประกอบเฉพาะนั้น ฉันไม่ต้องการเข้าถึงสถานะดังกล่าวจากด้าน C # มากเท่าที่ฉันจะไม่ทราบในเวลารวบรวมสิ่งที่ ScriptComponents พร้อมกับคุณสมบัติใดบ้างที่จะมีให้ฉัน ถึงกระนั้นผู้แก้ไขจะต้องเข้าใช้งาน …

5
เหตุใดจึงต้องวางเอนทิตี config นอกสคริปต์?
ฉันเห็นเกมจำนวนมากที่กำหนดองค์ประกอบเอนทิตีในไฟล์สคริปต์ แต่เมื่อพวกเขากำหนดค่าแต่ละเอนทิตีและระบุว่ามีองค์ประกอบใดพวกเขาใช้รูปแบบไฟล์อื่น (เช่น XML) ทำไมพวกเขาทำอย่างนั้น? ฉันขอให้ส่วนใหญ่ดูว่าเหตุผลของคนอื่นคืออะไรสำหรับเรื่องนี้ ฉันยังกำหนดค่าเอนทิตีของฉันนอกสคริปต์ (แม้ว่าฉันเลือก JSON ไม่ใช่ XML) เหตุผลของฉันในการทำเช่นนี้คือทำให้ฉันง่ายต่อการใช้เกมบันทึกและเพราะฉันคิดว่าการกำหนดค่าประเภทนี้จัดระเบียบได้ดีกว่าในสิ่งที่ชอบ XML หรือ JSON คำตอบของ @ Christopher Larsenยาวเกินกว่าจะโพสต์เป็นความคิดเห็น ฉันกลัวว่าคุณอาจเบี่ยงเบนไปเล็กน้อยจากเรื่องของคำถาม ปัญหาที่คุณกำลังอธิบายเกี่ยวข้องกับหน่วยงานที่ใช้ลำดับชั้นมากกว่า ในคำถามของฉันฉันพูดถึงฉันกำลังพูดถึงเอนทิตีที่อิงองค์ประกอบ นี่คือตัวอย่างของสิ่งที่ฉันต้องการถาม ด้านล่างมีสองทางเลือกในการกำหนดค่าเอนทิตี: ผ่านสคริปต์และผ่านไฟล์ JSON ภายนอก คำถามของฉันคือทำไมผู้คนจำนวนมากต้องการกำหนดเอนทิตีนอกสคริปต์? คลาสเอนทิตีฐาน: class Entity: def __init__(self, name): pass def addComponent(self, comp): pass วิธีการสคริปต์: orc = Entity('Orc') orc.addComponent(PositionComponent(3.4, 7.9)) วิธีการ JSON: { "name" : …

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