wake-up-neo.net

Wie kann man verhindern, dass Collider sich gegenseitig passieren?

Ich habe Probleme, Spielobjekte in einem geschlossenen Raum zu halten. Wenn sie den Rand erreichen, gibt es ein kurzes Drücken, aber dann gehen sie direkt durch die Wand.

Ich verwende einen Box-Collider für den Player und einen Mesh-Collider für die Wand des Levels. Ich habe Probleme mit einem Spielercharakter (einem Raumschiff), dass die Bewegung vom Spieler gesteuert wird. Und mit Geschossen, die feuern und die Bewegung mit konstanter Geschwindigkeit vergessen.

Dies ist mein Bewegungscode für meinen Spieler. Es wird in der Funktion FixedUpdate() ausgeführt.

//Movement
    haxis = Input.GetAxis("Horizontal") * speed;
    vaxis = Input.GetAxis("Vertical") * speed;

    moveVector.x = haxis;
    moveVector.z = vaxis;

    if(moveVector.magnitude > 1)
    {
        moveVector.Normalize();
    }

    rigidbody.MovePosition(transform.position + moveVector * speed);

Mit den Kugeln wird ihnen eine Geschwindigkeit gegeben und der Motor berechnet ihre Bewegungen. Sie verwenden Box Collider und sind als Auslöser festgelegt, sodass sie keine Physik haben. Aber ich benutze OnTriggerEnter, um sie zu vernichten.

//Projectiles without physics collisiions
function OnTriggerEnter (other : Collider) {
    Destroy(gameObject);
}

Einige, aber nicht alle Kugeln werden beim Auftreffen auf die Gittermauer zerstört. Der Spieler schlägt es manchmal und stoppt, kann es aber normalerweise durchdrücken. Wie kann ich die Kollisionen mit dem Mesh Collider jedes Mal funktionieren lassen?

13
Chris

Die Kollision mit sich schnell bewegenden Objekten ist immer ein Problem. Um sicherzustellen, dass Sie alle Kollisionen erkennen, sollten Sie Raycasting verwenden, anstatt sich auf die Physik-Simulation zu verlassen. Dies funktioniert gut für Aufzählungszeichen oder kleine Objekte, liefert jedoch keine guten Ergebnisse für große Objekte . http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html

Pseudocodeish (Ich habe hier keinen Code-Abschluss und einen schlechten Speicher):

void FixedUpdate()
{
    Vector3 direction = new Vector3(transform.position - lastPosition);
    Ray ray = new Ray(lastPosition, direction);
    RaycastHit hit;
    if (Physics.Raycast(ray, hit, direction.magnitude))
    {
        // Do something if hit
    }

    this.lastPosition = transform.position;
}
10
Petrucio

Ich habe einen Flipper-Prototyp, der mir in den gleichen Bereichen auch viel Ärger bereitet hat. Dies sind alle Schritte, die ich unternommen habe, um diese Probleme (aber noch nicht vollständig) zu lösen:

