MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Chimorin »

Guten Abend,

wie der Titel schon verrät, habe ich neuerdings Probleme mit MoveEntity(). Wenn ich als Flag #PB_Relative verwende und Physik im Sinne eines Physikkörpers ins Spiel kommt, spackt mein Entity voll ab, platt gesagt. Alle Typen (außer StaticBody und ConvexHullBody) führen dazu, dass mein Entity durch das Terrain ins Bodenlose stürzt.
Die beiden Typen, die funktionieren, funktionieren nicht richtig, da dann MoveEntity() nicht mehr funktioniert :D
Jetzt meine Frage, da ich leider kein Programm posten kann (Die Examples funktionieren ja komischerweise -.- und meins hat ~3000Zeilen), hoffe ich darauf, dass jemand das schon mal passiert ist:
Was hast du gemacht, als das passiert ist? Gibt es eine Lösung?
Fällt dir an meiner Fehlerbeschreibung was auf, was irgendwie verdächtig nach FAQ-Fehler klingt?
Wäre ja schön, wenn es nur am Mesh liegen würde... Hat jemand ein getestetes parat?

Ich bin am Verzweifeln... Ohne Physikbody funktioniert alles super, mit ist es beknackt. Ich hab da viel Zeit und Herzblut reingesteckt und es wäre super, wenn jemand mir helfen könnte :)

EDIT: Ich habe mich bei der Charakter"erstellung" genau an das Example "FPS First Person Shooter" gehalten.
Zuletzt geändert von Chimorin am 09.10.2013 17:51, insgesamt 1-mal geändert.
Bild

- formerly known as Bananenfreak -
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von STARGÅTE »

Wenn Physik im Spiel ist, solltest du ApplyEntityForce() und ApplyEntityImpulse() nutzen um das Entity zu bewegen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Chimorin »

Ok, werde ich ausprobieren.
Hast du eine Idee, was das für ein komischer Fehler mit dem durch den Boden fallen ist?
Bild

- formerly known as Bananenfreak -
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Chimorin »

ApplyEntityImpulse() geht, danke schön ^^
Sieht aber bescheiden aus, ich denke, ich werde das noch irgendwie ändern.

Was ich komisch finde ist, dass der Ersteller des Beispiels "FPSFirstPerson" dem Entity, das bewegt wird, einen Physikkörper zugewiesen hat und es trotzdem ganz normal bewegen kann...

Ich glaube, ich kann wenigstens das Problem mit dem Herunterfallen lösen:
Weiß jemand von euch, ob der Bezugspunkt des Entities (Im Editorprogramm der Ursprung der 3 Achsen) auch als Massepunkt gilt?
Ich setze meine Entities nämlich immer so, dass ich diese im Programm durch einfache Ortsangaben positionieren kann (Ein Baum aus mehreren Teilen: Äste, Stamm, Blätter,... hat einen gemeinsamen Bezugspunkt), was bedeutet, dass dieser Bezugspunkt bei meiner Figur mit ihr unten abschließt, bzw. er ist in der Mitte, aber unter den Füßen.

EDIT: Daran liegt es nicht. Der Roboter hat genau so seinen Mittelpunkt unter den Füßen.
Bild

- formerly known as Bananenfreak -
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Chimorin »

Super. Ich habe mir gedacht: "Da gibt es doch das TerrainPhysc.pb - Example". Was haben die gemacht? 2 Entities erstellt. Das Eine mit der Physik schwebt komischerweise, während das Andere, das für die Animation zuständig ist, nicht schwebt. :?
Ich lasse es glaube ich für heute und schau mir das morgen wieder an.
Bild

- formerly known as Bananenfreak -
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Chimorin »

Ich habe es jetzt mal mit dem Robotermesh probiert, immer noch das selbe Ergebnis.
Hier mal ein bisschen Code, fällt jemandem irgendetwas auf?

Code: Alles auswählen

