Jump to content

Recommended Posts

I'm trying to create a creature who simply follow the player but there's some problems (of course!)

 

problem 1. walking animation doesn't work...

 

here's names I used on spriter

 

idle_down (idle animation works)

idle_up

idle_side

 

walk_pre_down

walk_pre_up

walk_pre_side

 

walk_loop_down

walk_loop_up

walk_loop_side

 

and the SG

 

 

require("stategraphs/commonstates")

local states=
{

    State{

        name = "idle",

        tags = {"idle", "canrotate"},

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("idle", true)
        end,

    },

    State{

        name = "walk",

        tags = {"walk", "canrotate", "moving" },

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("walk", true)

            inst.components.locomotor:WalkForward()            
        end,
    },

}

local event_handlers=
{

    EventHandler("locomote",
        function(inst)

            if inst.components.locomotor:WantsToMoveForward() then

            else

                if not inst.sg:HasStateTag("idle") then

                    inst.sg:GoToState("idle")
                end
            end
        end),
}

return StateGraph("headbanger", states, event_handlers, "idle", {})

 

 

problem n.2

 

Tried to add  "follower" component, but the creature simply turns in the direction the player is, doesn't follow.

here's the brain

 

 

require "behaviours/follow"
require "behaviours/wander"
require "behaviours/faceentity"


local MIN_FOLLOW_DIST = 0
local MAX_FOLLOW_DIST = 12
local TARGET_FOLLOW_DIST = 6

local MAX_WANDER_DIST = 3


local function GetFaceTargetFn(inst)
    return inst.components.follower.leader
end

local function KeepFaceTargetFn(inst, target)
    return inst.components.follower.leader == target
end


local HeadBangerBrain = Class(Brain, function(self, inst)
    Brain._ctor(self, inst)
end)


function HeadBangerBrain:OnStart()
    local root =
    PriorityNode({
        --WhileNode( function() return self.inst.components.health.takingfiredamage end, "OnFire", Panic(self.inst)),
        Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),
        FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),
        --Wander(self.inst, function() return self.inst.components.knownlocations:GetLocation("home") end, MAX_WANDER_DIST),
        
    }, .25)
    self.bt = BT(self.inst, root)
end

return HeadBangerBrain

 

 

 

It's the first time I'm creating a creature from 0... What am I doing wrong?

I'm trying to create a creature who simply follow the player but there's some problems (of course!)

 

problem 1. walking animation doesn't work...

 

here's names I used on spriter

 

idle_down (idle animation works)

idle_up

idle_side

 

walk_pre_down

walk_pre_up

walk_pre_side

 

walk_loop_down

walk_loop_up

walk_loop_side

 

and the SG

 

 

require("stategraphs/commonstates")

local states=

{

    State{

        name = "idle",

        tags = {"idle", "canrotate"},

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("idle", true)

        end,

    },

    State{

        name = "walk",

        tags = {"walk", "canrotate", "moving" },

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("walk", true)

            inst.components.locomotor:WalkForward()            

        end,

    },

}

local event_handlers=

{

    EventHandler("locomote",

        function(inst)

            if inst.components.locomotor:WantsToMoveForward() then

            else

                if not inst.sg:HasStateTag("idle") then

                    inst.sg:GoToState("idle")

                end

            end

        end),

}

return StateGraph("headbanger", states, event_handlers, "idle", {})

 

 

problem n.2

 

Tried to add  "follower" component, but the creature simply turns in the direction the player is, doesn't follow.

here's the brain

 

 

require "behaviours/follow"

require "behaviours/wander"

require "behaviours/faceentity"

local MIN_FOLLOW_DIST = 0

local MAX_FOLLOW_DIST = 12

local TARGET_FOLLOW_DIST = 6

local MAX_WANDER_DIST = 3

local function GetFaceTargetFn(inst)

    return inst.components.follower.leader

end

local function KeepFaceTargetFn(inst, target)

    return inst.components.follower.leader == target

end

