การหลีกเลี่ยง RTS ในพื้นที่กระทำได้อย่างไร


15

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

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

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

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

โซลูชันที่ฉันกำลังมองหาต้องการตอบสนองความต้องการดังต่อไปนี้ (เช่นเดียวกับ Starcraft 2):

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

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


"พฤติกรรม flocking" (คำ google) เป็นปัญหาที่กว้างมาก
วงล้อประหลาด

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

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

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

นี่เป็นแหล่งข้อมูลที่ยอดเยี่ยม: red3d.com/cwr/steer
tbkn23

คำตอบ:


11

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

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

ตอนนี้ทำการจำลอง:

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

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

สำหรับการคำนวณอัลกอริธึมสองขั้นตอนข้างต้นคุณสามารถใช้ Minkowski Sums เพื่อกำหนดว่าสิ่งกีดขวางทางความเร็วคืออะไรแล้วใช้โมเดลการเขียนโปรแกรมเชิงเส้น (เช่นอัลกอริทึม Simplex ) เพื่อกำหนดจุดที่ใกล้เคียงที่สุดเพื่อv_pหลีกเลี่ยงอุปสรรคความเร็ว นอกจากนี้สำหรับการทำเช่นหลีกเลี่ยงการชนกันสามารถใช้ได้สำหรับการตรวจของคุณและได้รับการ ported C # จะใช้ในเครื่องยนต์เกมเช่นความสามัคคี เทคนิคนี้ได้ถูกนำมาใช้อย่างน้อยในWarhammer 40,000: พื้นที่ทางทะเลและบางทีเกมอื่น


นั่นเป็นบทความที่น่าอัศจรรย์และฉันรู้สึกว่าฉันได้อ่านบทความครึ่งหนึ่งจากคำอธิบายของคุณ ขอบคุณสำหรับข้อมูลนี้
JPtheK9

0

ฉันไม่ทราบว่าหน่วยของคุณทำงานอย่างไร แต่ฉันคิดว่ามันเป็นเหมือนเครื่องรัฐ:

สถานะที่เป็นไปได้

  • วิ่งไปที่ (x, y, z)
  • การเข้าร่วม (ศัตรู _id)
  • กำลังรวบรวม ressource (ressource_id)

หากคุณให้ความสนใจว่าสตาร์คราฟต์เข้าถึงปัญหานี้อย่างไรคุณจะพบว่า:

  1. หากมีพื้นที่ว่างที่จะเคลื่อนที่ไปในทิศทางที่ charachter เคลื่อนที่ไปในทิศทางนั้น
  2. หากไม่มีที่ว่างหน่วยในทางจะย้ายเพื่อให้มีพื้นที่
  3. หากหน่วยที่ต้องการย้ายเพื่อให้มีพื้นที่ว่างอยู่แล้วมีคำสั่งอยู่ก็จะเก็บคำสั่งไว้ แต่ปรับเปลี่ยนเล็กน้อยเพื่อให้เกิดขึ้นในที่สุด

ที่นี่สถานการณ์ 1:

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

ฉันมีที่ว่างให้ไปที่นั่นไหม? ใช่ไหม จากนั้นไป

สถานการณ์ที่ 2:

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

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

ดังนั้นสิ่งที่คุณจะต้องใช้:

  • หน่วยจะต้องตระหนักถึงสภาพแวดล้อมของพวกเขา
  • หน่วยจะต้องมีวิธีการสื่อสารซึ่งกันและกัน
  • คุณต้องใช้วิธีในการดำเนินการคำสั่งในขณะที่รวมหน่วยอื่น

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

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

คุณหมายความว่าอย่างไรเมื่อ "เคลื่อนที่จนกว่ามันจะออกนอกทาง"? หน่วยเคลื่อนที่อย่างไรในตอนแรก?
JPtheK9

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

0

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

ต่อไปนี้เป็นวิธีพื้นฐานในการทำโดยใช้การสร้างกล่องและสปริงแบบง่าย ๆ เพื่อให้หน่วยอยู่ในตำแหน่งที่เหมาะสม:

// Defines a phalanx (box) formation
class Formation
    // Center of the box in the world
    Position center;
    // Width in # of units
    int width;
    // Height in # of units
    int height;
    // Space between units
    float scale;
    // How much force units will apply to stay near
    // their assigned spot.
    float springforce;

    // Return a position of a unit at the given row and column
    // Todo: add a rotation to this formation so it can rotate when moving.
    Position GetUnitPhalanxPosition(int row, int column)
        return new Position(center.X + column * scale - width * scale /2, 
                            center.Y + row * scale    - height* scale / 2);

// Represents a simple point object with a velocity and position;
// it belongs to a formation.
class Unit
    Position pos;
    Velocity vel;
    Formation formation;
    // What's our assigned spot in the formation?
    int row;
    int column;

    void Update(float dt)
        // Get the desired target position in the formation
        Position target = formation.GetUnitPhalanxPosition(row, column);
        // Apply a spring force toward the position (todo: you might want to damp this)
        vel += (target - position) * dt * formation.springforce;
        // Move along the velocity vector.
        pos += vel * dt;

ขอบคุณ! นี่เป็นทางออกที่น่าสนใจและสร้างสรรค์ ฉันใช้สิ่งนี้คล้ายกับพฤติกรรมฝูงชน / การก่อตัว แต่ฉันยังคงมีปัญหาการทับซ้อนของหน่วย จะเกิดอะไรขึ้นถ้า 2 การก่อตัวเกิดขึ้นพร้อมกัน?
JPtheK9

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

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

ฉันมีปัญหาที่คล้ายกันกับคุณจะน่าสนใจที่จะรู้ว่าคุณแก้ปัญหาได้อย่างไร แนวคิดหนึ่งช็อตมาถึงใจหลังจากอ่านบทความนี้: อาจรวม Pathfinding (A *) สำหรับการวางแผนพา ธ มาโครในขณะที่ใช้กำลัง reppel สำหรับการหลีกเลี่ยงการชนขนาดเล็ก:
ColdSteel

0

ฉันรู้ว่าบางคนหน้าบึ้งในการถ่ายโอนข้อมูลลิงก์ แต่ฉันพบวิธีการแบบหลายฟิลด์ที่ใช้ศักยภาพสำหรับบอตเกมกลยุทธ์แบบเรียลไทม์ (ไอ 978-91-7295-160-0) เป็นกระดาษที่มีความสว่างมากและเห็นได้ชัดว่าสื่อถึง ทางที่มากกว่าที่ฉันจะทำอย่างละเอียด กระดาษสำรวจโดยใช้เขตข้อมูลที่มีศักยภาพเทียม (แนวคิดที่มาจากหุ่นยนต์) เพื่ออำนวยความสะดวกในการหลีกเลี่ยงการชนกันภายในบริบทการพัฒนาเกม


ขอบคุณ! การวิจัยมีประโยชน์เช่นเดียวกับคำอธิบายสำหรับฉัน ฉันจะดำดิ่งลงในกระดาษนี้
JPtheK9

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