Character is Getting Stuck
Blitz3D Forums/Blitz3D Programming/Character is Getting Stuck
| ||
for video of this problem go to: http://www.youtube.com/watch?v=hR5bdggt-BA Basically if I jump into some corners, very special ones (see video), my character will hover just a bit above the ground. He can still walk but even though MoveEntity is acting upon him he doesn't go anywhere Walking Code charAction = IDLE ;jumping + gravity Local playerCollided = EntityCollided(player,ENVIRONMENTTYPE) Local collisionIndex Local touchingGround = False TranslateEntity player,0,-.1,0 ;push the player down to make sure he is touching the ground ;cycle through the player collisions If playerCollided <> 0 Then For collisionIndex = 1 To CountCollisions(player) ;if the collision is under the player then If CollisionY#(player,collisionIndex) < EntityY#(player)-.1 Then touchingGround = True ;tell the computer hes touching the ground nx# = CollisionNX#(player,collisionIndex) ;get the normals ny# = CollisionNY#(player,collisionIndex) nz# = CollisionNZ#(player,collisionIndex) If playerYV# < -.5 curHealth# = curHealth# + maxHealth*((playerYV#)/3.0) ;subtract health if he fell too far RotateEntity character,0,0,0 ;make sure that the player is upright RotateEntity player,0,EntityYaw#(player),0 ;if the collision is over the player ElseIf CollisionY#(player,collisionIndex) > EntityY#(player)+.8 Then If playerYV# > 0 playerYV# = -playerYV# ;stop his upward momentum EndIf Next EndIf If collisionIndex >= 2 Then If touchingGround = False Then LinePick EntityX#(player),EntityY#(player),EntityZ#(player),0,-.95,0,.3 If PickedEntity() <> 0 Then nx# = 0 ny# = 0 nz# = 0 touchingGround = True EndIf EndIf EndIf ;if the player not touching the ground If touchingGround = False Then TranslateEntity player,0,.1,0 ;move the player back down (we move him up above to smooth collisions) timeSinceLastGround = timeSinceLastGround + 1 ;add 1 to a counter that counts how many frames since the last collision Else If timeSinceLastGround > 1 Then jumpXComp# = 0 jumpZComp# = 0 EndIf timeSinceLastGround = 0 EndIf ;keep player from getting stuck in corners (fixes a bug that kept player who were falling from a jump from getting stuck) If Abs((EntityY#(player)-oldPlayerY#)-playerYV#) > .001 And collisionIndex >= 3 Then jumpXComp# = 0 jumpZComp# = 0 EndIf ;this rotates the player so hes facing on the lay of the land but save the pitch yaw and roll so we can put him back after hes done pitch# = EntityPitch#(player) yaw# = EntityYaw#(player) roll# = EntityRoll#(player) playerNX# = playerNX# - ((playerNX#-nx#)/2) playerNY# = playerNY# - ((playerNY#-ny#)/2) playerNZ# = playerNZ# - ((playerNZ#-nz#)/2) AlignToVector player,NX#,NY#,NZ#,2 ;character movement If KeyHit(33) And chatOn = False autorun = 1-autorun Local currentlyMoving = 0 ;turns off autorun if the player presses a key If KeyDown(200) Or (KeyDown(17) And chatOn = False) Or (mouse1down And mouse2down) Or KeyDown(208) Or (KeyDown(31) And chatOn = False) autorun = 0 ;if the player should be going foward If ((KeyDown(200) Or (KeyDown(17) And chatOn = False) Or (mouse1down And mouse2down) Or autorun = 1)) And ((touchingGround = True) Or (timeSinceLastGround < 10)) Then ;if the player is going up too steep a hill then face him down so he can't walk up it If (EntityPitch#(player)+Abs(EntityRoll#(player)) < 40) Or (EntityPitch#(player) <= 0) Then If playerYV# <= 0 MoveEntity player,0,0,-.2 currentlyMoving = 1 EndIf ;tell the computer that hes moving, move him, and set the anim seq to moving charAction = MOVING ;if the player is supposed to be going backwards do much the same thing ElseIf (KeyDown(208) Or (KeyDown(31) And chatOn = False)) And (touchingGround = True Or timeSinceLastGround < 10) If (EntityPitch#(player)-Abs(EntityRoll#(player)) > -45) Or (EntityPitch#(player) >= 0) Then If playerYV# <= 0 MoveEntity player,0,0,.2 currentlyMoving = -1 EndIf charAction = MOVING EndIf ;rerotate the player to his original rotation RotateEntity player,pitch#,yaw#,roll# ;turn the player if he's got the turn keys down If KeyDown(203) Or (KeyDown(30) And chatOn = False) Then TurnEntity player,0,2,0 ElseIf KeyDown(205) Or (KeyDown(32) And chatOn = False) TurnEntity player,0,-2,0 EndIf ;jumP + store momentum of jump If KeyHit(57) And touchingGround = True And chatOn = False And PlayerYV# <= 0 Then touchingGround = False playerYV# = .4 jumpZComp# = Cos(EntityYaw#(player))*currentlyMoving jumpXComp# = Sin(EntityYaw#(player))*currentlyMoving EndIf ;if the player isn't touching ground If touchingGround = False Then ;and he hasn't been touching the ground for at least ten frames make him touch the ground If timeSinceLastGround >= 10 charAction = JUMPING playerYV# = playerYV# - .025 ;move him downwards TranslateEntity player,jumpXComp#*.2,0,jumpZComp#*-.2 ;if he had any momentum move him that way Else If playerYV# < 0 playerYV# = 0 EndIf ;gravity + save the playerY so that it can be used on the next loop If playerYV# < -3 Then playerYV# = -3 oldPlayerY# = EntityY#(player) TranslateEntity player,0,playerYV#,0 ;animation If charAction = IDLE Then If AnimSeq(character) <> 1 Animate character,1,.1,1 ElseIf charAction = MOVING Then If AnimSeq(character) <> 2 Animate character,1,1,2 ElseIf charAction = JUMPING Then If AnimSeq(character) <> 3 Animate character,2,1,3 EndIf ;camera rotation (for when the user wants to pivot around the player mesh) If curPlayerKeyMode = RUNMODE Then If mouse1down And mouse2down=0 And clicklock = False Then TurnEntity campiv,-mys/3.0,-mxs/3.0,0 ElseIf mouse2down Then If mouse2hit Then RotateEntity player,0,EntityYaw#(campiv)+EntityYaw#(player),0 RotateEntity campiv,EntityPitch#(campiv),0,0 EndIf TurnEntity player,0,-mxs/3.0,0 TurnEntity campiv,-mys/3.0,0,0 Else TurnEntity campiv,-EntityPitch#(campiv)/10,-EntityYaw#(campiv)/10,0 EndIf EndIf If EntityPitch#(campiv) > 80 RotateEntity campiv,80,EntityYaw#(campiv),0 If EntityPitch#(campiv) < -80 RotateEntity campiv,-80,EntityYaw#(campiv),0 RotateEntity campiv,EntityPitch#(campiv),EntityYaw#(campiv),0 |
| ||
I'd say don't collide with the environment itself, but a hidden (with zero alpha, not HideEntity), lower poly version of it. When you collide with those specific corners, the math can be quite jerky and eventually it'll stuck your character. Having a "lower resolution" mesh to act as a collider will avoid such issue. Collisions with levels: Make a detailed level model as normal and split it up into sections. Don't give this mesh a collision type but rather create a mesh that has basically the same layout with as few polygons as possible, with as little detail as required, set its alpha to zero and use it for detecting collisions between characters and the level. http://blitzbasic.com/Community/posts.php?topic=39205#497038 You don't need that collider mesh for the whole level, though. Only for buildings and structures where the detail might get your character stuck. Things like terrains and ground can be kept by themselves. |