I’m making an enemy npc and currently coding it to move between 2 walls in the game. I’ve written code that should cause it to hit the floor which is the level and then be in its idle animation (which is set to default). When the game runs there are no errors but everytime the npc falls through the level. Ive attached the enemy code, are there any logic errors in it, or can you help me tack where this error is coming from??
It would be better if you put your code between code fences so that people can easily read it, scroll through it and try it out.
Like so:
local move_acceleration = 100
local max_speed = 50
local gravity = -1000
local ground_contact = false
local wall_contcat = false
local msg_contact_point_response = hash("contact_point_response")
local msg_animation_done = hash("animation_done")
local group_obstacle = hash("floor")
local group_wall = hash("walls")
local anim_walk = hash("run")
local anim_idle = hash("idle")
local anim_hit = hash("hit")
local anim_attack = hash("attack")
function init(self)
self.velocity = vmath.vector3(0,0,0)
self.movement = 1
self.anim = nil
end
function final(self)
-- Add finalization code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
end
function update(self, dt)
local target_speed = self.movement * max_speed
local speed_diff = target_speed * self.velocity.x
local acceleration = vmath.vector3(0,gravity,0)
if (speed_diff ~= 0) then
if (speed_diff < 0) then
acceleration.x = -move_acceleration
else
acceleration.x = move_acceleration
end
end
local dv = acceleration * dt
if (math.abs(dv.x) > math.abs(speed_diff)) then
dv.x = speed_diff
end
local v0 = self.velocity
self.velocity = self.velocity + dv
local dp = (v0 + self.velocity) * dt
go.set_position(go.get_position() + dp)
self.correction = vmath.vector3()
self.ground_contact = false
self.wall_contact = false
end
local function handle_obstacle_contact(self, normal, distance)
local proj = vmath.dot(self.correction, normal)
local comp = (distance - proj) * normal
self.correction = self.correction + comp
go.set_position(go.get_position() + comp)
if normal.y > 0.7 then
self.ground_contact = true
end
proj = vmath.dot(self.velocity, normal)
if proj < 0 then
self.velocity = self.velocity - proj * normal
end
end
function fixed_update(self, dt)
-- This function is called if 'Fixed Update Frequency' is enabled in the Engine section of game.project
-- Can be coupled with fixed updates of the physics simulation if 'Use Fixed Timestep' is enabled in Physics section of game.project
-- Add update code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
end
function on_message(self, message_id, message, sender)
if message_id == msg_contact_point_response then
if message_group == group_obstacle then
handle_obstacle_contact(self, message.normal, message.distance)
end
end
end
function on_input(self, action_id, action)
-- Add input-handling code here. The game object this script is attached to
-- must have acquired input focus:
--
-- msg.post(".", "acquire_input_focus")
--
-- All mapped input bindings will be received. Mouse and touch input will
-- be received regardless of where on the screen it happened.
-- Learn more: https://defold.com/manuals/input/
-- Remove this function if not needed
end
function on_reload(self)
-- Add reload-handling code here
-- Learn more: https://defold.com/manuals/hot-reload/
-- Remove this function if not needed
end
Had a quick look and spotted a typo in the message function:
“message_group” should read “message.group”.
function on_message(self, message_id, message, sender)
if message_id == msg_contact_point_response then
if message.group == group_obstacle then
handle_obstacle_contact(self, message.normal, message.distance)
end
end
end
Does it work now?
Yes it works now, thank you soo much it really is appreciated :))
Devs - help please, I accidently flagged the penultimate post. Ah - flag seems to be gone.
I now have a problem where the enemy will load in but will not move as it should. Instead it stays in the idle position stationary. When i removed the brackes from the first 2 if statements in the update function the enemy did move but when i ran the game again it went back to staying stationary again. Do you know what the problem may be???
local move_acceleration = 100
local max_speed = 50
local gravity = -1000
local ground_contact = false
local wall_contcat = false
local msg_contact_point_response = hash("contact_point_response")
local msg_animation_done = hash("animation_done")
local group_obstacle = hash("floor")
local group_wall = hash("walls")
local anim_walk = hash("run")
local anim_idle = hash("idle")
local anim_hit = hash("hit")
local anim_attack = hash("attack")
function init(self)
self.velocity = vmath.vector3(0,0,0)
self.movement = 1
self.anim = nil
end
function final(self)
-- Add finalization code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
end
function update(self, dt)
local target_speed = self.movement * max_speed
local speed_diff = target_speed - self.velocity.x
local acceleration = vmath.vector3(0, gravity,0)
if speed_diff ~= 0 then
if speed_diff < 0 then
acceleration.x = -move_acceleration
else
acceleration.x = move_acceleration
end
end
local dv = acceleration * dt
if (math.abs(dv.x) > math.abs(speed_diff)) then
dv.x = speed_diff
end
local v0 = self.velocity
self.velocity = self.velocity + dv
local dp = (v0 + self.velocity) * dt
go.set_position(go.get_position() + dp)
self.correction = vmath.vector3()
self.ground_contact = false
self.wall_contact = false
end
local function handle_obstacle_contact(self, normal, distance)
local proj = vmath.dot(self.correction, normal)
local comp = (distance - proj) * normal
self.correction = self.correction + comp
go.set_position(go.get_position() + comp)
if normal.y > 0.7 then
self.ground_contact = true
end
proj = vmath.dot(self.velocity, normal)
if proj < 0 then
self.velocity = self.velocity - proj * normal
end
end
function fixed_update(self, dt)
-- This function is called if 'Fixed Update Frequency' is enabled in the Engine section of game.project
-- Can be coupled with fixed updates of the physics simulation if 'Use Fixed Timestep' is enabled in Physics section of game.project
-- Add update code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
end
function on_message(self, message_id, message, sender)
if message_id == msg_contact_point_response then
if message.group == group_obstacle then
handle_obstacle_contact(self, message.normal, message.distance)
end
end
end
function on_input(self, action_id, action)
-- Add input-handling code here. The game object this script is attached to
-- must have acquired input focus:
--
-- msg.post(".", "acquire_input_focus")
--
-- All mapped input bindings will be received. Mouse and touch input will
-- be received regardless of where on the screen it happened.
-- Learn more: https://defold.com/manuals/input/
-- Remove this function if not needed
end
function on_reload(self)
-- Add reload-handling code here
-- Learn more: https://defold.com/manuals/hot-reload/
-- Remove this function if not needed
end
As far as I can tell, the code pulls the enemy downwards, but doesn’t move him in the x direction. There is also no code in the input function to move the enemy around. Do I understand you correctly: you would like the enemy to constantly move left or right between walls until he hits a wall and then turns? I think there is code for this somewhere on the forum. I haven’t written such code myself, but can have a look tomorrow if you haven’t got an answer by then.
Edit: found this video - would this help?DEFOLD Game Engine TUTORIAL #02: Implementing the ENEMY MOVEMENT & ANIMATIONS - YouTube
that’s the video i’m using as a guide, and the code i have copied is the code from the video, so i’m not really sure what to do. If you want you can look at the video to see if i’ve missed anything
Ok - I’ll have a look for you tomorrow if possible. If you like, could you upload your project so I don’t have to reproduce it myself (and maybe spot sth in your setup) - in a pm if you prefer.
I’ve just been messing around with it now, and every now,and again it will move but this seems almost completly random usually every 3 - 8 times i build the game it moves lmao
Interesting - well, sth is amiss. Still, looking at what you have done so far in your project files would help to find the problem. So, it would be great if you could share the project.
I must be off now.
Edit: ah, you just did - great.