What's the best way to go around jumping?

well I’m not sure why i cant do gravity, from what i get and from what i saw in roaming ralph example it should work. common sense also tells that. but im not falling when walking outside the collider of the plane

char script

from panda3d.bullet import BulletTriangleMeshShape, BulletTriangleMesh
from panda3d.bullet import BulletRigidBodyNode
from panda3d.core import CollisionHandlerPusher, CollideMask, CollisionNode, CollisionSphere, CollisionRay, \
    CollisionHandlerQueue
from direct.actor.Actor import Actor
from reference import REFERENCE
from Swoosh import Swoosh
from direct.task.Timer import Timer


class Char():
    speed = 20
    NAMEID = 'apple_char'
    ORIGIN = (0,0,0)
    def __init__(self,ctrav,pusher):
        x,y,z = self.ORIGIN
        self.model = Actor(REFERENCE.loadTexturePath('moon6.bam'))#loader.loadModel(REFERENCE.loadTexturePath('moon.bam'))
        self.model.setScale(0.5,0.5,0.5)
        self.node = render.attachNewNode(self.NAMEID)
        self.model.setPos(x,y,z)
        self.node.setPos(x,y,z)
        self.model.reparentTo(self.node)
        self.futurepos = self.node.getPos()
        self.qq = CollisionHandlerQueue()
        self.cNode = CollisionNode(f'{self.NAMEID}')
        self.cNodeP = self.model.attachNewNode(self.cNode)
        self.cNodeP.setPos(x,y,z)
        self.cNode.addSolid(CollisionSphere(center=(x, y, z), radius=5))
        self.cNode.setFromCollideMask(CollideMask.bit(0))
        self.cNode.setIntoCollideMask(CollideMask.bit(0))
        self.cNodeP.setPos(self.model,0,0,2)

        #self.cNodeP.show()

        self.gcNode = CollisionNode(f'Gcollision_{self.NAMEID}')
        self.GroundColl = CollisionRay()
        self.GroundColl.setOrigin(z, y, z)
        self.GroundColl.setDirection(0, 0, -1)

        self.gcNode.add_solid(self.GroundColl)
        self.gcNode.setFromCollideMask(CollideMask.bit(1))
        self.gcNodeP = self.node.attachNewNode(self.gcNode)
        self.gcNodeP.setPos(self.node,0,0,0)
        #self.gcNodeP.show()

        self.floater = self.node.attachNewNode(f'camera_{self.NAMEID}')
        self.floater.setPos(self.node,0,0,2)
        self.floater.show()

        self.model.setPos(self.node,0,0,-1)


        ctrav.addCollider(self.gcNodeP, self.qq)


        self.controller = self.model.getAnimControl('walk.001')
        print(self.controller)

        #self.cNodeP.show()

        pusher.horizontal = True
        pusher.addCollider(self.cNodeP, self.node)
        ctrav.addCollider(self.cNodeP, pusher)

        self.lastDelta = [0,0]
        self.node.setScale(2,2,2)

        self.swoosh = Swoosh(self,ctrav)

        self.cmddict = {
            "up": self.Up,
            "down": self.Down,
            "left": self.Left,
            "right": self.Right,
            "shoot": self.beep,
            'not shoot': self.boop,
            'top' : self.top,
            'bottom' : self.bottom
        }

        self.CanHit = False




    def Update_state(self,keypass,dt, tup):
        self.lastDelta = [0,0]

        self.futurepos = self.node.getPos(self.node)
        dx, dy = tup






        valz = []
        for k, v in keypass.items():
            valz.append(v)
            if v:
                self.cmddict[k](dt)

        if not any(valz[:4]):
            self.model.stop()
        elif True in valz[:4] and not self.controller.isPlaying():
            self.model.loop('walk.001',True)




        self.node.setPos(self.node,self.futurepos)

        entries = list(self.qq.entries)

        if len(entries) == 0:
            self.node.setZ(self.node,self.node.getZ()-1)



        for entry in entries:
            if entry.getIntoNode().getName() == "collision_tGround":
                self.node.setZ(entry.getSurfacePoint(render).getZ()+4.5)

        self.qq.clear_entries()





        self.node.setHpr(dx, 0, 0)
        self.floater.setPos(self.node.getPos())




    def Up(self, dt):
        self.futurepos.x -= self.speed * dt
        self.lastDelta = [0, -1]




    def Down(self, dt):
        self.futurepos.x += self.speed * dt
        self.lastDelta = [0, 1]






    def Left(self, dt):
        self.futurepos.y -= self.speed * dt
        self.lastDelta = [-1,0]




    def Right(self, dt):
        self.futurepos.y += self.speed * dt
        self.lastDelta = [1, 0]



    def top(self, dt):
        self.futurepos.z += self.speed * dt

    def bottom(self, dt):
        self.futurepos.z -= self.speed * dt


    def beep(self,duduh):

        self.swoosh.YeetEnemy()
        self.CanHit = False



    def boop(self, b):
        pass



    #DEBUG METHODS
    def changecNode(self,tup):
        x,y,z = tup
        self.cNodeP.setScale((x,y,z))









