Greetings fellow Panda3D devs. It’s been a while since I posted here about my 3d adventure game, but there is something that has been stumping me for a long time and giving me a sort of coder’s block if you will. I am ashamed to admit I haven’t come up with any viable solutions so I am hoping you can help get me back on track.
My problem is: My game has uneven terrain such as hills and slopes and stairs that the player and NPCs can climb. I want them to move slowly up slopes and smoothly down slopes, but I also want them to slide down steep surfaces.
I need generic code that can apply in any situation with slopes of any angle / direction, not just cardinal directions.
The way I handled this so far is by checking the difference in the current Z value of the player compared to the surface below their feet, and adjusting speed based on that. But this does not address steep surfaces or sliding down while not providing any control input. Code below (highestZ here is the Z value of the surface below the player that collides with a downcast ray).
fudge=0.15
zd = highestZ - (self.node.getZ()-fudge)
if zd > 0:
self.grounded=True # we're on solid ground
self.node.setZ(highestZ+fudge) # set Z to floor height
self.moveZ = 0 # stop downward momentum
speedMult = max(0.2, min(1,1-(zd*self.climb_speed_penalty)))
self.moveX *= speedMult
self.moveY *= speedMult
This is not what I really want and it leads to some janky physics.
What I considered was to cast more rays downward, offset in a circle around the player, to detect the slope at various directions from the center of the player. But this seems dumb, as it requires an arbitrary number of rays to approach perfect slope detection and would probably slow things down if every NPC that moved needed so many collision rays. If we used fewer collision rays the performance would increase but the slope detection would suffer.
Is there any mathematical way to detect the angle / steepness of the slope that our downcast ray collides with, or is there some solution I haven’t thought of which does not require such a brute force method?
Please let me know your thoughts on this. I’m very new to 3D game design, and I think I lack the tools to solve this problem on my own. Thanks in advance, and I look forward to your comments.