local HeadBangerBrain = Class(Brain, function(self, inst)

    Brain._ctor(self, inst)

end)

function HeadBangerBrain:OnStart()

    local root =

    PriorityNode({

        --WhileNode( function() return self.inst.components.health.takingfiredamage end, "OnFire", Panic(self.inst)),

        Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),

        FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),

        --Wander(self.inst, function() return self.inst.components.knownlocations:GetLocation("home") end, MAX_WANDER_DIST),

        

    }, .25)

    self.bt = BT(self.inst, root)

end

return HeadBangerBrain

 

 

 

It's the first time I'm creating a creature from 0... What am I doing wrong?

 

Well, for the walk animations, I think you need:

 

walk

walk_pre

walk_loop

walk_post

 

Then amend "_direction" to those, for each direction you use.

 

For the follow component, are you setting the player as the leader in its prefab?

Edited by debugman18

Well, for the walk animations, I think you need:

 

walk

walk_pre

walk_loop

walk_post

 

Then amend "_direction" to those, for each direction you use.

 

For the follow component, are you setting the player as the leader in its prefab?

 

I tried

 

inst:AddComponent("follower")

    inst.components.follower.leader = GetPlayer()

 

and

    GetPlayer().components.leader:AddFollower(inst)

 

but the creature just looks at me..

 

so I THINK the problem is in the brain :/

Edited by Lawrence

I tried

 

inst:AddComponent("follower")

    inst.components.follower.leader = GetPlayer()

 

and

    GetPlayer().components.leader:AddFollower(inst)

 

but the creature just looks at me..

 

so I THINK the problem is in the brain :/

 

Okay, so for the follower line in the brain, try this:

Follow(self.inst, function() return self.inst.components.follower and self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),

 

Okay, so for the follower line in the brain, try this:

Follow(self.inst, function() return self.inst.components.follower and self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),

 

Nothing, it keeps looking..

 

Maybe I wrote something wrong in the prefab.lua?

 

local function fn()

    local inst = CreateEntity()

    local trans = inst.entity:AddTransform()

    local anim = inst.entity:AddAnimState()

    

    anim:SetBank("headbanger")

    anim:SetBuild("headbanger")

    

    inst.Transform:SetFourFaced()

    inst.Transform:SetScale(0.8, 0.8, 0.8)

    

    MakeCharacterPhysics(inst, 10, .5)

    inst:SetStateGraph("SGheadbanger")

    

        inst:AddComponent("locomotor")

        inst.components.locomotor.walkspeed = 7

        inst.components.locomotor.runspeed = 7

        inst:AddComponent("follower")

        inst.components.follower.leader = GetPlayer()

        

    inst.components.follower.maxfollowtime = 99999999

    GetPlayer().components.leader:AddFollower(inst)

    inst.components.follower:AddLoyaltyTime(9999999)

    

    local brain = require "brains/headbanger_brain"

    inst:SetBrain(brain)

    inst.entity:AddSoundEmitter()

        

    return inst

end

Nothing, it keeps looking..

 

Maybe I wrote something wrong in the prefab.lua?

 

local function fn()

    local inst = CreateEntity()

    local trans = inst.entity:AddTransform()

    local anim = inst.entity:AddAnimState()

    

    anim:SetBank("headbanger")

    anim:SetBuild("headbanger")

    

    inst.Transform:SetFourFaced()

    inst.Transform:SetScale(0.8, 0.8, 0.8)

    

    MakeCharacterPhysics(inst, 10, .5)

    inst:SetStateGraph("SGheadbanger")

    

        inst:AddComponent("locomotor")

        inst.components.locomotor.walkspeed = 7

        inst.components.locomotor.runspeed = 7

        inst:AddComponent("follower")

        inst.components.follower.leader = GetPlayer()

        

    inst.components.follower.maxfollowtime = 99999999

    GetPlayer().components.leader:AddFollower(inst)

    inst.components.follower:AddLoyaltyTime(9999999)

    

    local brain = require "brains/headbanger_brain"

    inst:SetBrain(brain)

    inst.entity:AddSoundEmitter()

        

    return inst

