Issue with cam updating with an onAction command within FlyCam

Hello all,

I am trying to setup a way to left click and make the mouse move at constant speed.

public void onAction(String name, boolean value, float tpf) {
if (!enabled)
return;

    if(name.equals("ForwardOn") && !value)
            move = !move;
    
    if(move == true)
    constantMove(false);
}

Each second the constantMove is called, which is basically a copy of moveCamera from flyByCamera.

protected void constantMove(boolean sideways){

    Vector3f vel = new Vector3f();
           
    pos = cam.getLocation().clone();
    vecL = new Vector3f(cam.getLeft().x, 0.0f, cam.getLeft().z);
    vecF = new Vector3f(cam.getDirection().x, 0.0f, cam.getDirection().z);
    

    if (sideways){
        vel.addLocal(vecL);
    }else{
       vel.addLocal(vecF);
    }

    vel.multLocal(moveSpeed/10);

    if (motionAllowedListner != null)
    {
        motionAllowedListner.checkMotionAllowed(pos, vel);
    }
    
    else
    {
        pos.addLocal(vel);

    }
     cam.setLocation(pos);  

}

The problem is, the camera will only update once, unless I press another key, then I will move forward + that other key i.e., if I press left with move on it will move left and forward. I do not understand how it doesn’t update when the same exact method is called, unless another key is pressed.

Any thoughts on this?

Thanks all for your time!

onAction is only called when the state changes. I think you probably want an analog listener…

1 Like

Gotcha, that makes sense. The doc mentioned on/off like “pause” so I figured my movement on/off would work in this case. I guess the same could work in the analog.

@KonradZuse said: Gotcha, that makes sense. The doc mentioned on/off like "pause" so I figured my movement on/off would work in this case. I guess the same could work in the analog.

“pause” would be a state change. You don’t need to remind the game to pause every frame. You tell the game to pause when it’s paused and you tell the game to unpause when it’s unpaused.

You could do similar with flying too but you’d have to have an update method that is called every frame. But you’d essentially be duplicating what onAnalog() would be doing for you.

@pspeed said: "pause" would be a state change. You don't need to remind the game to pause every frame. You tell the game to pause when it's paused and you tell the game to unpause when it's unpaused.

You could do similar with flying too but you’d have to have an update method that is called every frame. But you’d essentially be duplicating what onAnalog() would be doing for you.

Yeah I realize that, thanks for making it a bit clearer though, much appreciated as always.

EDIT: The only thing I’m noticing is that if I hold down the left click it calls the onAnalog over and over, instead of just once… With the onAction it seems to continuously call the method, whereas onAnalog only does it when you press?

I seem to have a bit of trouble just clicking the left button once and having it move forward. Will continue to mess around.

What is the behavior that you want?

onAction is called when the button is pressed. Once. And again when the button is released. Once.

onAnalog is called every frame while the button is down.

onAnalog is what the FlyCam uses to move forward since it is called every frame that the button is down.

FlyCam moves forward every frame while the button is down so it uses onAnalog since it is called every frame that the button is down.

@pspeed said: What is the behavior that you want?

onAction is called when the button is pressed. Once. And again when the button is released. Once.

onAnalog is called every frame while the button is down.

onAnalog is what the FlyCam uses to move forward since it is called every frame that the button is down.

FlyCam moves forward every frame while the button is down so it uses onAnalog since it is called every frame that the button is down.

I want to click the button once, and it to continuously move forward at a steady rate, and when I press it a second time, it shuts off.

I have OTHER keybuttons and other mouse movements mapped to the Analog which work as they should.

As I mentioned above when I press the button it goes to the constantMove method, and then moves once, but after it goes to the onAction method/the constantMove again it for some reason DOES NOT update, and only will update when another key is pressed, then both will move. So if I press right while move = true I will fly in a circle. It also moved forward again when I click the second time.

Thanks again for your time.

So, if the user presses the button and releases it then you want to continue flying?

You will need to have a method that is called every frame. I don’t know if this is an app state or a control or just some random class so I can’t really say how you would do that the easiest. Usually camera controls are best as an app state and then you have an easy way to get called every frame even if no input is happening.

@pspeed said: So, if the user presses the button and releases it then you want to continue flying?

You will need to have a method that is called every frame. I don’t know if this is an app state or a control or just some random class so I can’t really say how you would do that the easiest. Usually camera controls are best as an app state and then you have an easy way to get called every frame even if no input is happening.

Yes, exactly.

From the debugger it seemed that onAction is called every frame,a nd then calls the constantMove every frame. But again it’s not updated unless another key is invoked. It’s like the cam doesn’t want to update it’s position. I tried calling cam.update(); which doesn’t work either.

This is part of my main appstate when my game is running.

I’m not sure exactly how you are thinking about it, nor am I really that knowledgeable on appstates fully, but I do not see why I cannot be doing this in my normal FlyByCamera and Cam Appstate?

Here’s the logic you need:
onAction
-if released set move = !move

update(float tpf) (override the method on AppState)
-if( move ) move the camera

onAction should only be called for state changes. pressed then released. Not every frame… but either way. When there is no input then no input methods are called. So when there are no key presses you’re not going to get a bunch of “ok, keys are not pressed” messages. You’d be flooded with messages for every key on the keyboard every frame otherwise.

So you have to do that logic yourself as above.

@pspeed said: Here's the logic you need: onAction -if released set move = !move

update(float tpf) (override the method on AppState)
-if( move ) move the camera

onAction should only be called for state changes. pressed then released. Not every frame… but either way. When there is no input then no input methods are called. So when there are no key presses you’re not going to get a bunch of “ok, keys are not pressed” messages. You’d be flooded with messages for every key on the keyboard every frame otherwise.

So you have to do that logic yourself as above.

Gotcha, now I understand why you said appstate, I’m still using the simpleApplication for now.

I will see how it goes, thanks again.

Yup, works, thanks. I guess I figured that logic would work within the camera, but I guess somethings need to use the appstate.

Thanks for this insight.