Parabolic arc movement in a custom behavior (SOLVED)

Greetings,

I’m currently trying to remake the parabolic arc example: GDevelop 5
My goal is to move everything into a function call to hopefully make it more intuitive and reusable (Plus, remove the “one-bullet-at-a-time” restriction).
So far, I got everything coded in, although, I’ve run into a problem…
You see, in the original example, there’s an extra event which makes the bullets move, but since I’m using a function call here, things get complicated…
When this event is IN the function, the bullets ONLY move when the function is running. Plus, ALL the bullets reset their trajectories and move again for some reason…?
When this event is OUTSIDE of the function, it just straight up doesn’t work since the arguments being used in the function don’t exist outside of it.
Here’s the code:


And the function (The code that moves the bullets is at the bottom):

Basically, how do I get the bullet to move while preserving the function’s reusability? Or am I trying to have my cake and eat it too?
Additionally, if I want each bullet to act individually, would I need to convert these scene variables to object variables instead?
Thanks in advance

I went on a bit here but I couldn’t sum up my opinion in just a few sentences. This is simple and complex at the same time. Bear with me and know that I’m not in any way making any judgement. It’s all good.

I’m wondering if this would be better as a behavior. Then it could run on its own without the need to add an action that runs all the time. I looked at 6 other extensions that used movement and they were all behaviors. That way they could calculate the values and if needed use properties or object variables and then execute the movement with the step events. I’m not as experienced with behaviors.

I would suggest that you look at existing movement extensions and see how they work.

I’m no expert but this is how I see the best practices with functions. Functions shouldn’t retain any data. That’s why they take parameters that work as a handoff. It keeps it isolated. With expressions, the return action hands off any new value. The best practice would be for any value that is used by the function to either be calculated each time within the function or stored in the main part using a variable and then be handed off to the function each time through parameters.

Functions or expressions should behave the same way no matter what has happened in the past or which event is calling it. I just don’t see this working as a function. You might be able to create expressions that would calculate things and store their values in variables and then hand them back to a function but at that point you might as well just use a behavior. I definitely would want to recalculate things each time. IDK.

We all create things for personal use that break the “best practices”. I’m not making any judgements. But there are some things that just don’t work. Or at least not efficiently. And sometimes doing things easier later takes a lot of work to set up. The payoff comes later each time it gets used.

You should have made it a behavior, that is what you use to run code without the user prompt.

Alright, I understand, I went and studied a few of them behaviors and how they worked and took a stab at converting my function to a behavior instead. So far, this is what I made:


Action (That trigger once up there is just for testing, just ignore it):

StepPostEvents:

Some major differences is that the behavior no longer creates the object, and as such, the source is no longer required as a parameter, which allows it to also be used for objects that already exist on the scene. Also, all the scene variables have been converted to object variables instead, hopefully to make each object act individually.

Sadly, I’ve run into a new issue. I put a bullet on the scene, and it just doesn’t move at all, no matter how many times I press the spacebar.

After some testing and debugging, I’ve concluded that the reason why is because the values in the action event are just not increasing. Like, at all. So therefore, the bullet has nothing to work with, and simply doesn’t know what to do when I give it a command.

Am I getting warmer? Is there something I still need to do to get these values to update properly?

So, is what I’m doing not possible then?

I don’t think it sounds impossible in the least. I haven’t really examined your code but what you want to do sounds doable. You could look at similar extensions and see how they do it.

I might do it like a spawner. Use the object with the behavior as the spawn point, create an object using an action. Link the projectile to the spawner. Then you can get the linked projectiles from the behavior and control them.

My best advice is look at the events of behaviors that spawn and ones that control object movements. See how they do it.

You need to create it outside the behavior (in the extension) and then it will do things at OnCreated and doStepPostEvents.

I’m trying to get the code to work like I want to, but no matter what I try, the bullet simply isn’t moving.
I tried studying the events, but I just can’t get mine to work like the behaviors did? I’m really struggling here, the object variables for the bullet aren’t changing, and I don’t know how to get them to change. I even tried On Create, and that had no effect either…

Also

That’s the thing, the object not being created is INTENTIONAL. I’ve abandoned the idea of creating the object within the behavior to make it useable for objects already on the scene. I don’t want the behavior to spawn the bullet directly

The code is the same as before, nothing I tried worked. How do I get those variables (TargetX, TargetY, Speed, Arc, and vox) to change? Is there a specific method I need to put them in, or do I need a missing part?

Can you post your events? I played around with your idea. I didn’t try the formula, I’m not in the right mode. You can use the behavior as a spawner but it requires functions to reference a bullet object to both create and to control. They seem to then use a link to track the objects.

But… if you make the object that has the behavior the bullet then you just create that object through events like you were adding any object. Then you can control it through the behavior.

scene action

step event action

Alright, here’s the main code block that should move the bullet (There’s one bullet on the scene already).
Ideally, there would be more code to specify which bullet to refer to, but for the time being, I just want to get the one already on the scene to move.


The behavior, the inside of the action, which should set the variables to prepare the bullet to move.

And now the runtime event, which makes the bullet move.

And here’s the debugger. This is the results after I press the spacebar. All the values are 0, and the position variables are just the bullet’s own position, meaning it’s not getting subtracted by anything like it should…

Did I set this up the wrong way? Am I still missing an important method?