end

 

What prints if you add

print(inst.components.follower.leader)

to the prefab after you set the leader?

 

Okay, so the entity is correctly identifying the player as its leader. Does the entity properly move around (at all)?

 

Yes, if I make it manually walk ( WalkInDirection ) it moves

 

and he turns in the direction the player is

Edited by Lawrence

Nothing... :/ How annoying when those things happens

 

Yes, but a learning experience. :p

 

Try commenting out your current "walk" state, and add this separately from the states block:

CommonStates.AddWalkStates(states, {    walktimeline =    {        TimeEvent(1*FRAMES, function(inst)            inst.components.locomotor:RunForward()        end),        TimeEvent(14*FRAMES, function(inst)            PlayFootstep(inst)            inst.components.locomotor:WalkForward()        end),    }}, nil, true)

 

 

Yes, but a learning experience. :razz:

 

Try commenting out your current "walk" state, and add this separately from the states block:

CommonStates.AddWalkStates(states, {    walktimeline =    {        TimeEvent(1*FRAMES, function(inst)            inst.components.locomotor:RunForward()        end),        TimeEvent(14*FRAMES, function(inst)            PlayFootstep(inst)            inst.components.locomotor:WalkForward()        end),    }}, nil, true)

 

Still nothing...

 

With all this learning experience we will level up soon xD

Still nothing...

 

With all this learning experience we will level up soon xD

 

Quite possibly.

 

So, add this event to your "idle" state:

events={        EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),},

 

 

Quite possibly.

 

So, add this event to your "idle" state:

events={        EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),},

 

Ok I think I fixed it :D

 

I wrote

 

" inst.components.locomotor:WalkForward() "

 

here

 

 

local event_handlers=

{

    EventHandler("locomote",

        function(inst)

            if inst.components.locomotor:WantsToMoveForward() then

            inst.components.locomotor:WalkForward()

            else

                if not inst.sg:HasStateTag("idle") then

                    inst.sg:GoToState("idle")

                end

            end

        end),

}

 

 

The animations still doesn't play anyway mmh...

 

Quite possibly.

 

So, add this event to your "idle" state:

events={        EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),},

 

Thank you for your help :)

 

Mmmh... What could be wrong now, with animations?

I'm never 100% sure when using spriter >_<

Thank you for your help :-)

 

Mmmh... What could be wrong now, with animations?

I'm never 100% sure when using spriter >_<

 

I'm not entirely sure. Check your log.txt and see if it's trying to call a non-existant animation or something similar.

 

I'm not entirely sure. Check your log.txt and see if it's trying to call a non-existant animation or something similar.

 

 

There's no errors or something like that, It seems it doesn't call anything

I'm pretty sure that instead of writing inst.components.locomotor.WalkForward(), you want to do this: inst.sg:GoToState("walk").  In your walk state you will also need to change the inst.AnimState:PlayAnimation("walk") to inst.AnimState:PlayAnimation("walk_loop").  Your stategraph doesn't have code for walk_pre and walk_post, however, so it won't look complete unless you add that.

you were right, thanks.

But there's a strange bug: the creature start the animation (with walk_pre) only when it stops moving.

When moving it got stuck on idle animation...

 

Here's the current SG

 

--require("stategraphs/commonstates")

local events =
{
    --[[CommonHandlers.OnStep(),
    CommonHandlers.OnLocomote(false,true),
    EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), ]]
    EventHandler("locomote", function(inst)
        
        local is_moving = inst.sg:HasStateTag("moving")

        local should_move = inst.components.locomotor:WantsToMoveForward()
        
        if is_moving then
            inst.sg:GoToState("walk_start")
        end
        
       --[[ if is_moving and not should_move then

                inst.sg:GoToState("walk_stop")
           
        elseif (not is_moving and should_move) or (is_moving and should_move) then
            
                inst.sg:GoToState("walk_start")
            
        end --]]
    end),
}