Für sich schnell bewegende Objekte:

  • Setzen Sie Interpolate für den Rigidbody auf 'Interpolate' (dies wirkt sich nicht auf die tatsächliche Physiksimulation aus, aktualisiert jedoch das Rendern des Objekts ordnungsgemäß. Verwenden Sie dies nur für wichtige Objekte aus der Sicht des Renderns, z. B. des Players oder eines Flippers, jedoch nicht.) für Geschosse)

  • Setzen Sie die Kollisionserkennung auf Continuous Dynamic

  • Hängen Sie das Skript DontGoThroughThings ( https://www.auto.tuwien.ac.at/wordpress/?p=260 ) an Ihr Objekt an. In diesem Skript wird die Raycasting-Lösung, die ich in meiner anderen Antwort gepostet habe, geschickt verwendet, um beleidigende Objekte auf die Kollisionspunkte zurückzubringen.

In Bearbeiten -> Projekteinstellungen -> Physik :

  • Stellen Sie Min Penetration for Penalty auf einen sehr niedrigen Wert ein. Ich habe meine auf 0,001 gesetzt

  • Setzen Sie den Solver-Iterationszähler auf einen höheren Wert. Ich habe meins auf 50 eingestellt, aber Sie können wahrscheinlich mit viel weniger gut auskommen.

Das alles wird eine Strafe für die Performance haben, aber das ist unvermeidlich. Die Standardwerte sind weich in Bezug auf die Leistung, sind jedoch nicht für die korrekte Simulation von kleinen und sich schnell bewegenden Objekten gedacht.

12
Petrucio

Wie wäre es mit der Kollisionserkennung von starren Körpern auf Continuous oder Continuous Dynamic zu setzen?

http://unity3d.com/support/documentation/Components/class-Rigidbody.html

6
Chchwy
  • Bearbeiten ---> Projekteinstellungen ---> Zeit ... verringern Sie den Wert für "Festen Zeitschritt". Dadurch wird das Problem gelöst, die Leistung kann jedoch beeinträchtigt werden.

  • Eine andere Lösung wäre, die Koordinaten zu berechnen (z. B. haben Sie einen Ball und eine Wand. Der Ball wird gegen die Wand schlagen. Berechnen Sie also die Wandkoordinaten und setzen Sie den Schlagvorgang entsprechend diesen Koordinaten.)

1
fmp

Also konnte ich die Mesh Colliders nicht zum Laufen bringen. Ich habe einen Composite-Collider mit einfachen Box-Collidern erstellt und er hat genau wie erwartet funktioniert.

Andere Tests mit einfachen Mesh-Collidern haben sich ebenfalls bewährt.

Es scheint, dass die beste Antwort darin besteht, einen zusammengesetzten Collider aus einfachen Box-/Kugel-Collidern zu erstellen.

Für meinen speziellen Fall habe ich einen Wizard geschrieben, der einen Pipe-förmigen Compound-Collider erstellt.

@script AddComponentMenu("Colliders/Pipe Collider");
class WizardCreatePipeCollider extends ScriptableWizard
{
    public var outterRadius : float = 200;
    public var innerRadius : float = 190;
    public var sections : int = 12;
    public var height : float = 20;

    @MenuItem("GameObject/Colliders/Create Pipe Collider")
    static function CreateWizard()
    {
        ScriptableWizard.DisplayWizard.<WizardCreatePipeCollider>("Create Pipe Collider");
    }

    public function OnWizardUpdate() {
        helpString = "Creates a Pipe Collider";
    }

    public function OnWizardCreate() {
        var theta : float = 360f / sections;
        var width : float = outterRadius - innerRadius;

        var sectionLength : float = 2 * outterRadius * Mathf.Sin((theta / 2) * Mathf.Deg2Rad);

        var container : GameObject = new GameObject("Pipe Collider");
        var section : GameObject;
        var sectionCollider : GameObject;
        var boxCollider : BoxCollider;

        for(var i = 0; i < sections; i++)
        {
            section = new GameObject("Section " + (i + 1));

            sectionCollider = new GameObject("SectionCollider " + (i + 1));
            section.transform.parent = container.transform;
            sectionCollider.transform.parent = section.transform;

            section.transform.localPosition = Vector3.zero;
            section.transform.localRotation.eulerAngles.y = i * theta;

            boxCollider = sectionCollider.AddComponent.<BoxCollider>();
            boxCollider.center = Vector3.zero;
            boxCollider.size = new Vector3(width, height, sectionLength);

            sectionCollider.transform.localPosition = new Vector3(innerRadius + (width / 2), 0, 0);
        }
    }
}
1
Chris

Alte Frage aber vielleicht hilft es jemandem.

Gehen Sie zu Projekteinstellungen> Zeit und teilen Sie den festen Zeitschritt und den maximal zulässigen Zeitschritt durch zwei oder vier.

Ich hatte das Problem, dass mein Spieler in der Lage war, kleinere Öffnungen als den Spieler-Collider zu durchdringen, und das hat ihn gelöst. Es hilft auch, sich schnell bewegende Objekte zu stoppen.

0
Timanious

1.) Verwenden Sie niemals MESH COLLIDER. Verwenden Sie eine Kombination aus Box und Capsule Collider.

2.) Prüfen Sie die Einschränkungen in RigidBody. Wenn Sie die Freeze-Position X ankreuzen, wird das Objekt auf der X-Achse durchlaufen. (Gleiches für y-Achse). 

0
Simran Singh