I have exported a plane to map.x and I have a map class in python.
I also have a character that should walk on the plane.
Heres the code to set the right heigt on the ground for the character:
def setHeight(self, object, offset=0,
checkName=0, setHpr=1):
""" setZ of an object, so it will walk
on uneven terrain
"""
cTrav = CollisionTraverser()
pandaGroundRay = CollisionRay()
pandaGroundRay.setOrigin(0,0,10000)
pandaGroundRay.setDirection(0,0,-1)
pandaGroundCol = CollisionNode('pandaRay')
pandaGroundCol.addSolid(pandaGroundRay)
pandaGroundCol.setFromCollideMask(BitMask32.bit(0))
pandaGroundCol.setIntoCollideMask(BitMask32.allOff())
pandaGroundColNp = object.attachNewNode(pandaGroundCol)
pandaGroundHandler = CollisionHandlerQueue()
cTrav.addCollider(pandaGroundColNp, pandaGroundHandler)
if setHpr:
#set right hpr afterwards
H = object.getH()
entries = []
cTrav.traverse(render)
for e in xrange(pandaGroundHandler.getNumEntries()):
entry = pandaGroundHandler.getEntry(e)
entries.append(entry)
entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
x.getSurfacePoint(render).getZ()))
if (len(entries)>0):
print entries[0].getIntoNode().getName()
# if should check the name, so you dont walk up trees and stuff
if entries[0].getIntoNode().getName() == self.groundName or not checkName:
object.setZ(entries[0].getSurfacePoint(render).getZ() + offset)
object.pos = object.getPos()
else:
# go back, so you dont walk through a tree
object.setPos(object.pos)
#self.pos = self.char.getPos()
else:
print entries
pass #object.setPos(object.pos)
if setHpr:
object.setH(H)
This code works with the terrain from roaming ralph but not with a plane exported from blender.
Why?
I don’t see anything obviously wrong with the code, other than the fact that it doesn’t clean up pandaGroundColNp afterwards.
But what you’re asking is a fairly standard question: “My collisions are not being detected! Why not?” And the answer is the same: “Maybe your collision mask is wrong, or maybe you’re not calling traverse(), or maybe the objects really aren’t intersecting.”
You do appear to be calling traverse(). I don’t know whether your plane has a BitMask32(0) set on it or not, so I can’t say whether this is right or not. I don’t know where your plane is, or what position or rotation is held by your object, so I can’t say whether your objects should or should not be intersecting either.
You could call show() on your pandaGroundColNp to help visualize whether it should be intersecting or not. You might need to bring it a little closer than 10,000 units so you can see it.
Your map is an Actor? You know that collisions don’t work when loaded in an animated file, right?
You have to convert the plane model as a static model (animation type “none”) in order for it to be loaded correctly. Be sure you have a CollisionNode inside your model:
model = loader.loadModel('myPlane.egg')
print model.find('**/+CollisionNode')
In fact, you could show it visually to reassure yourself that it exists:
class M:
def __init__(self, map):
self.map = loader.loadModel(map)
self.map.reparentTo(render)
self.map.setHpr((0.0, 90.0, 0.0))
def setHeight(self, object, offset=0,
checkName=0, setHpr=1):
""" setZ of an object, so it will walk
on uneven terrain
"""
#if self.once:
# return
self.once = True
cTrav = CollisionTraverser()
pandaGroundRay = CollisionRay()
pandaGroundRay.setOrigin(0,0,1000)
pandaGroundRay.setDirection(0,0,-1)
pandaGroundCol = CollisionNode('pandaRay')
pandaGroundCol.addSolid(pandaGroundRay)
pandaGroundCol.setFromCollideMask(BitMask32.bit(0))
pandaGroundCol.setIntoCollideMask(BitMask32.allOff())
pandaGroundColNp = object.attachNewNode(pandaGroundCol)
pandaGroundHandler = CollisionHandlerQueue()
cTrav.addCollider(pandaGroundColNp, pandaGroundHandler)
object.test = pandaGroundColNp
object.show()
if setHpr:
#set right hpr afterwards
H = object.getH()
entries = []
cTrav.traverse(render)
for e in xrange(pandaGroundHandler.getNumEntries()):
entry = pandaGroundHandler.getEntry(e)
entries.append(entry)
entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
x.getSurfacePoint(render).getZ()))
if (len(entries)>0):
print entries[0].getIntoNode().getName()
# if should check the name, so you dont walk up trees and stuff
if entries[0].getIntoNode().getName() == self.groundName or not checkName:
object.setZ(entries[0].getSurfacePoint(render).getZ() + offset)
object.pos = object.getPos()
else:
# go back, so you dont walk through a tree
object.setPos(object.pos)
#self.pos = self.char.getPos()
else:
print entries
pass #object.setPos(object.pos)
if setHpr:
object.setH(H)
return
#object.removeNode(pandaGroundCol)
cTrav.destroy()
pandaGroundRay.destroy()
pandaGroundColNp.destroy()
pandaGroundHandler.destroy()
pandaGroundCol.destroy()
Can anyone tell me how to do that in blender?
Im not the blender expert at my project and I cant contact someone who knows that at my project.
Please help me!