Rotation and moving forward ? simple?

Okay so i have a rotating sprite i can get access to the rotation values but im lost on how to make it move forward in the rotated angle sure to be some math calculation in defold for making this part simple,

Also wondering how to make a sprite appear and disappear from a function also simple once you know how i guess.

Kind regards,

A.

Well simple enough to sort the moving issue out… now the simple question of making a sprite appear and disappear via script.

Use msg.post("#sprite", “enable”) and msg.post("#sprite", “disable”) if you want to toggle visibility

1 Like

Many thanks for a quick reply.

Will this code allow me to access one sprites visibility from another collections script ? not tested it yet just working on something else,

You will need a more specific url than “#sprite”, such as “default:/game_object#sprite”, but I think you can disable and enable components across collections

1 Like

Yes, and you can use partial url:s if you’re sending messages within the same world (main collection). Check out http://www.defold.com/doc/message-passing#_addressing_and_urls for details.

Hey guys,
i’m also struggling to make my objects move forward in their current facing. Any hints? Should be easy, but nothing i tried seems to work…

You should be able to pick a direction of your choosing, assuming it’s in the XY plane, and that the go.get_rotation() is a rotation around the Z axis. For instance, what direction makes sense to you when talking about “facing”?

Then, you should be able to do something like this to get your direction updated:

local rotation = go.get_rotation()
local direction = vmath.vector(1,0,0)
local updateddirection = vmath.rotate(rotation, direction)
local updatedposition = position + updateddirection * speed * dt -- or something similar

Read more here here. Big tip is to learn what available functions there is i the vmath module, that way it is easier to reason about what’s possible to do.

1 Like

Thx. Sadly the “pick a direction of your choosing” part ist my problem. The direction of my choosing is the one where the rotation of my object is facing. So if my object is currently looking left, i want it to move left. But how do i get a direction vector from of a rotation?

I already tried this code to get the x and y components i need:

local theta = math.rad(go.get(".",“euler.z”))
local dx = math.cos(theta)
local dy = -math.sin(theta)

dy looks fine, being 1 when looking upwards and -1 when looking downwards. But somehow dx is always positive, so i’m unable to determine if my object is looking left or right.

Am i on the correct path here (and if yes: what’s wrong?), or are there other/better solutions?

The rotation from go.get_rotation() is the total rotation of the object, so if you decide that your base direction is (1,0,0) (which is reasonable for a side scroller), then use that every time to update the current direction (my example).
The example I gave is how I rotate my vehicle in my current game, and every frame I update my direction.

What happens if you try my example? Does that not work in your case?

I created an example of how to let a game object have a facing and rotate around the Z-axis while moving forward and backward in the direction the game object is facing. The example can be found here:

And you can try it in your browser here:

http://britzl.github.io/publicexamples/rotate_and_move/index.html

left, right = rotate left/right
up, down = move forward/backwards

5 Likes

Thank you guys.

My problem was that i needed AI opponents in top-down perspective with full 360° movement which were supposed to patrol several positions. I first tried to avoid tracking their current facing/direction by myself and instead wanted to use their euler.z property to calculate their facing from by using the code in my last post.

This should have worked, but apparently the euler.z property is currently bugged. Now i tried your solutions which are keeping track of the object’s facing whenever they rotate. And currently this works like a charm. :ok_hand:

I wouldn’t say that euler.z is bugged. It just doesn’t behave the way you expect it to behave :slight_smile: If you print(go.get(".", "euler")) you will see that for certain angles it also rotates around x and y (ie flipping). This means that you can’t use euler.z as it is. You also need to account for the flipping. You could replace the update function in my example with this to get the same result without using your own facing variable:

local euler = go.get(".","euler")
local facing = math.rad(euler.x == 0 and euler.z or 180 - euler.z)
if self.rotate ~= 0 then
	facing = (facing + self.angular_velocity * self.rotate * dt) % math.rad(360)
	go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0, 0, 1), facing))
end

if self.move ~= 0 then
	local distance_to_move = self.linear_velocity * self.move * dt
	go.set_position(go.get_position() + vmath.vector3(-math.sin(facing) * distance_to_move, math.cos(facing) * distance_to_move, 0))
end
4 Likes

There’s a related issue in our backlog: DEF-1636 We should probably fix this since others inevitably will stumble upon this as well.

As @britzl mentions, it’s not a bug per se. What you’re seeing is a case of gimbal lock together with euler angles: wikipedia
Basically, you can have more than one euler.xyz representation for a rotation. Internally, we treat rotations as unit quaternions. So, when we convert the rotation quaternion into euler directly, which can have more than one solution.

That’s why I suggested to use the go.get_rotation() instead :slight_smile:

And in that case the update function would look like this:

local rotation = go.get_rotation()
if self.rotate ~= 0 then
	rotation = rotation * vmath.quat_rotation_z(self.angular_velocity * self.rotate * dt)
	go.set_rotation(rotation)
end

if self.move ~= 0 then
	local distance = self.linear_velocity * self.move * dt
	local direction = vmath.rotate(rotation, vmath.vector3(0, distance, 0))
	go.set_position(go.get_position() + direction)
end
2 Likes

But how did you make the game object move in the direction it is facing?
I am new to defold so i don’t really understand the basic code.
Can you or somebody add a copy/paste code snippet for everybody?
In my chase i need a ball to bounce on the walls.
The problem is how to make it move the way it is facing.
(Just so you know)
What i mean with code snippet (If somebody does not understand) is the following.

--Some random code snippet code will be displayed in this code snippet because it is a code snippet.

Just so if anybody new to coding wouldn’t understand.

Not sure what you’re asking for? I posted a link to a complete example further up in this thread.

This other solution may be little handy for someone… (Could even be faster since you don’t have to call rotation function from Lua, dev would confirm)

Add a child Game Object (directionDummy) to your Game Object, and set its position to : (1, 0, 0)

Anytime you want to know the direction vector of your root game object do this:

dir = go.get_world_position("directionDummy") - go.get_world_position())

Since the child object will rotate automatically by the engine every frame, its position in world space subtracting the position of the parent will coincide with its facing forward direction