Hello,
Like every newbie, I’m trying to prevent my avatar from going through walls.
I have something that kind of works but it’s weird, and I don’t know if it’s normal or not: The collisions are detected and I am always pushed back into a valid position. However, the whole part about sliding against the walls is messed up: I slide backward and end up stuck onto a convex corner for instance.
Is that expected with a CollisionHandlerPusher?
Here some details, maybe it can help:
My world is very simple, think “Wolfenstein 3D”: tile-based, no floor, no ceilings, walls are cubes (1x1x2 units in size, I think in meters).
I thought I could collide against the visible geometry since it was so simple (200 frames per second). My cube is exported from Blender with Yabee. I added the line " { Polyset descend keep }" (even though I don’t understand the “descend” part). Each wall in the maze is an instance of that cube.
I attached a CollisionNode to my avatar and gave it a CollisionSphere of radius 0.3 (or 30 cm). Since I changed the near-distance of my camera to 0.1, I never see through a wall.
This is how I set up the collisions:
self.avatar = self.render.attachNewNode('avatar')
self.avatar.setPos(Point3(0, 0, 1.5))
avatar_col = self.avatar.attachNewNode(CollisionNode('avatar collision'))
avatar_col.node().addSolid(CollisionSphere(0, 0, 0, .3))
avatar_col.node().setFromCollideMask(BitMask32.bit(0))
pusher = CollisionHandlerPusher()
pusher.addCollider(avatar_col, self.avatar)
traverser = CollisionTraverser('traverser')
traverser.addCollider(avatar_col, pusher)
traverser.showCollisions(self.render)
self.cTrav = traverser
self.camera.reparentTo(self.avatar)
self.camLens.setNear(0.1)
And this is how I move my avatar:
def movePlayerTask(self, task):
self.mouseLook()
# self.keys is updated with events
velocity = Vec3(self.keys['right'] - self.keys['left'],
self.keys['forward'] - self.keys['backward'],
0)
velocity.normalize()
# Move relatively to the cam.
quat = LRotationf(Vec3.up(), self.avatar.getH())
velocity = quat.xform(velocity)
# At a given speed.
dt = globalClock.getDt()
speed = 3.0
# Teleport there.
pos = self.avatar.getPos() + velocity * dt * speed
self.avatar.setPos(pos)
return Task.cont
Am I doing something wrong?