(Solved) Issue with set_rotation seeming to be 1 step behind

Here’s my code for updating the angle of my turret:

function update(self, dt)
	if self.commanded_target ~= nil then
		local target_angle = go_transform_angle(go_angle(self.commanded_target))
		local current_angle = go.get_rotation().z

		local angle_diff = angle_difference_2d(target_angle, current_angle)
		local dt_angle = angle_diff * 0.5 -- *dt
		go.set_rotation(vmath.quat_rotation_z(current_angle + dt_angle))
		print(current_angle, angle_diff, dt_angle, dt_angle * 0.1)
	end
end

I have validated angle_difference_2d etc.
If I set dt_angle = angle_diff, then everything works perfectly.

Instead, I wanted an easing effect, so I used dt_angle = angle_diff * 0.5.
(Eventually, I want to apply limits on the rotation speed, but let’s not complicate the issue)
I expected angle_diff to halve each tick, causing the turret to approach its target.

But what happens in reality is that current_angle is never updated as I would have expected by go.set_rotation and so the turret always gets stuck pointing exactly halfway between its initial orientation and its target.

I’ve had a similar vein of issues all week trying to ease between angles using get_rotation and set_rotation. Any ideas?

Here’s the excerpt of the print:

...
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|
|DEBUG:SCRIPT: hash: [/collection1/lhs_blaster]|-0.76081192493439|-1.936629256365|-0.96831462818252|-0.096831462818252|
|DEBUG:SCRIPT: hash: [/collection1/rhs_blaster]|0.80382585525513|2.1271444966362|1.0635722483181|0.10635722483181|
|DEBUG:SCRIPT: hash: [/collection0/lhs_blaster]|0.39581388235092|0.83618808605233|0.41809404302617|0.041809404302617|
|DEBUG:SCRIPT: hash: [/collection0/rhs_blaster]|-0.42112246155739|-0.89648520595394|-0.44824260297697|-0.044824260297697|

You can see if you follow the same object down the line (for example, collection1/rhs_blaster) then its position doesn’t change between updates at all, but dt_angle is clearly not insignificant.

It is, as though, set_rotation does nothing.

The problem you are experiencing originates from here. What go.get_rotation actually returns is not a vector3 as you set them on a gameobject, but rather a Quaternion. In simple words, go.get_rotation().z does not return what you are looking for. A solution would be to use Euler angles instead of the go.get_rotation.

local current_rotation = go.get(".", "euler.z")
2 Likes

It seems like euler.z is in degrees.

At first I thought it wasn’t working, but the angles were so small I couldn’t notice them.

You can always use math.rad(x) to get it in radians :slight_smile:

Yep, works well :slight_smile: Thanks
Are euler angles always in degrees? Would it be a good idea to add it to the manual.

1 Like

It’s in the game object API doc: https://defold.com/ref/go/#euler Possibly it should be mentioned somewhere else?

1 Like

Ah, I never found that one. I only managed to find https://defold.com/manuals/properties/?q=euler#game-object-and-component-properties .

1 Like

We’re happy to accept pull requests to the documentation too!

1 Like

Sorry guys, one last thing - I read a bit into go.animate and realized the docs say not to manually animate objects like I was doing in the first post. So I gave it a shot using go.animate instead;

function update(self, dt)
	if self.commanded_target ~= nil then

		local current_angle = go.get(".", "euler.z")
		local target_angle = go_transform_angle(go_angle(self.commanded_target))
		local shortest_angle = angle_difference_2d(target_angle, current_angle)
		local duration = math.abs(shortest_angle) / self.rotspeed

		go.animate(".", "euler.z", go.PLAYBACK_ONCE_FORWARD, current_angle + shortest_angle, go.EASING_LINEAR, duration)
	end
end

Works great, just one thing - do I need to call go.cancel_animations if I constantly set the rotation like this?

If it’s something that you need to recalculate every frame (like aiming at a moving target), then just set it every frame and don’t use go.animate. Calling go.animate on the same property every frame doesn’t make sense, since it needs multiple frames to actually animate.

If you want to change a property over time, and its ending value is fixed, then use go.animate.

5 Likes

And the documentation is here: https://github.com/defold/doc/blob/master/docs/en/manuals/properties.md#game-object-and-component-properties