News Forums Troubleshooting Trouble with Attack behavior

This topic contains 3 replies, has 2 voices, and was last updated by  prime 3 months, 2 weeks ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #33165

    hoodoo
    Participant

    Hello,

    I have a BT set up to patrol and then attack when the player gets close enough. This all works well, but on the attack I have a custom action to send damage. This action gets called a couple times and then no more, even though the attack animation continues to play. It seems to just stay in the attack mode and not keep going through the behavior tree. In addition I added a timer to do the attack for a random amount of time and in parallel I have a pause node that should idle the character for a random amount of time and then it should start attacking again. This is patterned after the patrol and pause example. So I don’t understand why it seems to stay in the attack animation which continuously plays and never pauses, and yet the custom action to send damage only runs a couple times?

    <behaviortree version="1.1" repeatuntil="" name="SimplePatrol" debugbreak="False">
        <parallel tiebreaker="fail" succeed="all" repeatuntil="" name="root" fail="any" debugbreak="False">
            <selector usepriorities="False" repeatuntil="running" name="selector" debugbreak="False">
                <constraint repeatuntil="" priority="" name="Player Out of Range" debugbreak="False" constraint="playerDetect == null">
                    <sequencer usepriorities="False" repeatuntil="" name="Patrol and Pause" debugbreak="False">
                        <parallel tiebreaker="fail" succeed="all" repeatuntil="" priority="" name="Patrol" fail="any" debugbreak="False">
                            <waypointpatrol waypointsetvariable=""PatrolRoute"" waypointactiontype="patrol" traversetype="pingpong" traverseorder="forward" repeatuntil="" pathtargetvariable="" name="waypointpatrol" movetargetvariable="moveTarget" debugbreak="False">
                                <parallel tiebreaker="fail" succeed="any" repeatuntil="" name="Move" fail="any" debugbreak="False">
                                    <animate repeatuntil="" name="animate" debugbreak="False" animationstate="walk" />
                                    <move turnspeed="" repeatuntil="" name="move" movetarget="moveTarget" movespeed="1" facetarget="" debugbreak="False" closeenoughdistance="" closeenoughangle="" />
                                </parallel>
                            </waypointpatrol>
                            <timer waitforsec="random(2,10)" returnvalue="success" name="patroltimer" debugbreak="False" />
                        </parallel>
                        <parallel tiebreaker="fail" succeed="all" repeatuntil="" priority="" name="Pause" fail="any" debugbreak="False">
                            <timer waitforsec="random(1,4)" returnvalue="success" name="pausetimer" debugbreak="False" />
                            <animate repeatuntil="" name="animate" debugbreak="False" animationstate="idle" />
                        </parallel>
                    </sequencer>
                </constraint>
                <constraint repeatuntil="" priority="" name="Player in Range" debugbreak="False" constraint="playerDetect != null">
                    <selector usepriorities="False" repeatuntil="" name="selector" debugbreak="False">
                        <constraint repeatuntil="" priority="" name="tooFarToAttack" debugbreak="False" constraint="nearPlayer == null">
                            <parallel tiebreaker="fail" succeed="all" repeatuntil="" name="parallel" fail="any" debugbreak="False">
                                <animate repeatuntil="" name="animate" debugbreak="False" animationstate="run" />
                                <move turnspeed="" repeatuntil="" name="move" movetarget="playerDetect" movespeed="2" facetarget="" debugbreak="False" closeenoughdistance="" closeenoughangle="" />
                            </parallel>
                        </constraint>
                        <constraint repeatuntil="" priority="" name="closeUp" debugbreak="False" constraint="nearPlayer != null">
                            <sequencer usepriorities="False" repeatuntil="" name="sequencer" debugbreak="False">
                                <parallel tiebreaker="fail" succeed="all" repeatuntil="" priority="" name="hit" fail="any" debugbreak="False">
                                    <move turnspeed="" repeatuntil="" name="move" movetarget="" movespeed="" facetarget="nearPlayer" debugbreak="False" closeenoughdistance="" closeenoughangle="" />
                                    <animate repeatuntil="" name="animate" debugbreak="False" animationstate="attack" />
                                    <action repeatuntil="" parametervalues="" parameters="" namespace="(global)" name="action" debugbreak="False" classname="SendDamageToPlayer" />
                                    <timer waitforsec="random(1-3)" returnvalue="success" name="timer" debugbreak="False" />
                                </parallel>
                                <parallel tiebreaker="fail" succeed="all" repeatuntil="" priority="" name="pauseattack" fail="any" debugbreak="False">
                                    <animate repeatuntil="" name="animate" debugbreak="False" animationstate="idle" />
                                    <timer waitforsec="random(1,2)" returnvalue="success" name="timer" debugbreak="False" />
                                </parallel>
                            </sequencer>
                        </constraint>
                    </selector>
                </constraint>
            </selector>
            <detect sensor=""eyes"" repeatuntil="running" name="far" entityobjectvariable="playerDetect" debugbreak="False" aspectvariable="" aspectobjectvariable="" aspect=""Player"" />
            <detect sensor=""close"" repeatuntil="running" name="near" entityobjectvariable="nearPlayer" debugbreak="False" aspectvariable="" aspectobjectvariable="" aspect=""Player"" />
        </parallel>
    </behaviortree>

    Unformatted:

    <scriptableobject version=”1.1″ type=”RAIN.BehaviorTrees.BTAsset”><fields><field value=”<behaviortree version=”1.1″ repeatuntil=”” name=”SimplePatrol” debugbreak=”False”><parallel tiebreaker=”fail” succeed=”all” repeatuntil=”” name=”root” fail=”any” debugbreak=”False”><selector usepriorities=”False” repeatuntil=”running” name=”selector” debugbreak=”False”><constraint repeatuntil=”” priority=”” name=”Player Out of Range” debugbreak=”False” constraint=”playerDetect == null”><sequencer usepriorities=”False” repeatuntil=”” name=”Patrol and Pause” debugbreak=”False”><parallel tiebreaker=”fail” succeed=”all” repeatuntil=”” priority=”” name=”Patrol” fail=”any” debugbreak=”False”><waypointpatrol waypointsetvariable=””PatrolRoute”” waypointactiontype=”patrol” traversetype=”pingpong” traverseorder=”forward” repeatuntil=”” pathtargetvariable=”” name=”waypointpatrol” movetargetvariable=”moveTarget” debugbreak=”False”><parallel tiebreaker=”fail” succeed=”any” repeatuntil=”” name=”Move” fail=”any” debugbreak=”False”><animate repeatuntil=”” name=”animate” debugbreak=”False” animationstate=”walk” /><move turnspeed=”” repeatuntil=”” name=”move” movetarget=”moveTarget” movespeed=”1″ facetarget=”” debugbreak=”False” closeenoughdistance=”” closeenoughangle=”” /></parallel></waypointpatrol><timer waitforsec=”random(2,10)” returnvalue=”success” name=”patroltimer” debugbreak=”False” /></parallel><parallel tiebreaker=”fail” succeed=”all” repeatuntil=”” priority=”” name=”Pause” fail=”any” debugbreak=”False”><timer waitforsec=”random(1,4)” returnvalue=”success” name=”pausetimer” debugbreak=”False” /><animate repeatuntil=”” name=”animate” debugbreak=”False” animationstate=”idle” /></parallel></sequencer></constraint><constraint repeatuntil=”” priority=”” name=”Player in Range” debugbreak=”False” constraint=”playerDetect != null”><selector usepriorities=”False” repeatuntil=”” name=”selector” debugbreak=”False”><constraint repeatuntil=”” priority=”” name=”tooFarToAttack” debugbreak=”False” constraint=”nearPlayer == null”><parallel tiebreaker=”fail” succeed=”all” repeatuntil=”” name=”parallel” fail=”any” debugbreak=”False”><animate repeatuntil=”” name=”animate” debugbreak=”False” animationstate=”run” /><move turnspeed=”” repeatuntil=”” name=”move” movetarget=”playerDetect” movespeed=”2″ facetarget=”” debugbreak=”False” closeenoughdistance=”” closeenoughangle=”” /></parallel></constraint><constraint repeatuntil=”” priority=”” name=”closeUp” debugbreak=”False” constraint=”nearPlayer != null”><sequencer usepriorities=”False” repeatuntil=”” name=”sequencer” debugbreak=”False”><parallel tiebreaker=”fail” succeed=”all” repeatuntil=”” priority=”” name=”hit” fail=”any” debugbreak=”False”><move turnspeed=”” repeatuntil=”” name=”move” movetarget=”” movespeed=”” facetarget=”nearPlayer” debugbreak=”False” closeenoughdistance=”” closeenoughangle=”” /><animate repeatuntil=”” name=”animate” debugbreak=”False” animationstate=”attack” /><action repeatuntil=”” parametervalues=”” parameters=”” namespace=”(global)” name=”action” debugbreak=”False” classname=”SendDamageToPlayer” /><timer waitforsec=”random(1-3)” returnvalue=”success” name=”timer” debugbreak=”False” /></parallel><parallel tiebreaker=”fail” succeed=”all” repeatuntil=”” priority=”” name=”pauseattack” fail=”any” debugbreak=”False”><animate repeatuntil=”” name=”animate” debugbreak=”False” animationstate=”idle” /><timer waitforsec=”random(1,2)” returnvalue=”success” name=”timer” debugbreak=”False” /></parallel></sequencer></constraint></selector></constraint></selector><detect sensor=””eyes”” repeatuntil=”running” name=”far” entityobjectvariable=”playerDetect” debugbreak=”False” aspectvariable=”” aspectobjectvariable=”” aspect=””Player”” /><detect sensor=””close”” repeatuntil=”running” name=”near” entityobjectvariable=”nearPlayer” debugbreak=”False” aspectvariable=”” aspectobjectvariable=”” aspect=””Player”” /></parallel></behaviortree>” type=”System.String” id=”treeData” /><field type=”System.Array” id=”treeBindings” elementtype=”System.String” /></fields><references /></scriptableobject>

    Thanks,

    -Dave.

    • This topic was modified 3 months, 2 weeks ago by  hoodoo.
    • This topic was modified 3 months, 2 weeks ago by  hoodoo.
    • This topic was modified 3 months, 2 weeks ago by  hoodoo.
    • This topic was modified 3 months, 2 weeks ago by  hoodoo.
    • This topic was modified 3 months, 2 weeks ago by  hoodoo.
    #33172

    prime
    Keymaster

    I’m guessing that your animate node is playing a looping animation, and so never returns true. Your Parallel is set to only succeed on All. So, once your SendDamageToPlayer action succeeds, it won’t run again, but the Parallel won’t exit because it is waiting for the animation to finish.

    Some thoughts:
    1) I’m guessing you don’t actually want the Move inside that parallel. Unless you are running while shooting?
    2) What’s the timer for?
    3) If the animation is looping (like for a machine gun firing), then you will want to put the Animate and Timer inside a parallel and have that parallel succeed on ANY. If the animation is not looping, then your Parallel should probably become a sequencer.

    #33188

    hoodoo
    Participant

    Thank you so much prime. The problem was definitely the animation being looped. Also, I now understand better how to correctly use the parallel and sequencer nodes. Your feedback really helped me! The move I have in there is to make the enemy face the player and I added that because my enemy character started to rotate as it began hitting the player. Not sure if that’s a result of the collision between the two - maybe I should move the enemy back a bit before it starts to attack. Does anyone else have trouble with unwanted rotation during an attack?

    <behaviortree version="1.1" repeatuntil="" name="SimplePatrol" debugbreak="False">
        <parallel tiebreaker="fail" succeed="all" repeatuntil="" name="root" fail="any" debugbreak="False">
            <selector usepriorities="False" repeatuntil="running" name="selector" debugbreak="False">
                <constraint repeatuntil="" priority="" name="Player Out of Range" debugbreak="False" constraint="playerDetect == null">
                    <sequencer usepriorities="False" repeatuntil="" name="Patrol and Pause" debugbreak="False">
                        <parallel tiebreaker="fail" succeed="any" repeatuntil="" priority="" name="Patrol" fail="any" debugbreak="False">
                            <waypointpatrol waypointsetvariable=""PatrolRoute"" waypointactiontype="patrol" traversetype="pingpong" traverseorder="forward" repeatuntil="" pathtargetvariable="" name="waypointpatrol" movetargetvariable="moveTarget" debugbreak="False">
                                <parallel tiebreaker="fail" succeed="any" repeatuntil="" name="Move" fail="any" debugbreak="False">
                                    <animate repeatuntil="" name="animate" debugbreak="False" animationstate="walk" />
                                    <move turnspeed="" repeatuntil="" name="move" movetarget="moveTarget" movespeed="1" facetarget="" debugbreak="False" closeenoughdistance="" closeenoughangle="" />
                                </parallel>
                            </waypointpatrol>
                            <timer waitforsec="random(2,10)" returnvalue="success" name="patroltimer" debugbreak="False" />
                        </parallel>
                        <parallel tiebreaker="fail" succeed="any" repeatuntil="" priority="" name="Pause" fail="any" debugbreak="False">
                            <timer waitforsec="random(1,4)" returnvalue="success" name="pausetimer" debugbreak="False" />
                            <animate repeatuntil="" name="animate" debugbreak="False" animationstate="idle" />
                        </parallel>
                    </sequencer>
                </constraint>
                <constraint repeatuntil="" priority="" name="Player in Range" debugbreak="False" constraint="playerDetect != null">
                    <selector usepriorities="False" repeatuntil="" name="selector" debugbreak="False">
                        <constraint repeatuntil="" priority="" name="tooFarToAttack" debugbreak="False" constraint="nearPlayer == null">
                            <parallel tiebreaker="fail" succeed="all" repeatuntil="" name="parallel" fail="any" debugbreak="False">
                                <animate repeatuntil="" name="animate" debugbreak="False" animationstate="run" />
                                <move turnspeed="" repeatuntil="" name="move" movetarget="playerDetect" movespeed="2" facetarget="" debugbreak="False" closeenoughdistance="" closeenoughangle="" />
                            </parallel>
                        </constraint>
                        <constraint repeatuntil="" priority="" name="closeUp" debugbreak="False" constraint="nearPlayer != null">
                            <sequencer usepriorities="False" repeatuntil="" name="sequencer" debugbreak="False">
                                <sequencer usepriorities="False" repeatuntil="" priority="" name="hit" debugbreak="False">
                                    <move turnspeed="" repeatuntil="" priority="" name="facePlayer" movetarget="" movespeed="" facetarget="nearPlayer" debugbreak="False" closeenoughdistance="" closeenoughangle="" />
                                    <animate repeatuntil="" priority="" name="animate attack" debugbreak="False" animationstate="attack" />
                                    <action repeatuntil="" priority="" parametervalues="" parameters="" namespace="(global)" name="action" debugbreak="False" classname="SendDamageToPlayer" />
                                </sequencer>
                                <parallel tiebreaker="fail" succeed="any" repeatuntil="" priority="" name="pauseattack" fail="any" debugbreak="False">
                                    <animate repeatuntil="" name="animate" debugbreak="False" animationstate="idle" />
                                    <timer waitforsec="random(0,1)" returnvalue="success" name="timer" debugbreak="False" />
                                </parallel>
                            </sequencer>
                        </constraint>
                    </selector>
                </constraint>
            </selector>
            <detect sensor=""eyes"" repeatuntil="running" name="far" entityobjectvariable="playerDetect" debugbreak="False" aspectvariable="" aspectobjectvariable="" aspect=""Player"" />
            <detect sensor=""close"" repeatuntil="running" name="near" entityobjectvariable="nearPlayer" debugbreak="False" aspectvariable="" aspectobjectvariable="" aspect=""Player"" />
        </parallel>
    </behaviortree>
    #33195

    prime
    Keymaster

    Unwanted rotation often happens because you are using a rigidbody and you haven’t constrained rotation. When dealing with rigidbodies and humanoid characters, we almost always constrain position x/z and rotation x/y/z, leaving only position y unconstrained to allow for gravity.

Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.