Kollision: An der Wand entlang gleiten



  • Hi,
    zur Zeit habe ich folgenden Code:

    ///Content Load///
                bbLevel = new BoundingBox[] {
                    new BoundingBox(new Vector3(1391, -532, -2980), new Vector3(1432, 531, 3186)),
                    new BoundingBox( new Vector3(-1450,-532,-2980), new Vector3(-1409,531,3186) )
                };
    //////////////////
    
    /////Update/////
    
                PlayerQRot = Quaternion.CreateFromAxisAngle(Vector3.Up,
                                MathHelper.ToRadians(PlayerRotY));
                PlayerPos += Vector3.Transform(PlayerVel, Matrix.CreateFromQuaternion(gcvQRot));
    
                BoundingBox bbPlayer = new BoundingBox(new Vector3(-1,-1,-1) + gcvPos,
                                        new Vector3(0,0,0) + PlayerPos);
                foreach (BoundingBox bb in bbLevel)
                {
                    if (bbPlayer.Intersects(bb))
                    {
                        PlayerPos -= Vector3.Transform(PlayerVel, Matrix.CreateFromQuaternion(PlayerQRot));
                    }
                }
    //////////////////
    
    /////Draw////////
                view = Matrix.CreateLookAt(PlayerPos + Vector3.Transform(new Vector3(-80, 200, -200), Matrix.CreateFromQuaternion(PlayerQRot)),
                               PaylerPos + Vector3.Transform(new Vector3(-80, 100, 200), Matrix.CreateFromQuaternion(PlayerQRot)),
                               Vector3.Up);
    ////////////////
    

    Die Kollisionserkennung funktioniert, nun soll der Player aber an der Wand entlang gleiten.
    Was muss ich jetzt machen, die BoundingBox soweit zurücksetzen dass es keine Kollision mehr gibt? Beim stöbern im Internet bin ich auf so eine Bedingung gestoßen, ist das eine Lösung?

    if (bbGCV.Max.Z >= bb.Max.Z)
                        {
                            bbGCV.Max.Z = bb.Max.Z + irgendwas;
                        }
                        else if (bbGCV.Max.Z <= bb.Max.Z)
                        {
                            bbGCV.Max.Z = bb.Max.Z - Irgendwas;
                        }
    

    Wenn ja müsste ich dieses hier ja irgendwie ändern oder?

    PlayerPos -= Vector3.Transform(PlayerVel, Matrix.CreateFromQuaternion(PlayerQRot));
    

    ]hier etwas zur BoundingBox:

    BoundingBox  Creates an instance of BoundingBox. 
    
    Public Fields
    --------------------------------------------------------------------------------
    
     Name Description 
      CornerCount  Specifies the total number of corners (8) in the BoundingBox. 
      Max  The maximum point the BoundingBox contains. 
      Min  The minimum point the BoundingBox contains.  
    
    Public Methods
    --------------------------------------------------------------------------------
    
     Name Description 
      Contains  Overloaded. Tests whether the BoundingBox overlaps another bounding volume. 
      CreateFromPoints  Creates the smallest BoundingBox that will contain a group of points. 
      CreateFromSphere  Overloaded. Creates the smallest BoundingBox that will contain the specified BoundingSphere.  
      CreateMerged  Overloaded. Creates the smallest BoundingBox that contains the two specified BoundingBox instances.  
      Equals  Overloaded. Determines whether two instances of BoundingBox are equal.  
      GetCorners  Overloaded. Gets an array of points that make up the corners of the BoundingBox. 
      GetHashCode  Gets the hash code for this instance. 
      GetType  (Inherited from Object.) 
      Intersects  Overloaded. Checks whether the current BoundingBox intersects with another bounding volume. 
      op_Equality  Determines whether two instances of BoundingBox are equal.  
      op_Inequality  Determines whether two instances of BoundingBox are not equal.  
      ToString  Returns a String that represents the current BoundingBox.  
    
    Protected Methods
    --------------------------------------------------------------------------------
    
     Name Description 
      Finalize  (Inherited from Object.) 
      MemberwiseClone  (Inherited from Object.)
    

    oder hierhttp://msdn.microsoft.com/en-us/library/microsoft.xna.framework.boundingbox_members.aspx



  • Das Problem ist, das hierauf die Antwort gar nicht so leicht ist, zumindest nicht mit den gegeben Mitteln. Im Prinzip müsstest du mindestens die Flächenormale der Fläche des Würfels wissen... Am besten noch die Eintauchtiefe, aber die bekommt man näherungsweise ineffizient auch über schrittweise unterteilung der bewegung, die zur Kollision führte mit dem anschließenden Test auf Kollision. Ich habe den Eindruck, dass diese Klassen nur dem schnellen Aussortieren beim Rendern dienen sollen, nicht der wirklichen Behandlung von Kollisionen.



  • mhhh ok, da sollte die vector Klasse weiterhelfen denk ich.

    http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector3_members.aspx



  • Späte Antwort, aber du müsstest jede einzelne Komponente auf Kollision überprüfen und nur die neue Komponente übernehmen, die keine Kollision erzeugt.
    Beispiel:

    // gegeben:
    Vector3 Position;
    Vector3 NewPosition;
    Vector3 TestPosition;
    
    BoundingBox.Position = Position;
    BoundingBox.Position.x = NewPosition.x;
    if(!BoundingBox.intersects(World)) Position.x = NewPosition.x;
    
    BoundingBox.Position = Position;
    BoundingBox.Position.y = NewPosition.y;
    if(!BoundingBox.intersects(World)) Position.y = NewPosition.y;
    
    BoundingBox.Position = Position;
    BoundingBox.Position.z = NewPosition.z;
    if(!BoundingBox.intersects(World)) Position.z = NewPosition.z;
    

    Ich hoffe das löst dein Problem.


Anmelden zum Antworten