Basic Python script issue - Activation of Actuator isn't working properly

versuch track.blend (540 KB)

Hello

I want to have an object tracking another one if a key is pressed. As soon as the key is released it should track back to its starting position.

I’ve solved this problem with the logic bricks and its working fine.

But this issue is part of a bigger game I’m making and solving it all with logic bricks would be too complex.
So I need to do it in python.

In the annexed blend file I’ve made two scenes, one demonstrates how the result should be (solving it with logic bricks) and the other one shows the problem I have with the script.

The script doesnt give me any error messages but I have no idea why it isn’t working…

Hopefully someone knows where is the issue in my script.

Thanks a lot for your help!

You have to deactivate actuators.


if space.positive:
    cont.deactivate(tbmotion)
    cont.deactivate(TrackBack)
    cont.activate(motion)
    cont.activate(TrackTo)
else:
    cont.activate(tbmotion)
    cont.activate(TrackBack)
    cont.deactivate(motion)
    cont.deactivate(TrackTo)

If you’re already using a Python script, I would bother with the additional actuators. Here’s a simple script. You just need to enable True Level Triggering on the Always sensor.

import bge
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
own = cont.owner
space = cont.sensors['Space']

# choose the object to move to
if space.positive:
    target = scene.objects['Grab1.001']
else:
    target = scene.objects['ParentToBar.001']

# get the movement vector and limit movement speed    
moveVec = target.worldPosition - own.worldPosition
moveVec.magnitude = min(moveVec.magnitude, 0.4)

# apply the movement
own.worldPosition += moveVec

That is a brute force approach …

It might be fine wit ha few small controllers, but needlessly eats a processing power. (Do you check your mailbox every two minutes?)

I suggest following:

The “Always -> AND -> TrackTo” works as you need … it enables the actuator letting it run all the time (in native code … not Python).

A) When you press the key you want to reconfigure the actuator to a new goal.
B) When you release the key you want to reconfigure the actuator to the previous goal.

This involves that B) know about the status before A) … more specific we need to store the target before reconfiguring.

We need to code blocks for A) and for B), but we use the same entry point (because we are listen to the same sensor).


import bge

INTERNAL_PROPERTY_STORED_TARGET = "_internal.stored.target"

controller = bge.logic.getCurrentController()
owner = controller.owner

sensor = controller.sensors[0]
trackToActuator = controller.actuators[0]

if sensor.positive:
    owner[INTERNAL_PROPERTY_STORED_TARGET] = trackToActuator.object
    trackToActuator.object = owner.scene.objects["Cone.001"] #<= implement your object finder here

else:
    trackToActuator.object = owner[INTERNAL_PROPERTY_STORED_TARGET]
    del owner[INTERNAL_PROPERTY_STORED_TARGET]

This code does ONLY care stetting up the trackToActuator. It should not be connected to any other actuator.

Keyboard sensor -> Python controller -> TrackToActuator “Grab1.001”

As said, activating the actuators belongs to an AND (or any other) controllers.

I hope you see this is pretty flexible as you can exchange with any object you like (by replacing owner.scene.objects[“Cone.001”]) apply any object you like (e.g. detected by a mouse over sensor mouseOverSensor.hitObject)

Thanks a lot for these solutions! Very helpful, I will consider them as soon as I get to it.

Hello,

I tried all different kind of approaches but I definitely suck at programming (that’s why I love the logic bricks).
Maybe someone of you guys could help me finding the problem.
-After pressing the key the object isn’t returning to its start-position.
-I want the main object to traval to grab1 if the A-key is pressed, and to travel to grab2 if the S-key is pressed. If neither of them is pressed it should return to the starting position.

Unfortunately, with my script it doesn’t do any of these conditions :smiley:

Would appreciate any help!

Attachments

versuch track.blend (637 KB)

This is a complete different approach.

A simple solution would be 3 trackTo actuators triggered by the according key. This also solves the issue where to enter the new target (as you enter them at the according actuator).

For a Python solution I would like to know what you are aiming for (what happens when on what objects).

Ok, here’s an explanation for what I need this.
I am making a kitesurf game and want to animate the grabs. Unfortunately the animation doesn’t work so I found a workaround using the track-to actuator in combination with a motion. Which works fine using logic bricks.
I want the keys w,a,s,d to be used for every grab.
That means:

a - Nose grab (left end of the board)
a+w - Crail grab (left toeside edge of the board)
w - mute grab (toeside edge of the board)
d+w - Indy grab (right toeside edge of the board)
d - tail grab (right end of the board)
etc.

(here’s a reference for the grabs)


So there are in total eight combinations for the grabs.

Here’s a little demo how I solved it with logic bricks.
Maybe that’s the way to go.
By the way… What is better for the performance - using complex logic bricks or a complex script?

Attachments

versuch track.blend (687 KB)

I just figured out, that I can save a lot of bricks even in the logic editor.

I guess I will stick to the logic bricks, since this solution doesn’t seem too bad…
Here’s an updated version:

Attachments

versuch track.blend (686 KB)

I would go in for a state machine. This way you can use a few controls to get lots of different requests. But this really depends on your situation. Just now I can’t really tell if it is sufficient or not.

8 grabs are not that much. I’m sure this is not even a problem with logic bricks. You might need some more dynamic later on. That requires Python as logic bricks have typically a static setup. I suggest to look at this as soon as you need this.

The above code is an example. It dynamically reconfigures the actuator. But as there is no dynamic input (what object to assign as target) there is no benefit. You can achieve the exact same effect with a few logic bricks. The difference would come if you want the result of an - lets say - raysensor to be configured. A logic brick can sense an object, but can’t assign the actuator to it. Here the Python controller makes sense. It can grab the object from sensor and apply it to the actuator. But … just that. Everything else can still be handled by other logic bricks. There is no need to mic in other code that does other things.

Performance depends on how you implement. Both ways can result in inefficient code. Beside of that you need to look what is better for maintenance. Very efficient code has less use when you can’t support it (e.g. develop it further or fix bugs). This belongs to logic bricks mess as well as to Python code mess. There is no difference (it just looks different … like different mess :wink: ).

hehe, ok, thanks anyway for all given hints and help.
I’ve solved it as you suggested with the logic bricks states. Never had used these before and they give a whole new world of possibilities. I used to solve most of the problems with properties.