With spieler
  \augenHoehe = 2
  \masse = 2
  \bodyEnt = CreateEntity(#PB_Any, MeshID(LoadMesh(#PB_Any, "robot.mesh")), 
                          #PB_Material_None, 
                          50, 
                          TerrainHeight(terrain(TerrainTile(5, weltGroesse, #G_Welt), TerrainTile(5, weltGroesse, #G_Welt))\terrainNr, 5, 5),
                          50)
  ScaleEntity(\bodyEnt, 0.04, 0.04, 0.04, #PB_Relative)
  EntityPhysicBody(\bodyEnt, #PB_Entity_StaticBody, \masse, 1, 0)
  
  MoveCamera(#Kamera_0, 0, 0, 0, #PB_Absolute)
  AddBillboard(0, #Bill_Kreuz, 0.1, 0, 0)
  
  \hauptnode = CreateNode(#PB_Any, EntityX(\bodyEnt), EntityY(\bodyEnt), EntityZ(\bodyEnt))        ;Die Hauptgruppe
  \kameranode = CreateNode(#PB_Any, 0, \augenHoehe, 0)       ;Die Kamera- und Zielkreuzgruppe
  \vornode = CreateNode(#PB_Any, 1, 0, 0)          ;Die Vorwaertsgruppe ist zuständig für die Vorwärts- und Rückwärtsbewegung (Vor dem Spieler)
  \seitnode = CreateNode(#PB_Any, 0, 0, -1)         ;Die Seitwärtsgruppe ist zuständig für die Seitwärtsbewegungen (Links vom Spieler)
  
  NodeLookAt(\kameraNode, -NodeX(\vornode) * 100, NodeY(\kameranode), 0)
  
  AttachNodeObject(\hauptnode, NodeID(\kameranode))        ;Fügt der Hauptnode die Kameranode als Untergeordnete hinzu.  
  AttachNodeObject(\hauptnode, NodeID(\vornode))         ;Fügt der Hauptnode die Kreuznode als Untergeordnete hinzu.
  AttachNodeObject(\hauptnode, NodeID(\seitnode))         ;Fügt der Hauptnode die Kreuznode als Untergeordnete hinzu.
  AttachNodeObject(\kameraNode, BillboardGroupID(#Bill_Kreuz))        ;Fügt der Kameranode die Kreuzbillboardgruppe als Untergeordnerte hinzu.
  AttachNodeObject(\kameraNode, CameraID(#Kamera_0))        ;Fügt der Kameranode die Kamera als Untergeordnete hinzu.
  
  CameraDirection(#Kamera_0, NodeX(\vornode) * 100, NodeY(\kameranode), 0);-NodeX(\vornode) * 100
EndWith

Code: Alles auswählen

MoveEntity(\bodyEnt, trans\x + trans2\x, trans\y + trans2\y, trans\z + trans2\z, #PB_Relative)
    ;MoveEntity(\bodyEnt, EntityX(\bodyEnt) + trans\x + trans2\x, EntityY(\bodyEnt) + trans\y + trans2\y, EntityZ(\bodyEnt) + trans\z + trans2\z, #PB_Absolute)
    ;ApplyEntityImpulse(\bodyEnt, \masse * (trans\x + trans2\x), 0, \masse * (trans\z + trans2\z))
       MoveNode(\hauptNode, EntityX(\bodyEnt), EntityY(\bodyEnt), EntityZ(\bodyEnt), #PB_Absolute)
Das Rotieren und die Vektorrechnung,... funktioniert richtig, hier müsste der Fehler drin stecken.
Wie gesagt: Wenn ich dem Roboter ein Kapsel, Kugel,... Körper gebe, verhält er sich wie eine Kugel (Ich denke, das soll so sein). Das relative Bewegen geht in jedem Fall nicht mehr.
Mir geht es in erster Linie beim Physikkörper nur darum, dass die Kollisionen überprüft werden (Soll ja ein Spiel sein, also wenn auf den Spieler geschossen wird, sollen die Kugeln nicht durchfliegen :D). Kann man das auch anders realisieren (Wenn es sein muss auch mit 2 Entities)?
Ich hätte da eine Idee: Ich nehme das eine als Bewegungsentity, das wird relativ bewegt und animiert. Das 2. Entity ist unsichtbar und wird auch animiert, aber bekommt den Physikkörper und wird "nachgezogen".
Problem: Könnte ich so nicht aus Versehen durch andere Meshes durchsausen, weil das Physikentity nur nachgezogen wird?
Bild

- formerly known as Bananenfreak -
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Chimorin »

Ich glaube, ich habe es gefunden. Dieses Stückchen Code müsste doch anspringen, wenn mein Entity NICHT aktiv ist (Ja, das tut es):

Code: Alles auswählen

If Not GetEntityAttribute(\bodyEnt, #PB_Entity_IsActive)
      Debug "1"
    EndIf
Nächste Frage: Kann ich das irgendwie verhindern? Einfach aktiv setzen geht nicht, wie kann ich das sonst machen?
Unter SetEntityAttribute() gibt's das hier:
#PB_Entity_LinearSleeping : Ändert den minimalen linearen Geschwindigkeitswert, unter dem das Entity-Objekt "schlafen" wird.
#PB_Entity_AngularSleeping : Ändert den minimalen Winkel-Geschwindigkeitswert, unter dem das Entity-Objekt "schlafen" wird.
#PB_Entity_DeactivationTime : Zu wartende Zeit (in Millisekunden), bevor das Entity-Objekt in den Ruhezustand ("Schlaf-Modus")
versetzt wird, wenn die vorgenannten Bedingungen zutreffen.
Die ersten Beiden auf 0 und das Letzte ignorieren?
Ich bitte um Hlfe :praise:
Bild

- formerly known as Bananenfreak -
Benutzeravatar
Makke
Beiträge: 156
Registriert: 24.08.2011 18:00
Computerausstattung: AMD Ryzen 7 5700X - AMD Radeon RX 6800 XT - 32 GB DDR4 SDRAM
Wohnort: Ruhrpott
Kontaktdaten:

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Makke »

HI Banane,

also, ich habe mal ein kleinen Test gemacht mit Programmteilen die ich zu 5.11 Zeiten benutzt habe. Dort war die relative Entity Bewegung mit eingeschalteter Physik und Kollisionen definitv möglich. Jetzt mit 5.20 nicht mehr.

Ich habe mich doch sehr gewundert.

Ich versuche mal war kurzes zu schreiben und hier zu posten. Im Moment würde ich sagen Bug oder undokumentiertes Feature ... wenn ich wieder etwas Zeit habe poste ich mal etwas Code.
---
Windows 11 (64 bit)
Benutzeravatar
Makke
Beiträge: 156
Registriert: 24.08.2011 18:00
Computerausstattung: AMD Ryzen 7 5700X - AMD Radeon RX 6800 XT - 32 GB DDR4 SDRAM
Wohnort: Ruhrpott
Kontaktdaten:

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Makke »

So,

habe mal das Beispiel bei den 3D-Demos ausprobiert. Da funktioniert die relative Bewegung, sehr komisch. Aber der Spieler schwebt dauerhaft, er fällt also nicht mehr hinuter. Irgendwie scheint da einiges nicht mehr richtig zu sein. Ich teste weiter. Ich hatte ein Beispiel fast wie das 3D-FPS-Demo gemacht, aber da geht die relative Bewegung nicht. sehr merkwürdig.

Code: Alles auswählen

EnableExplicit

#MINFPS = 30

#PLAYER_SIZE = 1.8
#CAMERA_DIST = 8

#SCALE_WALK = 1.0
#SCALE_RUN  = 1.4
#SCALE_TURN = 0.1

Structure fVector3
  x.f
  y.f
  z.f
EndStructure

Structure structKeysettings
  forward.i
  backward.i
  turnLeft.i
  turnRight.i
  strafeLeft.i
  strafeRight.i
  run.i
EndStructure

Structure structPlayer
  init.b
  Keys.structKeysettings
  Rotate.fVector3
  Move.fVector3
  entity.i
  camera.i
  bbCross.i
  nodeMain.i
  nodeForward.i
  nodeStrafe.i
  nodeCamera.i
EndStructure

Structure structLevel
  floor.i
  grass.i
  Array houses.i(25)
EndStructure

Define.b            DoLoop = #True
Define.f            TimeSinceLastFrame
Define.structPlayer Player
Define.structLevel  Level

Declare Level_Create()
Declare Player_Create()
Declare Player_UpdateControls()
Declare Player_Update()

; init
InitEngine3D(#PB_Engine3D_DebugLog)
InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0,0,0,1024,768,"Simple 3rd Person",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0, #PB_Screen_WaitSynchronization)

Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Textures\", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Scripts\", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Models\", #PB_3DArchive_FileSystem)
Parse3DScripts()

EnableWorldPhysics(#True)
EnableWorldCollisions(#True)

Level_Create()
Player_Create()

Repeat
 
  While WindowEvent() : Wend
  
  Player_Update()
  
  TimeSinceLastFrame = RenderWorld(#MINFPS) / 60
  FlipBuffers()
 
Until DoLoop = #False

End

Macro SetPosition(Object, PositionX=0, PositionY=0, PositionZ=0)
  If IsNode(Object)
    MoveNode(Object, PositionX, PositionY, PositionZ, #PB_Absolute)
  ElseIf IsEntity(Object)
    MoveEntity(Object, PositionX, PositionY, PositionZ, #PB_Absolute)
  ElseIf IsCamera(Object)
    MoveCamera(Object, PositionX, PositionY, PositionZ, #PB_Absolute)
  EndIf
EndMacro

Macro GetPosition(Object, Position)
  If IsNode(Object)
    Position\x = NodeX(Object)
    Position\y = NodeY(Object)
    Position\z = NodeZ(Object)
  ElseIf IsEntity(Object)
    Position\x = EntityX(Object)
    Position\y = EntityY(Object)
    Position\z = EntityZ(Object)
  ElseIf IsCamera(Object)
    Position\x = CameraX(Object)
    Position\y = CameraY(Object)
    Position\z = CameraZ(Object)
  EndIf
EndMacro

Macro AddVec3(v1, v2, vResult)
  vResult\x = v1\x + v2\x
  vResult\y = v1\y + v2\y
  vResult\z = v1\z + v2\z
EndMacro

Macro SubVec3(v1, v2, vResult)
  vResult\x = v1\x - v2\x
  vResult\y = v1\y - v2\y
  vResult\z = v1\z - v2\z
EndMacro
  
Procedure Level_Create()
  
  Shared      Level
  Protected.l i
  Protected.i tempTexture, tempMaterial, tempMesh
  Protected.f radius, scale, height
  
  SkyDome("clouds.jpg", 60)
  
  ; floor
  tempTexture  = LoadTexture(#PB_Any, "grass.jpg")
  tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
  tempMesh     = CreatePlane(#PB_Any, 512, 512, 1, 1, 128, 128)
  Level\floor  = CreateEntity(#PB_Any, MeshID(tempMesh), MaterialID(tempMaterial), 0, -#PLAYER_SIZE/2, 0)
  EntityPhysicBody(Level\floor, #PB_Entity_StaticBody)
  FreeMesh(tempMesh)
  FreeMaterial(tempMaterial)
  FreeTexture(tempTexture)
  
  ; grass
  tempTexture  = LoadTexture(#PB_Any, "grass1.png")
  tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
  MaterialBlendingMode(tempMaterial, #PB_Material_AlphaBlend)
  Level\grass  = CreateBillboardGroup(#PB_Any, MaterialID(tempMaterial), 1, 1)
  For i = 0 To 10240
    AddBillboard(i, Level\grass, Random(512)-256, 0, Random(512)-256)
  Next
  FreeMaterial(tempMaterial)
  FreeTexture(tempTexture)

  ; houses
  tempMesh = LoadMesh(#PB_Any, "tudorhouse.mesh")
  radius   = MeshRadius(tempMesh)
  scale    = 10 * #PLAYER_SIZE / radius
  height   = scale * (radius / 2)
  For i = 0 To 19
    Level\houses(i) = CreateEntity(#PB_Any, MeshID(tempMesh), #PB_Material_None, Random(384)-162, height, Random(384)-162)
    RotateEntity(Level\houses(i), 0, Random(90), 0, #PB_Absolute)
    ScaleEntity(Level\houses(i), scale, scale, scale, #PB_Absolute)
    EntityPhysicBody(Level\houses(i), #PB_Entity_StaticBody)
  Next
  FreeMesh(tempMesh)
  
  ; done !
  
EndProcedure

Procedure Player_Create()
  
  Shared      Player
  Protected.i tempTexture, tempMaterial, tempMesh
  Protected.f radius, scale
  
  tempTexture  = LoadTexture(#PB_Any, "viseur-jeux.png")
  tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
  MaterialBlendingMode(tempMaterial, #PB_Material_AlphaBlend)
  
  tempMesh = LoadMesh(#PB_Any, "ninja.mesh")
  radius   = MeshRadius(tempMesh)
  scale    = #PLAYER_SIZE / radius
  
  With Player
    
    \entity = CreateEntity(#PB_Any, MeshID(tempMesh), #PB_Material_None, 0, 0, 0)
    ScaleEntity(\entity, scale, scale, scale, #PB_Absolute)
    EntityPhysicBody(\entity, #PB_Entity_CapsuleBody, 0.8, 0, 0)
    
    \bbCross = CreateBillboardGroup(#PB_Any, MaterialID(tempMaterial), 1, 1, 0, 0, -10)
    AddBillboard(0, \bbCross, 0, 0, 0)
    
    \nodeMain    = CreateNode(#PB_Any, 0, #PLAYER_SIZE, 0)
    \nodeForward = CreateNode(#PB_Any, 0, 0, -1)
    \nodeStrafe  = CreateNode(#PB_Any, -1, 0, 0)
    \nodeCamera  = CreateNode(#PB_Any, 0, #CAMERA_DIST/4, #CAMERA_DIST)
    
    \camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
    RotateCamera(\camera, -10, 0, 0, #PB_Absolute)
    
    AttachNodeObject(\nodeMain, NodeID(\nodeForward))
    AttachNodeObject(\nodeMain, NodeID(\nodeStrafe))
    AttachNodeObject(\nodeMain, NodeID(\nodeCamera))
    AttachNodeObject(\nodeMain, BillboardGroupID(\bbCross))
    AttachNodeObject(\nodeCamera, CameraID(\camera))
    
    \Keys\forward     = #PB_Key_W
    \Keys\backward    = #PB_Key_S
    \Keys\turnLeft    = #PB_Key_A
    \Keys\turnRight   = #PB_Key_D
    \Keys\strafeLeft  = #PB_Key_Q
    \Keys\strafeRight = #PB_Key_E
    \Keys\run         = #PB_Key_LeftShift
    
  EndWith
  
  FreeMesh(tempMesh)
  FreeMaterial(tempMaterial)
  FreeTexture(tempTexture)
  
EndProcedure

Procedure Player_UpdateControls()
  
  Shared             Player, DoLoop, TimeSinceLastFrame
  Protected.f        speed, speed2
  Protected.fVector3 mainPos, forwardPos, strafePos, forwardDir, strafeDir, forwardMove, strafeMove
  
  With Player
    
    GetPosition(\nodeMain, mainPos)
    GetPosition(\nodeForward, forwardPos)
    GetPosition(\nodeStrafe, strafePos)
    SubVec3(forwardPos, mainPos, forwardDir)
    SubVec3(strafePos, mainPos, strafeDir)
    
  EndWith
  
  If ExamineKeyboard()
    
    If KeyboardReleased(#PB_Key_Escape)
      DoLoop = #False
    EndIf
    
    With Player\Keys
      
      If KeyboardPushed(\run)
        speed = #SCALE_RUN * TimeSinceLastFrame
      Else
        speed = #SCALE_WALK * TimeSinceLastFrame
      EndIf
      speed2 = speed / 2
      
      If KeyboardPushed(\forward)
        forwardMove\x = forwardDir\x * speed
        forwardMove\z = forwardDir\z * speed
      ElseIf KeyboardPushed(\backward)
        forwardMove\x = forwardDir\x * -speed2
        forwardMove\z = forwardDir\z * -speed2
      Else
        forwardMove\x = 0
        forwardMove\z = 0
      EndIf
      
      If KeyboardPushed(\turnLeft)
        Player\Rotate\y = 1
      ElseIf KeyboardPushed(\turnRight)
        Player\Rotate\y = -1
      Else
        Player\Rotate\y = 0
      EndIf
      
      If KeyboardPushed(\strafeLeft)
        strafeMove\x = strafeDir\x * speed2
        strafeMove\z = strafeDir\z * speed2
      ElseIf KeyboardPushed(\strafeRight)
        strafeMove\x = strafeDir\x * -speed2
        strafeMove\z = strafeDir\z * -speed2
      Else
        strafeMove\x = 0
        strafeMove\z = 0
      EndIf
        
    EndWith
      
  EndIf
  
  If ExamineMouse()
    
    If Player\Rotate\y = 0
      Player\Rotate\x = -MouseDeltaY() * #SCALE_TURN
      Player\Rotate\y = -MouseDeltaX() * #SCALE_TURN
    EndIf
    
  EndIf
  
  AddVec3(forwardMove, strafeMove, Player\Move)
  
EndProcedure

Procedure Player_Update()
  
  Shared   Player
  Static.b walking
  
  Player_UpdateControls()
  
  With Player
    
    If \Move\x <> 0 Or \Move\z <> 0
      If Not walking
        StartEntityAnimation(\entity, "Walk")
        walking = #True
      EndIf
    Else
      If walking
        StopEntityAnimation(\entity, "Walk")
      EndIf
      walking = #False
    EndIf
    
    MoveEntity(\entity, \Move\x, 0, \Move\z, #PB_Relative)
    RotateEntity(\entity, 0, \Rotate\y, 0, #PB_Relative)
    
    RotateNode(\nodeCamera, \Rotate\x, 0, 0, #PB_Relative)
    
    MoveNode(\nodeMain, EntityX(\entity), #PLAYER_SIZE, EntityZ(\entity), #PB_Absolute)
    RotateNode(\nodeMain, 0, EntityYaw(\entity), 0, #PB_Absolute) 
    
  EndWith

EndProcedure
Wenn da jemand einen Fehler findet, ich bin gespannt.
---
Windows 11 (64 bit)
Benutzeravatar
Makke
Beiträge: 156
Registriert: 24.08.2011 18:00
Computerausstattung: AMD Ryzen 7 5700X - AMD Radeon RX 6800 XT - 32 GB DDR4 SDRAM
Wohnort: Ruhrpott
Kontaktdaten:

Re: MoveEntity(#PB_Relative) funzt mit Physik nicht mehr ?!

Beitrag von Makke »

Also, wenn man das Node relativ bewegt und das Entity "nachzieht", dann funktioniert es:

Code: Alles auswählen

EnableExplicit

#MINFPS = 30

#PLAYER_SIZE = 1.8
#CAMERA_DIST = 8

#SCALE_WALK = 1.0
#SCALE_RUN  = 1.4
#SCALE_TURN = 0.1

Structure fVector3
  x.f
  y.f
  z.f
EndStructure

Structure structKeysettings
  forward.i
  backward.i
  turnLeft.i
  turnRight.i
  strafeLeft.i
  strafeRight.i
  run.i
EndStructure

Structure structPlayer
  init.b
  Keys.structKeysettings
  Rotate.fVector3
  Move.fVector3
  entity.i
  physic.i
  camera.i
  bbCross.i
  nodeMain.i
  nodeForward.i
  nodeStrafe.i
  nodeCamera.i
EndStructure

Structure structLevel
  sun.i
  floor.i
  grass.i
  Array houses.i(25)
EndStructure

Define.b            DoLoop = #True
Define.f            TimeSinceLastFrame
Define.structPlayer Player
Define.structLevel  Level

Declare Level_Create()
Declare Player_Create()
Declare Player_UpdateControls()
Declare Player_Update()
Declare CheckCollisions()

; init
InitEngine3D(#PB_Engine3D_DebugLog)
InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0,0,0,1024,768,"Simple 3rd Person",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0, #PB_Screen_WaitSynchronization)

Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Textures\", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Scripts\", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Models\", #PB_3DArchive_FileSystem)
Parse3DScripts()

WorldShadows(#PB_Shadow_Additive)

EnableWorldPhysics(#True)
EnableWorldCollisions(#True)

Level_Create()
Player_Create()

WorldDebug(#PB_World_DebugBody)

Repeat
 
  While WindowEvent() : Wend
  
  Player_Update()
  
  TimeSinceLastFrame = RenderWorld(#MINFPS) / 60
  FlipBuffers()
  
  CheckCollisions()
 
Until DoLoop = #False

End

Macro SetPosition(Object, PositionX=0, PositionY=0, PositionZ=0)
  If IsNode(Object)
    MoveNode(Object, PositionX, PositionY, PositionZ, #PB_Absolute)
  ElseIf IsEntity(Object)
    MoveEntity(Object, PositionX, PositionY, PositionZ, #PB_Absolute)
  ElseIf IsCamera(Object)
    MoveCamera(Object, PositionX, PositionY, PositionZ, #PB_Absolute)
  EndIf
EndMacro

Macro GetPosition(Object, Position)
  If IsNode(Object)
    Position\x = NodeX(Object)
    Position\y = NodeY(Object)
    Position\z = NodeZ(Object)
  ElseIf IsEntity(Object)
    Position\x = EntityX(Object)
    Position\y = EntityY(Object)
    Position\z = EntityZ(Object)
  ElseIf IsCamera(Object)
    Position\x = CameraX(Object)
    Position\y = CameraY(Object)
    Position\z = CameraZ(Object)
  EndIf
EndMacro

Macro AddVec3(v1, v2, vResult)
  vResult\x = v1\x + v2\x
  vResult\y = v1\y + v2\y
  vResult\z = v1\z + v2\z
EndMacro

Macro SubVec3(v1, v2, vResult)
  vResult\x = v1\x - v2\x
  vResult\y = v1\y - v2\y
  vResult\z = v1\z - v2\z
EndMacro
  
Procedure Level_Create()
  
  Shared      Level
  Protected.l i
  Protected.i tempTexture, tempMaterial, tempMesh
  Protected.f radius, scale, height
  
  SkyDome("clouds.jpg", 60)
  
  ; floor
  tempTexture  = LoadTexture(#PB_Any, "grass.jpg")
  tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
  tempMesh     = CreatePlane(#PB_Any, 512, 512, 1, 1, 128, 128)
  Level\floor  = CreateEntity(#PB_Any, MeshID(tempMesh), MaterialID(tempMaterial), 0, -#PLAYER_SIZE/2, 0)
  EntityPhysicBody(Level\floor, #PB_Entity_StaticBody)
  FreeMesh(tempMesh)
  FreeMaterial(tempMaterial)
  FreeTexture(tempTexture)
  
  ; grass
  tempTexture  = LoadTexture(#PB_Any, "grass1.png")
  tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
  MaterialBlendingMode(tempMaterial, #PB_Material_AlphaBlend)
  Level\grass  = CreateBillboardGroup(#PB_Any, MaterialID(tempMaterial), 1, 1)
  For i = 0 To 10240
    AddBillboard(i, Level\grass, Random(512)-256, 0, Random(512)-256)
  Next
  FreeMaterial(tempMaterial)
  FreeTexture(tempTexture)

  ; houses
  tempMesh = LoadMesh(#PB_Any, "tudorhouse.mesh")
  radius   = MeshRadius(tempMesh)
  scale    = 6 * #PLAYER_SIZE / radius
  height   = scale * (radius / 2) + 1.75
  For i = 0 To 19
    Level\houses(i) = CreateEntity(#PB_Any, MeshID(tempMesh), #PB_Material_None, Random(384)-162, height, Random(384)-162)
    RotateEntity(Level\houses(i), 0, Random(90), 0, #PB_Absolute)
    ScaleEntity(Level\houses(i), scale, scale, scale, #PB_Absolute)
    EntityPhysicBody(Level\houses(i), #PB_Entity_StaticBody)
  Next
  FreeMesh(tempMesh)
  
  ; sun
  Level\sun = CreateLight(#PB_Any, RGB(255, 250, 205), -512, 512, 0, #PB_Light_Point)
  
  ; done !
  
EndProcedure

Procedure Player_Create()
  
  Shared      Player
  Protected.i tempTexture, tempMaterial, tempMesh
  Protected.f radius, scale
  
  tempTexture  = LoadTexture(#PB_Any, "viseur-jeux.png")
  tempMaterial = CreateMaterial(#PB_Any, TextureID(tempTexture))
  MaterialBlendingMode(tempMaterial, #PB_Material_AlphaBlend)
  
  tempMesh = LoadMesh(#PB_Any, "ninja.mesh")
  radius   = MeshRadius(tempMesh)
  scale    = #PLAYER_SIZE / radius
  
  With Player
    
    \entity = CreateEntity(#PB_Any, MeshID(tempMesh), #PB_Material_None, 0, 0, 0)
    ScaleEntity(\entity, scale, scale, scale, #PB_Absolute)
    ;EntityPhysicBody(\entity, #PB_Entity_CapsuleBody, 0.8, 0, 0)
    
    \physic = CreateEntity(#PB_Any, MeshID(tempMesh), #PB_Material_None, 0, 0, 0)
    ScaleEntity(\physic, scale, scale, scale, #PB_Absolute)
    HideEntity(\physic, #True)
    EntityPhysicBody(\physic, #PB_Entity_CapsuleBody, 0.8, 0, 0)
    
    \bbCross = CreateBillboardGroup(#PB_Any, MaterialID(tempMaterial), 1, 1, 0, 0, -10)
    AddBillboard(0, \bbCross, 0, 0, 0)
    
    \nodeMain    = CreateNode(#PB_Any, 0, #PLAYER_SIZE, 0)
    \nodeForward = CreateNode(#PB_Any, 0, 0, -1)
    \nodeStrafe  = CreateNode(#PB_Any, -1, 0, 0)
    \nodeCamera  = CreateNode(#PB_Any, 0, #CAMERA_DIST/4, #CAMERA_DIST)
    
    \camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
    RotateCamera(\camera, -10, 0, 0, #PB_Absolute)
    
    AttachNodeObject(\nodeMain, NodeID(\nodeForward))
    AttachNodeObject(\nodeMain, NodeID(\nodeStrafe))
    AttachNodeObject(\nodeMain, NodeID(\nodeCamera))
    AttachNodeObject(\nodeMain, BillboardGroupID(\bbCross))
    AttachNodeObject(\nodeCamera, CameraID(\camera))
    
    \Keys\forward     = #PB_Key_W
    \Keys\backward    = #PB_Key_S
    \Keys\turnLeft    = #PB_Key_A
    \Keys\turnRight   = #PB_Key_D
    \Keys\strafeLeft  = #PB_Key_Q
    \Keys\strafeRight = #PB_Key_E
    \Keys\run         = #PB_Key_LeftShift
    
  EndWith
  
  FreeMesh(tempMesh)
  FreeMaterial(tempMaterial)
  FreeTexture(tempTexture)
  
EndProcedure

Procedure Player_UpdateControls()
  
  Shared             Player, DoLoop, TimeSinceLastFrame
  Protected.f        speed, speed2
  Protected.fVector3 mainPos, forwardPos, strafePos, forwardDir, strafeDir, forwardMove, strafeMove
  
  With Player
    
    GetPosition(\nodeMain, mainPos)
    GetPosition(\nodeForward, forwardPos)
    GetPosition(\nodeStrafe, strafePos)
    SubVec3(forwardPos, mainPos, forwardDir)
    SubVec3(strafePos, mainPos, strafeDir)
    
  EndWith
  
  If ExamineKeyboard()
    
    If KeyboardReleased(#PB_Key_Escape)
      DoLoop = #False
    EndIf
    
    With Player\Keys
      
      If KeyboardPushed(\run)
        speed = #SCALE_RUN * TimeSinceLastFrame
      Else
        speed = #SCALE_WALK * TimeSinceLastFrame
      EndIf
      speed2 = speed / 2
      
      If KeyboardPushed(\forward)
        forwardMove\x = forwardDir\x * speed
        forwardMove\z = forwardDir\z * speed
      ElseIf KeyboardPushed(\backward)
        forwardMove\x = forwardDir\x * -speed2
        forwardMove\z = forwardDir\z * -speed2
      Else
        forwardMove\x = 0
        forwardMove\z = 0
      EndIf
      
      If KeyboardPushed(\turnLeft)
        Player\Rotate\y = 1
      ElseIf KeyboardPushed(\turnRight)
        Player\Rotate\y = -1
      Else
        Player\Rotate\y = 0
      EndIf
      
      If KeyboardPushed(\strafeLeft)
        strafeMove\x = strafeDir\x * speed2
        strafeMove\z = strafeDir\z * speed2
      ElseIf KeyboardPushed(\strafeRight)
        strafeMove\x = strafeDir\x * -speed2
        strafeMove\z = strafeDir\z * -speed2
      Else
        strafeMove\x = 0
        strafeMove\z = 0
      EndIf
        
    EndWith
      
  EndIf
  
  If ExamineMouse()
    
    If Player\Rotate\y = 0
      Player\Rotate\x = -MouseDeltaY() * #SCALE_TURN
      Player\Rotate\y = -MouseDeltaX() * #SCALE_TURN
    EndIf
    
  EndIf
  
  AddVec3(forwardMove, strafeMove, Player\Move)
  
EndProcedure

Procedure Player_Update()
  
  Shared   Player
  Static.b walking
  
  Player_UpdateControls()
  
  With Player
    
    If \Move\x <> 0 Or \Move\z <> 0
      If Not walking
        StartEntityAnimation(\entity, "Walk")
        walking = #True
      EndIf
    Else
      If walking
        StopEntityAnimation(\entity, "Walk")
      EndIf
      walking = #False
    EndIf
    
    ;MoveEntity(\entity, \Move\x, 0, \Move\z, #PB_Relative)
    ;RotateEntity(\entity, 0, \Rotate\y, 0, #PB_Relative)
    MoveNode(\nodeMain, \Move\x, 0, \Move\z, #PB_Relative)
    RotateNode(\nodeMain, 0, \Rotate\y, 0, #PB_Relative)
    
    RotateNode(\nodeCamera, \Rotate\x, 0, 0, #PB_Relative)
    
    ;MoveNode(\nodeMain, EntityX(\entity), #PLAYER_SIZE, EntityZ(\entity), #PB_Absolute)
    ;RotateNode(\nodeMain, 0, EntityYaw(\entity), 0, #PB_Absolute) 
    MoveEntity(\entity, NodeX(\nodeMain), -#PLAYER_SIZE/2, NodeZ(\nodeMain), #PB_Absolute)
    RotateEntity(\entity, 0, NodeYaw(\nodeMain), 0, #PB_Absolute) 
    
    MoveEntity(\physic, NodeX(\nodeMain), -0.1, NodeZ(\nodeMain), #PB_Absolute)
    
  EndWith

EndProcedure

Procedure CheckCollisions()
  Shared      Level
  Protected.i first, second
  If ExamineWorldCollisions(#False)
    While NextWorldCollision()
      first  = FirstWorldCollisionEntity()
      second = SecondWorldCollisionEntity()
      If first <> Level\floor And second <> Level\floor
        Debug "Entity #"+Str(first)+" collide with Entity #"+Str(second)
      EndIf
    Wend
  EndIf
EndProcedure
ABER, der physische Körper des Entities ist irgendwie verschoben, von daher muss ein zweites, unsichtbares Entity her, das in der Höhe verschoben wird um diesen physischen Körper gleich mit dem ursprünglichen Entity zu setzen. So, dann ist das Problem, das die ExamineWorldCollisions() Funktion die Collision nicht mehr registriert.

Kannst mal mit dem Beispiel rumspielen, dann siehst Du was ich meine.
---
Windows 11 (64 bit)
Antworten