Renaming Input Binding Action changes crated Factory Bullet velocity

Hello!
I have encountered a weird behavior and I can’t figure it out. I am new to Defold but I have now spent my entire day trying to solve this issue. To me it is still a mystery.

The Problem:
When I change the input action name for the Spacebar input, for example from “space” to “shoot1” to “kaboom” I get different velocities for my bullets depending on the direction I am moving. The Bullets will either pick up the velocity of the parent game object (the intended behavior) or have no velocity (the bug).

I will provide the entire project on Github, it is a simple project with a 2k background image so the download shouldn’t be too bad if anyone would like to see the whole thing.

https://github.com/CobaltMongoose/DefoldIssue1

The trouble spot in code is in the PlayerController script involving line 26, 34 and 53 - 63.
But as I stated, simply altering the Input Action name for Spacebar in the Game.Input_Binding file will change the behavior on my Windows 10 Desktop.

Hopefully a wiser coder can show me what I’ve done wrong.

--velocity property
go.property("velocity", vmath.vector3(0,0,0))

go.property("Gun", msg.url())
go.property("FireRateInMS", 333)
go.property("ProjColor", vmath.vector4(1, 1, 1, 1))
go.property("ProjSpeed", vmath.vector3(0, 0, 0))

-- Declare Local Variables

local fireTimer = 0

function init(self)
	-- Acquire Input Focus for the entier game object.
	msg.post(".", "acquire_input_focus")
	fireTimer = 0
end

function update(self, dt)
	fireTimer = fireTimer + dt
	if fireTimer > 1000 then
		fireTimer = 999
	end
	
	-- Update the arrowMove Character's Postion based on velocity and time since last update 
	go.set_position(go.get_position(".") + self.velocity * dt)

	
	--self.velocity.x = 0
	--self.velocity.y = 0

	--for some reason this results in a bullet that will not take a velocity in the right or +x direction.
	--comment out this line and the projectile will take on the right or +x velocity.
	self.velocity = vmath.vector3(0,0,0)

	
end

function on_input(self, action_id, action)
	if action_id == hash("up") then
		self.velocity.y = 150
	end
	if action_id == hash("down") then
		self.velocity.y = -150
	end
	if action_id == hash("left") then
		self.velocity.x = -150
	end
	if action_id == hash("right") then
		self.velocity.x = 150
	end

	pprint(self.velocity.x, self.velocity.y)
	if action_id == hash("space") then
		if fireTimer > self.FireRateInMS / 1000 then
			fireTimer = 0
			local pos = go.get_position(".")
			pos.z = pos.z - 0.1
			local rot = go.get_rotation(".")
			local vel = self.velocity
			factory.create(self.Gun, pos, nil, {color = self.ProjColor, BulletVelocity = vel})
		end
	end
end

Some observations:

  • You reset self.velocity every frame in update()
  • This means that the bullet will only ever receive a velocity other than zero if you move and press space in the same frame
  • This may not be a problem but it actually depends on the repeat interval in your input settings. The default value is 0.2 seconds which means that unless you changed it to 0 you’ll not always get both a direction and space key press in the same frame.
1 Like

Thanks for taking a look. I set the Repeat Interval to 0 as you suggested but the behavior persisted.

I noticed that I bungled the first upload of my project on github, it lacked the script files.
This should be the corrected project link:
https://github.com/CobaltMongoose/DefoldIssue_V2

I modified the PlayerController script to add a dampening effect to the movement velocity instead of setting it straight to zero when there is no input.

In the debug output I see that when moving right and shooting the velocity is decreased much quicker than when moving and shooting in the other directions. I am still scratching my head at why that would be.

Maybe my entire approach to moving the ship and shooting is wrong? I’m open to suggestions!

--velocity property
go.property("velocity", vmath.vector3(0,0,0))

go.property("Gun", msg.url())
go.property("FireRateInMS", 333)
go.property("ProjColor", vmath.vector4(1, 1, 1, 1))
go.property("ProjSpeed", vmath.vector3(0, 0, 0))

-- Declare Local Variables

local fireTimer = 0

function init(self)
	-- Acquire Input Focus for the entier game object.
	msg.post(".", "acquire_input_focus")
	fireTimer = 0
end

function update(self, dt)
	fireTimer = fireTimer + dt
	if fireTimer > 1000 then
		fireTimer = 999
	end
	
	-- Update the arrowMove Character's Postion based on velocity and time since last update 
	self.velocity.x = self.velocity.x * dt
	self.velocity.y = self.velocity.y * dt
	self.velocity.z = self.velocity.z * dt
	local current_position = go.get_position(".")
	current_position = current_position + self.velocity
	go.set_position(current_position)

	
	--self.velocity.x = 0
	--self.velocity.y = 0

	--for some reason this results in a bullet that will not take a velocity in the right or +x direction.
	--comment out this line and the projectile will take on the right or +x velocity.
	--self.velocity = vmath.vector3(0,0,0)

	--trying dampening instead of hard reseting velocity to zero
	if vmath.length(self.velocity) > 0.0005 then
		self.velocity = self.velocity * 0.5 --vmath.vector3(0.5,0.5,0.5)
	else
		self.velocity.x = 0
		self.velocity.y = 0
	end

	
end

function on_input(self, action_id, action)
	if action_id == hash("up") then
		self.velocity.y = 150
	end
	if action_id == hash("down") then
		self.velocity.y = -150
	end
	if action_id == hash("left") then
		self.velocity.x = -150
	end
	if action_id == hash("right") then
		self.velocity.x = 150
	end

	pprint(self.velocity.x, self.velocity.y)
	if action_id == hash("shoot") then
		if fireTimer > self.FireRateInMS / 1000 then
			fireTimer = 0
			local bullet_pos = go.get_position(".")
			bullet_pos.z = bullet_pos.z - 0.1
			local bullet_rot = go.get_rotation(".")
			local bullet_vel = self.velocity
			factory.create(self.Gun, bullet_pos, nil, {color = self.ProjColor, BulletVelocity = bullet_vel})
		end
	end
end