plane script

from panda3d.core import CollisionNode, CollisionPolygon, CollisionHandlerPusher, CollideMask, CollisionPlane, Plane, \
    Point3, Vec3
from reference import REFERENCE


class test_ground():
    NAMEID = 'tGround'
    def __init__(self,ctrav,QQ):
        self.model = loader.loadModel(REFERENCE.loadTexturePath('plane3.bam'))
        self.model.setScale(0.7*10,0.7*10,0.1)
        self.node = render.attachNewNode(f"{self.NAMEID}")
        self.cNode = CollisionNode(f"collision_{self.NAMEID}")
        self.cNode.add_solid(CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))))
        self.cNode.setFromCollideMask(CollideMask.bit(1))
        self.cNode.setIntoCollideMask(CollideMask.bit(1))
        self.cNodeP = self.node.attachNewNode(self.cNode)
        self.cNodeP.setScale(0.7 * 11.5, 0.7 * 11.5, 0.1)
        self.model.reparentTo(self.node)
        #self.cNodeP.show()



        ctrav.addCollider(self.cNodeP, QQ)












and the issue:

sorry for really squeezing everything outa this place. i try to keep my questions once per day here, and like 5 a day on discord. But the urge to progress really drives me mad, and i cant just abandon the issue and work on other stuff in the meantime as it makes me feel bad

I suspect that what’s happening is that your code is intended to move your character down when there are no collision entries present in your ray’s queue. However, since your character has an attached collider, the ray may well be colliding with that, meaning that there’s (presumably) always at least one collision entry.

One potential solution might be to look into using bitmasks to prevent your ray from colliding with your character’s collider.

im aware of what bitmasks are but i kinda wonder if i can do bitwise operations on them? i ant to have one bitmask include others, so for example bitmask 3 can collide with everything like bitmask 2 and 1 but not 4. cuz i wanna keep some collisions but negate others

You can indeed! (In fact, that’s pretty much how they work.)

For example:

BIT_FLOOR = 0
BIT_WALL = 1
BIT_CHAR = 2
BIT_ENEMY = 3

floorMask = BitMask32(0)
floorMask.setBit(BIT_FLOOR)
self.floorCollider.node().setIntoCollideMask(floorMask)

playerTerrainMask = BitMask32(0)
playerTerrainMask.setBit(BIT_FLOOR)
playerTerrainMask.setBit(BIT_WALL)
self.playerTerrainCollider.node().setFromCollideMask(playerTerrainMask)

enemyColliderMask = BitMask32(0)
enemyColliderMask.setBit(BIT_ENEMY)
enemy.collider.node().setIntoCollideMask(enemyColliderMask)

# The player "terrain" collider should now collide with
# the floor and walls, but not with the enemy

The manual provides another approach to something similar:
https://docs.panda3d.org/1.10/python/programming/collision-detection/bitmask-example

See the API for more information on the methods that BitMask32 provides:
https://docs.panda3d.org/1.10/python/reference/panda3d.core.BitMask_uint32_t_32

thanks a lot! that’s really helpful. Big Thanks

1 Like

Sorry for bringing back the issue but after changing it to different bitmask i still have same issue. after doing bit of debugging I’ve noticed that one particular entry is generated outside of collision range by my character, weird thing it’s the plane collider i use for my ground. When doing cNodeP.show() it shows im out of its range…
that’s the entries
[render/apple_char/Gcollision_apple_char into render/tGround/collision_tGround at 97.6874 110.6 0]

It looks like you have two things named “cNodeP”, one for your character and one for the ground. From the context I’m guessing that the one that you’re calling “show” on is the one associated with the ground.

If so, then I note that the collider that you’re using for the ground is a CollisionPlane. As far as I recall, a CollisionPlane is (theoretically) infinite in size: it extends in all directions without end. Thus there is no place outside of its collision range.

(If the debug representation looks otherwise, that may be for practical reasons: it’s much easier to create a debug representation that simply indicates the location and orientation of the plane than one that actually depicts an infinite expanse.)

i do have 2 nodes for my char but they have different id and handle, the plane when shown is only white within its texture range. Im not sure whether its indeed infinite

However when i remove it i fall all good. How do i replace it with polygon without stealing much processing power?

I’m very confident that it is infinite. The debugging representation is just a visualisation, I daresay.

Note how the manual describes it:
“The CollisionPlane is an infinite plane extending in all directions.”

A CollisionBox might be the simplest solution: it has a rectangular top-surface, is finite in size, is easy to construct, and should perform fairly well, I imagine.