Make agent face the direction of movement (SOLVED)

Hi, I’m trying to have an agent face the direction of movement. This should be a piece of cake with any good vector library. Any good vector library should have a function to create a rotation (quaternion) from a vector (say the velocity). The vector library in Defold doesn’t seem to have sucha function which is ridiculous. Or am I missing something?

Regards
Robin

There are some math functions here which might help you

https://www.bookofdefold.com/api/

You can use the Euler property on z for 2d facing rotation, and then use whichever method you want to calculate the direction to look at.

go.set(".", "euler.z", direction)

Under the hood it’s converted to quaternions.

See http://www.defold.com/ref/vmath/#vmath.quat_from_to

1 Like

go.set(".", “euler.z”, direction). Well then I have to make all the calculatations manually which is what I wanted to avoid with a simple function that creates a quaternion from a vector direction…

I’ve tried using vmath.quat_from_to() but I get weird results (sprite scales up and turns invisible):

go.set_rotation(vmath.quat_from_to(vmath.vector3(0, 1, 0), self.velocity))

Maybe this function doesn’t work like I expect it to. Note that sprite is facing up along the y-axis with 0 rotation (and thus has forward vector (0,1,0)).

Velocity implies that it can be of zero length. That won’t work well with that function. Try using the direction of the object instead?

I’m only setting the rotation if vmath.length(self.velocity) is greater than some small threshold but still getting that weird result. Not sure what you mean by “direction of the the object”.

Ok. What I meant was that I’d try using two vectors of length=1 as input to that function, I’m not sure if the function normalises the input vectors (I haven’t looked at the actual implementation).

Oh thanks that actually solved the issue. Bad of me to not normalize the vectors (the function is probably using a dot product or something).

The final working code:

if vmath.length(self.velocity) > threshold then
        local rotation = vmath.quat_from_to(vmath.vector3(0,1,0), vmath.normalize(self.velocity))
	go.set_rotation(rotation)
end
1 Like

I’m glad it worked! I think we should clarify this in the documentation (we have some good changes to this docs coming up in the next release, not sure if this case is one of them though).

1 Like

For reference, another way of making the agent face the direction of movement is using the math.atan2 function:

local angle = math.atan2(-self.velocity.x, self.velocity.y)
local agent_rotation = vmath.quat_axis_angle(vmath.vector3(0,0,1), angle)
go.set_rotation(agent_rotation)

I’m not sure which way’s the best one but this way seemed to produce “cleaner” rotations. But maybe it’s just my imagination!