Collision Entries - Trouble accessing From object's methods

So I am, again, stuck with the problem of interacting via collision entries. I’ve managed to access the actor from the entries, but I am now unable to acces the methods of the actor’s class. My basic setup is that I have a Moving() task-method and a Move() method within the Unit() class, and I want to, from within my World() class, trigger the Move() method in response to a right mouse-click, which activates the Moving() task.

The trouble is, I get “libpanda.NodePath has no attribute ‘moving’” when I try to call the Unit() class’s Moving() function via an instance of Unit() called ‘unit’. I have also tried adding the task to the taskmanager directly from the World() class, which was unsuccessful.

I thought that the way to call a class’ methods from within another class was to use an instance, and I believe that’s what I’m doing, so what’s the problem?

Here is the relevant code. First, the click-triggering:

    def rightClick(self):
        for i in range(self.moverHandler.getNumEntries()):
            entry = self.moverHandler.getEntry(i)
            if (entry.getIntoNode().getName() == "floorcollider"):
                for oldArrow in self.indicatorArrow:
                    oldArrow.remove()
                self.indicatorArrow = []
                pos = entry.getSurfacePoint(render)
                arrow = indicatorArrow(pos)
                self.indicatorArrow.append(arrow)
                for unit in self.selectedUnits:
                    position = unit.getPos(unit)
                    target = entry.getSurfacePoint(unit)
                    moveVector = target - position
                    moveHeading = math.degrees(math.atan2(moveVector.getY(), moveVector.getX())) + 90
                    if moveHeading < 0:
                        moveHeading += 360
                    unit.setH(unit, moveHeading)
                    unit.move(pos)

Then, the unit’s movement code:

    def move(self, pos):
        taskMgr.add(self.moving, "moving", extraArgs=[pos])

    def moving(self, task, target):
        self.pos = self.actor.getPos(self.actor)
        self.targetPos = target.getPos(self.actor)
        self.move = self.targetPos - self.pos
        self.moveX = self.move.getX()
        self.moveY = self.move.getY()
        self.moveZ = self.move.getZ()
        self.twoDdistance = math.sqrt((self.moveX * self.moveX) + (self.moveY * self.moveY))
        self.threeDdistance = math.sqrt((self.twoDdistance * self.twoDdistance) + (self.moveZ * self.moveZ))
        if self.threeDdistance > 5:
            self.actor.setY(self.actor, +40 * globalClock.getDt())
            return task.cont
        elif self.threeDdistance <= 5:
            return task.done

Keep in mind that I am trying to make the code viable even if several units are moving at once, RTS-style, which one reason it seems a better idea to have the movement handled in the unit class itself, rather than in a superordinate class.

Any and all help is greatly appreciated! :smiley:

You’ve run into the NodePath/Actor conundrum. A detailed description of the problem is given on the Subclassing page of the manual. For a workaround, use setPythonTag(); there are several examples in the forums.

David

Thanks for the tip! A little fumbling later, and I’ve got it working.