Parabolic arc movement in a custom behavior (SOLVED)

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.

I changed some of the code out of trial and error (I’ve disabled the booleans for now since they aren’t working for some reason)

I dropped the SelfX and SelfY properties and just went back to using Object.X() and .Y() instead, and got a different result:
GDevelop_RcQil4yXIO

This is getting close to what I want, but not quite. The objects are quickly lerping ABOVE the target and THEN slowly falling down towards the targeted destination, not the smooth arc motion I’m looking for…

As a reminder, here’s the code in event form and what it looks like:


GDevelop_JqFjw78C9a

Therefore, I know for sure that there’s nothing wrong with the formula since it works perfectly in the events. Something is wrong with how the behavior is handling it, and I’m just stumped on what it could possibly be.

Is there anybody who’s proficient at custom behaviors? I’ve tried studying multiple, but I just can’t wrap my head around why those work, but mine doesn’t…

1 Like

I can’t figure out what’s wrong, so I tried to create it from your events that don’t use the behavior. I didn’t use the behavior properties, I kept it to the object variables. I just copied and pasted the code and reworked the events. The framework is there. It’s just a matter of swapping object variables for behavior properties.

project:

try me, click anywhere

I decided to try to switch it to properties instead of object variables. It seems to work. I made some slight changes. I changed the keep going property to a Boolean instead of the toggle object, so, it needs to be called differently based on the toggle because you can’t pass Booleans.

new project:

I renamed the action to setup because it sets up the properties, the object will move automatically once added to the scene. Name it whatever.

I added a property called initialized to set the startX and startY once in the step events. I guess you might be able to use trigger once there but I prefer a variable. The way it is now, it will fire to the behavior settings whether there’s a setup event or not. You can verify that by adding an object in the scene editor and setting the object’s behavior settings. All of the instances will use the same values unless you change it with events as runtime just like other behaviors.

2 Likes

Sorry for the upcoming wall of text

Thank you so much, I can’t believe it was that simple. After checking out your example, here’s what I changed with mine:


I’ve added the initialization event to initialize the starting point like you suggested, something I originally thought had to be set up in the action, not the doPreStepEvents. I never would’ve guessed this in a million years, but it works perfectly!

Also, thank you for pointing out I was setting up my booleans incorrectly, I was just using simple toggles, not actually checking if the properties were set to true or not. As a result, my booleans are working in ship shape too.

I DID run into one minor error along the way, but I was able to figure it out.

Creating objects and moving them works flawlessly, but in the event where I may have to apply this behavior to an object already existing on the scene (Like an enemy that tries to jump on you for example), things don’t work out as planned.

GDevelop_Mpw5ndHZ8M

As you can see here, when the scene loads, the two objects I have loaded in at the start instantly snap to coordinates 0,0 for whatever reason, likely because there aren’t any values for StartX and StartY yet.
Once I click, both objects snap right back to the spots I originally put them in and function seemingly normally. However, if I click again either when they stop or mid-flight, they snap back to their starting positions. My hope is to make it dynamic so that they take their CURRENT position and jump from THAT spot instead of snapping back to where they started.
I tried removing the Trigger Once initialization, and it DOES make the object move dynamically, but unfortunately, that causes the weird fast arc and slow falling again.
Instead, I tried to use an initialization variable like you suggested. In addition, I added another boolean check that turns the initialization off when the code is re-run:

And now, it’s working ALMOST perfectly. The object now actually jumps dynamically from it’s current stop exactly how I wanted it to…

…BUT it still snaps to position 0,0 when the scene starts up.

I tried to make an OnActivate event that is meant to try and save the current position on loading the scene or activating the behavior, but no such luck, it still snaps the object to 0,0:


GDevelop_x922OtzjTr
(There are two objects in the scene btw, they’re both stacked on top of each other)

For objects placed on the scene when it starts up, how can I get the objects to STAY in the spot I put them in the editor?

1 Like

You have a lot of options. My versions is a bit like the physics behavior. It kicks in the second the object is added or the scene starts.

You probably want it more like the pathfinder behavior where you use an action to start the movement. You can have as many expressions, conditions and actions as you need.

If you already have all of the events in the step function controlled by a boolean property then you can also have my initionialzation boolean or maybe a trigger once to reset the start x, y. You could also add a function to trigger a reset. Or when the move action is triggered it always updates either the start x, y or sets the init boolean back to false. I can only recommend that you keep experimenting since you seem real close.

I don’t know enough about behaviors on how they work with certain things. It’s mostly the same but there are some slight differences.

Alright, I’ve done some experimenting, and I just couldn’t get it to work for the life of me. No matter what I tried, the result either didn’t change, or just started that weird slow falling arc again.
Although, I was able to get a few pointers.
After experimentation, I can confirm that this codeblock is the culprit:


I tried moving the position change into a disabled codeblock, and when I tested, sure enough, the objects appeared directly where they should be on startup as intended, but once I run the code, they go flying off the top of the screen.
I tried to add triggers and variables to try and force the code to only run once the behavior is called, but no matter what I’ve tried, the code absolutely insists that it needs to snap the objects to the top left corner on startup, even though nothing is being called.
I tried the beginning of scene, I tried messing with the initialization variable, I tried putting the positions directly into the behavior properties, I even tried moving everything from doStepPreEvents, to doStepPostEvents, thinking that the code was being run before the actions, but sadly nothing worked.
Eventually, I sidetracked and decided to make a condition that returns true once the object has reached it’s targeted destination. Tracking the position only works sometimes and wasn’t reliable, but eventually, I figured out with the use of the debugger and original events that having the code check if the T variable is equal to 1 does the job perfectly:


(Yes, I’m aware that the behavior call and create event are out of order here, I fixed it)

This condition works very well, but at the same time, it’s revealed another thing about the issue. If I place objects into the scene and run it, the objects are gone. The game deleted them. I tried replacing the delete action with a color tint, and sure enough, the objects were tinted that color on startup.
So for some reason, the objects already placed on the scene think they’ve already reached their destination, despite the actions not being called.
I also assume that since the values by default are initially empty, the game reads the SelfX and SelfY values, reads 0,0, then just instantly snaps the object to that when the above culprit code is launched.

So basically, I’m trying to figure out how to launch the code ONLY if the action has been called, but again, nothing I tried did anything productive, I was only able to find WHAT was going wrong, but have yet to figure out HOW to fix it.

1 Like

If you don’t want the object to move then you can place all of the events in the steps function as a subevent of a condition that checks a boolean parameter. Have it set to false by default. You can use the function that sets the values and have it also set the boolean in the step event to true. Or you could create a function like play that does nothing but set the boolean to true.

The main thing is you want to prevent all of the events in the step function from running until you want them to. At the same time make sure it updates the start x, y once when it starts.