local states=
{

    State{

        name = "idle",

        tags = {"idle", "canrotate"},

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("idle", true)
        end,

    },

    State{
        name = "walk_start",
        tags = {"moving", "canrotate"},
        
        onenter = function(inst)
            inst.components.locomotor:WalkForward()
            inst.AnimState:PlayAnimation("walk_pre")
        end,

        events=
        {   
            EventHandler("animover", function(inst) inst.sg:GoToState("walk") end ),        
        },
    },
    
    State{

        name = "walk",

        tags = { "moving", "canrotate" },

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("walk_loop", true)
            inst.components.locomotor:WalkForward()            
        end,
    },

    State{
        name = "walk_stop",
        tags = {"canrotate"},
        
        onenter = function(inst)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("walk_pst")
        end,
        
        events=
        {   
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),        
        },
    },
        
}

CommonStates.AddWalkStates(states, {
    walktimeline =
    {
        TimeEvent(1*FRAMES, function(inst)
            inst.components.locomotor:WalkForward()
        end),
        TimeEvent(14*FRAMES, function(inst)
            PlayFootstep(inst)
            inst.components.locomotor:WalkForward()
        end),
    }
}, nil, true)

local event_handlers=
{

    EventHandler("locomote",
        function(inst)

        if inst.components.locomotor:WantsToMoveForward() then
            inst.sg:GoToState("walk_start")
        else
            
            if not inst.sg:HasStateTag("idle") then
                inst.sg:GoToState("walk_stop")
              end
            end
        end),
}

return StateGraph("headbanger", states, event_handlers, "idle", {})

 

I modified it many many times but It gives always the same result

Edited by Lawrence