Also, I apologize for not being proficient with custom behaviors, this is my first time truly making one. Functions are fine with me, but custom behaviors just destroy me

Edit: I’ve just now realized that the Arc variable in the runtime event is referencing a scene variable instead of an object variable, I went ahead and changed it to an object variable. Code still doesn’t work though

Note: My example projects are sloppy and not necessarily the best way or practice. This is a bit new to me.

From what I can tell by looking at the other extensions, this is basically how they work. They use at least 2 actions. One runs on every frame that works like the do event but it provides the bullet object. The other action adds the bullet and links it to the object with the behavior.

project:

I like the 2nd version. With this version, the behavior is assigned to the bullet instead of a spawner. It’s sort of like the physics behavior. My example is a bit chaotic because I don’t truly understand the behavior best practices.

source:

I started to play around. It uses behavior properties instead of variables. I initially set the values through actions, While you can still do that, the settings can be added to the move function. You can set them on the behavior screen or for instance through action. Like any action, you need to pick the object like after the action to add the object otherwise it changes all of the objects.

You can add the functions to change and get the property value by clicking the 3 dots.

Play around with both versions. If you have questions, I’ll try to help.

I appreciate you testing this out for yourself, but unfortunately, this isn’t quite what I’m looking for.
This is a sine wave, not a parabolic arc. Although, it did kind of give me a little nudge in the right direction.

I’ve decided to also compare my behavior to the boomerang behavior, and I’ve made some major changes.

I’ve changed every object variable to GetArgumentAsNumber() instead, since apparently, custom behaviors don’t work very well with variables.

The object variables in the lifetime event have been changed to Object.Behavior::Property instead.

I’ve added new actions to modify the behavior further, since I’ve discovered the option that automatically creates them, although, I’m probably not going to need those for now.

At last, I’ve finally got SOMETHING to happen. Not the thing I want, but SOMETHING.

When I press the spacebar, the bullet just vanishes from the scene entirely. Poof, gone without a trace.

The debugger reads that the Y position of the bullet has not changed, but the X position reads NULL…

I feel like I’m getting close, something is happening at last, it’s just missing something else important…

Here’s the code:
The main code block running the behavior:


The behavior’s action:

And the lifetime event:

Again, I’m comparing this to the boomerang example, so I tried to get it as similar as I could. Is there anything else I’m missing here?

Sorry, I should’ve said that the formula I used was just to test the behavior’s abilities.

If it’s null then I’m wondering if you’re getting a division by zero error or maybe the property name is wrong. IDK. Try displaying vox in the debugger. See what it’s value is.

Can you see behavior properties in the debugger. Maybe if you click that lightening bolt icon. Yes, clicking whatever that lightening bolt icon is called allows you to expand into the behavior values.

Alright, I’ve logged the value of vox using the debugger, and when I press space, the value always reads zero…


In fact, all of these just return zero. Something isn’t working correctly, but I can’t seem to figure it out

EDIT: Upon closer inspection, when I manually add the values into the behavior, the bullet no longer disappears, but when the scene starts, it just moves automatically. It doesn’t even move in an arc, it just moves straight down…?

Something with the formula that dynamically changes the values must be wrong somehow, I can only assume that without the manual behavior inputs, using the formula makes the ball fall down so fast, te game can’t keep up. I’m not sure how it could be wrong though, it’s practically copied from the ready made parabola example…

Are you logging the values before or after they’re set?

edit: I’m still learning behaviors myself. FYI… There are 2 types of properties. The behavior is the same on in the behavior settings. it works on an instance level. The scene property is shared. It’s like a scene variable. Just make sure you’re using a matching set.

Sorry for taking so long to reply, I realized how messy my code was and decided to start over from scratch.
I now have a much cleaner and more compact version of the code, and it even nets better results:

However, it only works well when it’s in events…
Once I try to put it in a custom behavior to make it reusable, things start to go wrong again…
The single codeblock:

The behavior action (Variables don’t work btw):

DoPreStepEvents:

The same issue as before, the X and Y positions return as NULL

I have no idea what I’m doing wrong, aside from the variables being swapped out for “Change Property Value” and “Object.Behavior::Property,” this code is practically the exact same. I even tried copy pasting the variables directly into the behavior and only got the same results…

This is the same code used in the events, so why isn’t it the same in the behavior?

You can use property names directly in expressions (the same way as variables). Your events will be easier to follow.

Is there a reason why there are trigger once conditions in the behavior but not the non-behavior?

behavior

Ahhh, I forgot, thanks, that makes it simpler to read now!
Also, I’m not sure why I put them there. I guess it was my attempt to stop the values from changing so much that the debugger returns NULL. Unfortunately, removing the trigger onces didn’t work…

EDIT: I’ve tweaked with the thing a little bit and got a different result:


The two code blocks on the bottom. For changing the Y position (The arc movement), I changed the direct position changes with SelfY properties.
As a result, the objects are now being fired towards the target in an arc, but they’re doing so REALLY fast, and at a hugely overexaggerated arc. So fast that they’re on screen for only a frame, vanish, then come on screen again at the target’s position and disappear…
Also, then they spawn, they briefly warp to the bottom left corner of the screen for some reason
There must be one last thing I’m missing here, but I’m not sure what it could be?

I don’t see anything. I don’t understand the formula, so I can’t help with that.