News Forums RAIN Sample Projects, How To, and Code Example XML Files OR A Tutorial For Wander, Eat, Attack, and Reset.

This topic contains 48 replies, has 2 voices, and was last updated by  Sigil 4 days, 22 hours ago.

Viewing 15 posts - 31 through 45 (of 49 total)
  • Author
    Posts
  • #39168

    Sigil
    Keymaster

    You are moving faster than me, but this is to be expected, as you can concentrate all your efforts on this one issue. I am just busy and it takes me awhile to get back around to the forums some times.

    So I mentioned it before, and I’ll say it again now, several things stand out to me as problems:

    1. The original behavior tree setup for attacking doesn’t need a constraint, a visual sensor, or any of that to work properly. It should play the whole attack and it shouldn’t attack from far away.
    2. The original attack action, and your new ConsumeFood action, don’t require ResetTrigger calls. A trigger doesn’t keep the animation playing or stop it from playing unless you setup your transitions that way.

    You shouldn’t need bools either… these are all signs that something isn’t setup quite right, either I assumed something and you did it differently, or vice versa. We need to figure out why these things aren’t working before trying to change them, otherwise whatever the problem is, it is going to come up again (like you are seeing with your attack being flaky).

    So let’s start with attacking, in the original tree, with your custom action (minus the ResetTrigger):

    ...
    sequencer
        move (move target: playerTarget)
        move (face target: playerTarget)
        mecanim parameter (parameter: Attack, parameter type: Trigger), value: true)
        custom action (class: AttackTarget, target: playerTarget)
    ...

    So this is all in a sequencer, which means the attack won’t happen until the first two move nodes return success. The first move won’t return success until you are within close enough distance… so if you are attacking from far away, what happened to make it return success?

    Let’s say it does work though, and he gets close enough but the animation is stuttering. First, the Attack parameter should be a trigger, and it should only be used to transition into the attack state. Second, the only way out of the attack state should be a transition when the attack is done. I believe the default settings on a transition out of the state would be the correct settings.

    I’ll be hanging around today, so let’s see if we can solve this problem.

    #39174

    Mad_Mark
    Participant

    OK, I have stripped everything out, set attack and eat to triggers, and setup the code as detailed. No Bools. Transitions out of Attack and Eat have no conditions (Suspect this was a problem, as I had added them for the bools to work).

    1) When I start the game, zombie is out of detect range. He throws an attack, then starts RandomLocation seeking.
    2) When I get up in his grill, he launches an attack, and the console logs “Controller ‘BigZombie': Transition” in state ‘Locomotion’ uses parameter ‘Attack’ which is not compatible with condition type.” followed by the same error referencing ‘New State’ instead of ‘Locomotion’. (I have nothing called New State, and this happens in 2 out of 3 test runs)
    3) When I let him get a RandomLocation, he heads to it. He will sometimes spin on the destination. When I step into his sensor range, he attacks once (from too far away) and then moves towards the player. He attacks as he should once close.
    4) When moving towards the player after detecting, he doesn’t always face the player. Sometimes he walks sideways. (That’s why I stuck the FaceTarget:playerTarget into the move box).
    5) When I flee from detect range, he attacks as I leave the range. Then when he catches up, he walks right by me, or into me, and does not attack until I leave detect range (too far).

    I will strip my controller down to Locomotion[blend](Idle, Walk, Run), Feeding, and Attack. I have all the other parts in there just begging me to figure them out…

    Thanks for your patience. Lead on.
    Mark

    #39175

    Sigil
    Keymaster

    I wrote up a large post trying to answer all the problems, but once I got towards the end I started to realize that it wasn’t going to help much. We’ll have to keep trying to go back and forth and addressing things one at a time.

    First let’s fix the console error. It’s giving you that error because one of your transitions is still trying to check a trigger, but thinks its a boolean. It’ll be one of the exit conditions on your Locomotion state. I was able to get the same error by adding a condition on a transition, checking a boolean parameter for a false value, and then removing the parameter while the transition wasn’t selected, and adding the parameter back again as a trigger. Anyhow, the error is caused by one of the transitions, so double check them and make sure they are all setup correctly.

    Once there are no more console errors, let’s see what your behavior looks like.

    While working on that could you post the xml for your behavior tree in pastebin, or even here (in a code block) so that I can take a look at it and make sure we aren’t missing anything?

    #39180

    Mad_Mark
    Participant

    4 element controller, Locomotion(defaultState), ZfeedingFull(Eat Trigger in, none out), Any State, Attack(Attack Trigger in, none out->Locomotion)

    No errors in the console.
    Controller
    BT
    Mark

    • This reply was modified 2 weeks, 5 days ago by  Mad_Mark.
    #39186

    Sigil
    Keymaster

    Oh, by console error I meant the “Controller ‘BigZombie': Transition” in state ‘Locomotion’ uses parameter ‘Attack’ which is not compatible with condition type.” that you mentioned. Did that get fixed too?

    #39188

    Sigil
    Keymaster

    Well let’s assume it did get fixed, or that it will be.

    Let’s figure out why the AI is attacking when it starts, as from the behavior tree there is no reason that should happen. First thing, try turning off the AI altogether (disable the AIRig). Press play and if the AI does an attack we know something else is causing it to outside of the AI, either a bit of code, or something about the Controller.

    Let’s assume that works as expected, in which case we need to look at the first frames of playback in the behavior tree editor to see why the attack was executed. Start the game paused and get your AI open in the behavior tree editor so you can debug it, step the game until you see the attack occur in the behavior tree. Check the scene and see if it makes sense, the only way the AI should be able to attack is if is within its close enough distance to the player.

    Screenshot the tree if it is wonky.

    #39202

    Mad_Mark
    Participant

    It is working with the simplified controller.

    Let us begin…

    #39203

    Sigil
    Keymaster

    OK, not sure where we are. When you get this, update me on what the AI is doing at this point.

    Until then, I’ll address another issue that you discussed, which is the spinning in place when he reaches a random location. It sounds like you are using root motion and the AI is overshooting its target because of its walk animation. If that is the case, there are a few things to do to try and fix it:

    1. Make sure the transition from walk to idle doesn’t have “Has Exit Time” checked, as that would often delay the transition out of walking.
    2. Shorten the transition time from walk to idle to make it a little more responsive when stopping.
    3. Increase the close enough distance on the move node for the random location, this will give the AI more time to stop, albeit sometimes he may stop early (better than spinning).

    If you aren’t using root motion, check your close enough distance on your motor and see if setting it higher helps. Usually spinning in place means the AI missed its target, but we have a lot of checks to keep that from happening, and close enough also helps that out.

    #39204

    Mad_Mark
    Participant

    We are exactly where we were on thread page 1. No code changes, no tree changes.
    I have root motion enabled in AI, as well as OverRide Root Rotation.

    1 Walk to Idle is in a blend tree, based on Speed.
    2 Idle is set to Threshold:0 Speed:1, Walk = T:0.4 & S:1, Run = T:2 S:1
    3 Close enough on RandomLocation=4, on playerTarget moves = 2 on BT. In AI Motor, default CloseEnough Dist & Angle are 0.1. Single parameter Speed passed through motor.

    Not seeing any anomalies at this point.
    Mark

    #39205

    Sigil
    Keymaster

    I think I’m confused as to where we are. Perhaps we went back too far?

    You say you see no anomalies, so what is happening? At the end of the first page there was random wandering, eating food, chasing the player, and resuming the random wandering if he loses the player. Is that what we are seeing at this point?

    Did you remove your changes to the ConsumeFood action as well? The original setup assumed an animation that either looped or was less than the timer I set in the tree (I didn’t clarify this at the time, which was dumb, my mistake). Your modification was a good one if you want to have the entire animation play properly (doesn’t need the ResetTrigger though). If you use your modified version you can remove the timer as well, as your custom action will handle the wait.

    #39214

    Mad_Mark
    Participant

    I have put that change back into ConsumeFood.
    Forward ho!

    #39226

    Sigil
    Keymaster

    OK, well then if everything else is working, all that is left is to add the attack back in. Behavior tree should look like this at this point:

    root
        sequencer
            parallel (fail: any, success: any, tie breaker: fail)
                detect (repeat: Until Success, aspect: "Player", form variable: playerTarget)
                sequencer (repeat: Forever)
                    parallel (fail: any, success: any, tie breaker: fail)
                        detect (repeat: Until Success, aspect: "Food", form variable: foodTarget)
                        sequencer (repeat: Forever)
                            custom action (class: ChooseRandomLocation, target: moveTarget, distance: 20)
                            move (move target: moveTarget)
                            timer (seconds: random(1, 5))
                    move (move target: foodTarget, close enough distance: 1)
                    mecanim parameter (parameter: Eat, parameter type: Trigger), value: true)
                    custom action (class: ConsumeFood, target: foodTarget)
            selector
                parallel (fail: any, success: any, tie breaker: fail)
                    sequencer (repeat: Until Failure)
                        expression (expression: playerTargetPosition = position(playerTarget), returns: Success)
                        detect (aspect: "Player", form variable: playerTarget)
                    sequencer
                        move (move target: playerTarget)
                        move (face target: playerTarget)
                        mecanim parameter (parameter: Attack, parameter type: Trigger), value: true)
                        custom action (class: AttackTarget, target: playerTarget)
                parallel (fail: any, success: any, tie breaker: fail)
                    detect (repeat: Until Success, aspect: "Player", form variable: playerTarget)
                    move (move target: playerTargetPosition)

    Note that I removed the timer that was before the ConsumeFood action, as the action will handle that wait at this point. Also I’m assuming we’re using the AttackTarget custom action originally posted.

    #39240

    Mad_Mark
    Participant

    Yes, using the attack custom action.

    #39264

    Sigil
    Keymaster

    So is everything working at this point?

    #39266

    Mad_Mark
    Participant

    Pretty much. The only quibble so far is that the zombie sometimes gets up in my grill, attacks once, then stands there until I move out of range, then he attacks again from too far away, then pursues me and resumes attacking properly. Not always, but sometimes. Not enough to worry about at this point.

    Since we have been going back and forth with “are we ready?” “Yeah, we’re ready.” for a while, I’ve started messing with code again. I still hope to give my grandkids a personalized zombie-shooter game by Christmas… I added:

    // Here you should call out to your player and make them take damage in some way
    		GameObject tTarget = Target.Evaluate<GameObject> (ai.DeltaTime, ai.WorkingMemory);
    ***		tTarget.SendMessage ("Damage", 0.1f, SendMessageOptions.DontRequireReceiver);
    		_doneDamage = true;

    To the AttackTarget.cs. Seems to be working, the zombie can now give me damage when he attacks.
    More than willing to take that out if it isn’t what you had in mind. Just want to learn and move forward.

    Mark

Viewing 15 posts - 31 through 45 (of 49 total)

You must be logged in to reply to this topic.