You are trying to do two of the same thing at the same time. You cannot use the Commonstates unless you have all of the animations that are needed in that state. You are also trying to make it walk on your own, so you have Commonstates and your states fighting I think. Looking at the code, it is hard to tell what exactly the problem is. I will when I have more time, but it will be easier if you use EITHER Commonstates or your own states, and eliminate the other (I comment large chunks out until I know I won't need them).

 

Not to be shameless, but I recommend getting the grasshopper mod from my sig. It has custom walk states using my animations, stategraph, etc. The stategraph calls are a little convoluted as I tried everything to get them to hop properly. I can help you with any questions you have.

 

Disclaimer: This is all "as far as I know".

 

EDIT: Oh and I would stick with the animations you previously had with the up, down, and side prefixes if you have already made them.

Edited by ProfFarnsworth

You are trying to do two of the same thing at the same time. You cannot use the Commonstates unless you have all of the animations that are needed in that state. You are also trying to make it walk on your own, so you have Commonstates and your states fighting I think. Looking at the code, it is hard to tell what exactly the problem is. I will when I have more time, but it will be easier if you use EITHER Commonstates or your own states, and eliminate the other (I comment large chunks out until I know I won't need them).

 

Not to be shameless, but I recommend getting the grasshopper mod from my sig. It has custom walk states using my animations, stategraph, etc. The stategraph calls are a little convoluted as I tried everything to get them to hop properly. I can help you with any questions you have.

 

Disclaimer: This is all "as far as I know".

 

EDIT: Oh and I would stick with the animations you previously had with the up, down, and side prefixes if you have already made them.

 

Uhm... I don't think I understand... Sorry what should I remove (for sure)?

 

EDIT: Ah ok... So I have to use commonstate OR my states (sorry I didn't sleep this night so I'm a bit slow xD) Ok...

But I already commented away the "require commonstates" and the animation stucks... I'm going to test some things (and look on your mod of course)

Edited by Lawrence

Ok, I fixed it! Finally :grin:

 

here's how I did it:

 

 


local events =
{
    CommonHandlers.OnStep(),
    CommonHandlers.OnLocomote(false,true),
   
    EventHandler("animover", function(inst)
        
        local is_moving = inst.sg:HasStateTag("moving")
        local should_move = inst.components.locomotor:WantsToMoveForward()
        
    if is_moving and not should_move then
                
        inst.sg:GoToState("walk_stop")
           
   elseif (not is_moving and should_move) then
                inst.sg:GoToState("walk_start")
            
        end
    end),
  
}

local states=
{

    State{

        name = "idle",

        tags = {"idle", "canrotate"},

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("idle", true)
        end,

    },

    State{
        name = "walk_start",
        tags = {"moving", "canrotate"},
        
        onenter = function(inst)
            inst.AnimState:PlayAnimation("walk_pre")
            inst.components.locomotor:WalkForward()
        end,

        events=
        {   
            EventHandler("animover", function(inst) inst.sg:GoToState("walk") end ),        
        },
    },
    
    State{

        name = "walk",

        tags = {"walk", "canrotate", "moving", "nostop" },

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("walk_loop", true)
            inst.components.locomotor:WalkForward()            
        end,
    },

    State{
        name = "walk_stop",
        tags = {"canrotate"},
        
        onenter = function(inst)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("walk_pst")
        end,
        
        events=
        {   
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),        
        },
    },
            
}
--[[
CommonStates.AddWalkStates(states, {
    walktimeline =
    {
        TimeEvent(1*FRAMES, function(inst)
            inst.components.locomotor:WalkForward()
            inst.sg:GoToState("walk_start")
        end),
        TimeEvent(14*FRAMES, function(inst)
            PlayFootstep(inst)
            inst.components.locomotor:WalkForward()
            inst.sg:GoToState("walk")
        end),
    }
}, nil, true)]]


return StateGraph("headbanger", states, events, "idle", {})

 

 

Finally! (now I should modify a bit the animations because there are horrible xD) But it wooorks :grin:

 

Thanks you everyone for the help

Edited by Lawrence

Ok, I fixed it! Finally :grin:

 

here's how I did it:

 

 

local events =

{

    CommonHandlers.OnStep(),

    CommonHandlers.OnLocomote(false,true),

   

    EventHandler("animover", function(inst)

        

        local is_moving = inst.sg:HasStateTag("moving")

        local should_move = inst.components.locomotor:WantsToMoveForward()

        

    if is_moving and not should_move then

                

        inst.sg:GoToState("walk_stop")

           

   elseif (not is_moving and should_move) then

                inst.sg:GoToState("walk_start")

            

        end

    end),

  

}

local states=

{

    State{

        name = "idle",

        tags = {"idle", "canrotate"},

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("idle", true)

        end,

    },

    State{

        name = "walk_start",

        tags = {"moving", "canrotate"},

        

        onenter = function(inst)

            inst.AnimState:PlayAnimation("walk_pre")

            inst.components.locomotor:WalkForward()

        end,

        events=

        {   

            EventHandler("animover", function(inst) inst.sg:GoToState("walk") end ),        

        },

    },

    

    State{

        name = "walk",

        tags = {"walk", "canrotate", "moving", "nostop" },

        onenter = function(inst, playanim)

            inst.AnimState:PlayAnimation("walk_loop", true)

            inst.components.locomotor:WalkForward()            

        end,

    },

    State{

        name = "walk_stop",

        tags = {"canrotate"},

        

        onenter = function(inst)

            inst.Physics:Stop()

            inst.AnimState:PlayAnimation("walk_pst")

        end,

        

        events=

        {   

            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),        

        },

    },

            

}

--[[

CommonStates.AddWalkStates(states, {

    walktimeline =

    {

        TimeEvent(1*FRAMES, function(inst)

            inst.components.locomotor:WalkForward()

            inst.sg:GoToState("walk_start")

        end),

        TimeEvent(14*FRAMES, function(inst)

            PlayFootstep(inst)

            inst.components.locomotor:WalkForward()

            inst.sg:GoToState("walk")

        end),

    }

}, nil, true)]]

return StateGraph("headbanger", states, events, "idle", {})

 

 

Finally! (now I should modify a bit the animations because there are horrible xD) But it wooorks :grin:

 

Thanks you everyone for the help

Glad to hear it

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...