I’m trying to rotate the sword 90 degrees like a swinging motion, so it has to be smooth, but whenever I add code besides the original movement code, it breaks all the code for it. There are no consol or build errors when I run the game, and the other game object work fine. By the way "swing refers to left click.
First, you are using go.get_rotation
, which is used to read the current rotation of the object, but not change it. You have to use go.set_rotation
to set the rotation.
Second, go.set_rotation
will need a quaternion as argument, not three numbers in degrees.
Third, you most likely want to rotate against the z axis, not y axis. In your screenshot, the red line is the x axis, the green line the y axis, and the z axis is from your point of view, which you want to rotate around.
So you have to use this for an instant 90 degrees rotation:
go.set_rotation(vmath.quat_rotation_z(90 * math.pi / 180))
Or use go.animate
for a smooth rotation:
local duration = 1.0
go.animate(".", "euler.z", go.PLAYBACK_ONCE_FORWARD, 90, go.EASING_INOUTSINE, duration)
If “Sword” is the correct address from that script, it should work to rotate the object once.
It doesn’t work. “Sword” is the game object. Also, the movement script still doesn’t work (not the rotate the normal movement) unless I remove the rotate script.
Make sure that you pick the correct address of the game object (see Addressing in Defold).
And is the line of code even called, for example if you do print("Test")
there? Or else the input focus or action id might be wrong.
Please don’t include code as a screen shot. Include it as text instead!
You probably only want to trigger the attack animation on the first frame when the key is pressed?
if action_id == hash("Swing") and action.pressed then
go.animate ...
end
This is the current code for the Sword:
function init(self)
msg.post(".", "acquire_input_focus") -- <1>
self.vel = vmath.vector3() -- <2>
end
function update(self, dt)
local pos = go.get_position() -- <3>
pos = pos + self.vel * dt -- <4>
go.set_position(pos) -- <5>
self.vel.x = 0 -- <6>
self.vel.y = 0
end
function on_input(self, action_id, action)
if action_id == hash("Up") then
self.vel.y = 300 -- <7>
elseif action_id == hash("Down") then
self.vel.y = -300
elseif action_id == hash("Left") then
self.vel.x = -300 -- <8>
elseif action_id == hash("Right") then
self.vel.x = 300
end
end
function on_input(action_id, action)
if action_id == hash("Swing") and action.pressed then
local duration = 1.0
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 90, go.EASING_INOUTSINE, duration)
end
end
You can only have one function with the same name. So one on_input()
is ignored, as a function with that name already exists. Also your second on_input()
forgot the self
, which has to be the first argument, as they are defined not by name, but order.
You have to put the code in a single on_input()
, like this:
function on_input(self, action_id, action)
if action_id == hash("Up") then
self.vel.y = 300
elseif action_id == hash("Down") then
self.vel.y = -300
elseif action_id == hash("Left") then
self.vel.x = -300
elseif action_id == hash("Right") then
self.vel.x = 300
elseif action_id == hash("Swing") and action.pressed then
local duration = 1.0
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 90, go.EASING_INOUTSINE, duration)
end
end
How would I make it wait 0.1 secs and then return to the previous position, because the current code isn’t working.
go.animate(/Sword, euler.z, go.PLAYBACK_ONCE_FORWARD, -290, go.EASING_INOUTSINE, duration) | ||
---|---|---|
timer.delay(0.1, false, self) | ||
go.animate(/Sword, euler.z, go.PLAYBACK_ONCE_FORWARD, 290, go.EASING_INOUTSINE, duration) |
You can give a callback function to go.animate()
that will run after it is done, like this:
function on_input(self, action_id, action)
if action_id == hash("Up") then
self.vel.y = 300
elseif action_id == hash("Down") then
self.vel.y = -300
elseif action_id == hash("Left") then
self.vel.x = -300
elseif action_id == hash("Right") then
self.vel.x = 300
elseif action_id == hash("Swing") and action.pressed then
local duration = 1.0
local delay = 0.1
go.cancel_animations("/Sword", "euler.z")
go.set_rotation(vmath.quat_rotation_z(0), "/Sword")
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 90, go.EASING_INOUTSINE, duration, 0, function(self, url, property)
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 0, go.EASING_INOUTSINE, duration, delay)
end)
end
end
Is there any way to stop people from doing this?
You could set a variable (for example attacking
) to true
when the attack starts, and only set it to false
when the attack is done. Then only allow the attack to start if the variable is false
.
I did that but is there a reason why the variable changes after only the first swing?
Here’s the code:
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, -290, go.EASING_INOUTSINE, duration, 0, function(self, url, property)
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 0, go.EASING_INOUTSINE, duration, delay)
attacking = false
So you only want the player to attack again if the sword has returned to the starting angle? Then you have to set attacking
to false
in the callback of the second (inner) go.animate()
, not in the callback of the first (outer).
Wait what, like in the (), where.
For example like this:
local function attack_done(self)
self.attacking = false
end
function on_input(self, action_id, action)
if action_id == hash("Up") then
self.vel.y = 300
elseif action_id == hash("Down") then
self.vel.y = -300
elseif action_id == hash("Left") then
self.vel.x = -300
elseif action_id == hash("Right") then
self.vel.x = 300
elseif action_id == hash("Swing") and action.pressed and not self.attacking then
local duration = 1.0
local delay = 0.1
self.attacking = true
go.cancel_animations("/Sword", "euler.z")
go.set_rotation(vmath.quat_rotation_z(0), "/Sword")
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 90, go.EASING_INOUTSINE, duration, 0, function(self, url, property)
go.animate("/Sword", "euler.z", go.PLAYBACK_ONCE_FORWARD, 0, go.EASING_INOUTSINE, duration, delay, attack_done)
end)
end
end
It works! Thank you for helping me through all this.