Root Motion NavMeshAgent Animation | AI Series Part 42 | Unity Tutorial

แชร์
ฝัง
  • เผยแพร่เมื่อ 16 ก.ค. 2024
  • Learn how to combine a Root Motion animated model with a NavMeshAgent! This gives you all the pathing benefits and local avoidance of the Navigation System with the precise animation you expect from Root Motion.
    Root Motion is a great way to remove that annoying "foot sliding" from mismatched animation vs velocity. But synchronizing that motion with a NavMeshAgent can be tricky! The NavMeshAgent knows where to go and considers local avoidance. So, there's a lot of things to consider when trying to match these two systems!
    We've already learned how to animate NavMeshAgents where the NavMeshAgent drives the Animator state (way back in AI Series Part 3: • Sync Animator and NavM... ), but in this video we're going to do it the other way - with the Animator driving the NavMeshAgent!
    There are multiple ways to approach this solution. In this repository I have chosen what makes the most sense to me - correcting the position of the Root Motion to pathable areas by moving the position of the model back towards the NavMeshAgent when they are out of sync.
    Gargoyle Model used here: assetstore.unity.com/packages...
    It's not required to run the project, but you will need to use a different model for the Player with 1D animation, or update the "PlayerMovement.cs" to set 2D Animator parameters like it's done in "EnemyMovement.cs".
    👨‍💻 As always, all code from this video is available on GitHub: github.com/llamacademy/ai-ser...
    💸 Ongoing sales 💸
    ⚫ See all active asset sales on the Asset Store: assetstore.unity.com/?on_sale...
    ⚫ Save 25% off your first Asset Store Order: prf.hn/click/camref:1101l9QvC...
    ⚫ Save up to 50% on NEW Assets: assetstore.unity.com/?new_sal...
    📚 Resources 📚
    ⚫ Root Motion: docs.unity3d.com/Manual/RootM...
    ⚫ Synchronizing NavMeshAgents and Root Motion: docs.unity3d.com/Manual/nav-C...
    ⚫ NavMeshAgents and Other Systems: docs.unity3d.com/Manual/nav-M...
    ⚫ AI Series Part 3 - • Sync Animator and NavM...
    As usual with the AI Series, we're using the NavMesh Components: docs.unity3d.com/Manual/NavMe... not the built-in navigation system.
    ❤ Believe in LlamAcademy's mission and have received value from the videos? Become a Patreon Supporter or TH-cam Member:
    ⚫ Patreon: / llamacademy
    ⚫ TH-cam Member: / @llamacademy or click the Join button on any video
    📱 Let's stay connected
    TH-cam: / llamacademy
    Patreon: / llamacademy
    Facebook: / llamacademyofficial
    Twitter: / thellamacademy
    TikTok: / llamacademy
    Instagram: / llamacademy
    ----
    Most tutorials come from knowledge gained making survival.llama.software Llama Survival - a top-down zombie survival shooter for Android and iOS.
    I also have some Unity Assets: assetstore.unity.com/publishe...
    Some links may be affiliate links, which at no additional cost to you, gives me a small portion of the purchase.
    #unitytutorial #tutorialtuesday #gamedev #tutorial #unity #llamacademy #gamedevelopment #ai
    Chapters:
    00:00 Topic Introduction
    01:22 3 Keys to Successful Root Motion Animated NavMeshAgents
    03:42 Animator Overview - 2D Movement Blend Tree
    04:52 Animator Overview - 1D Movement Blend Tree
    05:54 NavMeshAgent Configuration
    06:58 Why You May Want to Use Root Motion Animation
    07:40 PlayerMovement.cs - Prepare Agent and Animator for Root Motion
    08:46 PlayerMovement.cs - Synchronize Animator and Agent
    09:42 PlayerMovement.cs - Set Animator Parameters
    12:26 PlayerMovement.cs - Reconcile Difference in Animation and Agent Positions
    13:24 Become a Supporter!
    13:56 Demo & Showing Polish Focus Areas
    15:21 Final Thoughts

ความคิดเห็น • 80

  • @Space_Masters
    @Space_Masters ปีที่แล้ว +5

    This is the best video on this subject, and I've been looking for a while.

  • @AetherXIV
    @AetherXIV ปีที่แล้ว +2

    you cracked the code! I've wanted to fix issues between nav/anim for 2 years. Thank you so much.

  • @membuli
    @membuli 11 หลายเดือนก่อน +1

    This helped so much! Thanks for making these videos, super essential to my project :)
    The end thoughts about the importance of BlendTree setup finally fixed my jitter issues i've had for months now

    • @LlamAcademy
      @LlamAcademy  11 หลายเดือนก่อน

      🧡 that's awesome to hear! I love to hear stories like this!

  • @kevinmorales9942
    @kevinmorales9942 ปีที่แล้ว +1

    Thank you! You just made my game a little better.

  • @FunnyCunny
    @FunnyCunny ปีที่แล้ว +1

    This worked great. You are a legend!

  • @ronigleydsonvilasnovas8067
    @ronigleydsonvilasnovas8067 ปีที่แล้ว +7

    Very good, I've always used Root Motion in my controllers, I find it easier to use the movement of the animations than to synchronize everything with the movement of Rigidbody or CharacterController, but I've never been able to do that with Agents. you saved me again, mandatory.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +2

      Awesome 😎! I actually didn't realize so many people used root motion. I had always done it with just a playback of the animation and setting velocity. After diving in deep into it on this video I see why a lot of people prefer root motion!

  • @MagicPigGames
    @MagicPigGames 10 หลายเดือนก่อน +1

    I'm very happy to be coming to this video to remind myself how to do this :D

  • @theoneandonlylg3824
    @theoneandonlylg3824 10 หลายเดือนก่อน +1

    Thank you for a truly helpful tutorial, haven't really seen anyone tackle this problem in such a simple way
    Also to anyone who is still having troubles syncing agent and animator even with root motion working, make sure all your armature bone scales are set to 1, I had root bone resized to make character the desired size, but it caused further desync, hope this helps

  • @Husmanmusic
    @Husmanmusic ปีที่แล้ว +1

    Dude you are a lifesaver!

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      😃 thanks! I knew it was an important topic to cover!

  • @KamikazeBourloten
    @KamikazeBourloten ปีที่แล้ว +2

    Great Video as always. You have only forgot to include it in the "AI Tutorial Series" Playlist

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      Oh! Thank you for that! I will add it right away

  • @fookustudios3279
    @fookustudios3279 ปีที่แล้ว +1

    Very helpful.
    I had some trouble because I set the Agent.updateRotation = false;
    Which hosed everything, once I commented it out everything worked well.

  • @PikaPetey
    @PikaPetey 16 วันที่ผ่านมา

    I'm using this tutorial for a series of NPC cats. it works wonderful except during a cat's jump attacks. The Navmesh agent launches the cat further than it should, then the cat snaps back into the NavMesh spot. I don't know how to fix this.

  • @carollopez4099
    @carollopez4099 ปีที่แล้ว

    Very cool thanks 💝😋

  • @yunnietv78
    @yunnietv78 ปีที่แล้ว +1

    Awesome program

  • @heman922
    @heman922 ปีที่แล้ว +5

    Waiting for brust compiler and job system tutorial ❤

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      Hey 👋! Since I know you're super excited about that topic, I wanted to let you know the way I was planning to implement that didn't work out how I wanted to. I need to restart it from the drawing board so that video is not on the immediate horizon

    • @heman922
      @heman922 ปีที่แล้ว

      @@LlamAcademy oh really....ok then i will wait. thanks for the update ❤️

  • @maxg5196
    @maxg5196 ปีที่แล้ว +2

    High quality video

  • @insaneduane
    @insaneduane ปีที่แล้ว +4

    Great video as always and I appreciate what you are doing. Foot slip annoys me so I have been toying with this issue for a while and this is what I have come up with.
    Attach the navMeshAgent to the npc's Animator.transform and turn the npc towards the navMeshAgent.steeringTarget while having the navAgent's speed = 0 using the following code:
    public void TurnToNavTarget()
    {
    var navTarget = navMeshAgent.steeringTarget;
    Vector3 direction = (navTarget - navMeshAgent.transform.position).normalized;
    if (direction.x != 0 && direction.z != 0)
    {
    Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
    navMeshAgent.transform.rotation = Quaternion.Slerp(navMeshAgent.transform.rotation,
    lookRotation, Time.deltaTime * 5);
    }
    }
    This way the NavMeshAgent is always in the same position relative to the npc. I have the npc model a child of a GameObject that has all it's scripts so the only thing my npc model has attached to it is it's Animator, a NavMeshAgent and any scripts that use the "OnAnimatorIK" function.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      Cool, thanks for sharing that!

  • @KirillPashkov
    @KirillPashkov ปีที่แล้ว

    Great tutorial. One question tho. Does setting up root animation to control Agent movement affects the the real-time neighbor Agent avoidance in anyway?
    So far mine are completely ignoring each other and just bump in one another, although the priorities are randomized.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      It's been a little bit but I'm pretty sure it considered the avoidance even using root motion here. Agents with mixed priorities tend to have worse results (in my opinion) than if they all have the same priority. With mixed priority some agents, seemingly randomly, will just push other agents out of the way.

  • @alextreme98
    @alextreme98 ปีที่แล้ว

    Great tutorial! Can you make one even more complex? With animation turns in place, different states, jumping?

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +2

      Maybe. That’s mostly setting up your state machine in the Animator. I can add some more in-depth Animator configuration topic to the list of ones to cover

    • @alextreme98
      @alextreme98 ปีที่แล้ว

      @@LlamAcademy also, the scripting, regarding different settings, the animation might have foot sliding, i encountered different issues and difficulties with this kind of system.

    • @alextreme98
      @alextreme98 ปีที่แล้ว

      @@LlamAcademy Hi, I'm back with another question. At min 5:50 the character has a flick. Have you managed to fix that?

  • @willthomas4909
    @willthomas4909 ปีที่แล้ว +3

    Awesome video, but I'm trying to make the animations work with rotation and I'm noticing that velocity.x is very sparadic and fast moving. This makes it near impossible to "smooth" animations as it flicks from say 0 to 1 constantly. Even trying to smooth this out using a lerp I'm finding very jittery motion when turning. I think the issue here is that the nextPosition from the agent is forever changing, so velocity.x is flicking back and forth very quickly. Have you had any luck with root motion rotations?

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      Hmm... I didn't have that problem with 2d velocity when the animation had turns. In this repository you can see a 2d velocity including turning animations with "The Dude". github.com/llamacademy/ai-series-part-42. What you are describing sounds like perhaps you have a zero stopping distance on the NavMeshAgent that is resulting in the NavMeshAgent never coming to a complete stop so they are toggling between moving slightly and being completely still.

    • @dimiturkolev2
      @dimiturkolev2 ปีที่แล้ว +1

      @@LlamAcademy I have the same problem and i dont have a stopping distance of 0, the transitions between the animations on my blendtree are super stuttery, also i did put a in place walking animation

    • @songerk7102
      @songerk7102 ปีที่แล้ว

      did you ever found a solution ? because I still have this problem

    • @willthomas4909
      @willthomas4909 ปีที่แล้ว

      ​ @Emanuel Polsky Hey - yea sorry I thoguht I'd written a reply to LlamAcademy on this, but clearly never hit send! Ops.
      I'm running a little by memory here, as I do'nt have the code to hand. I ended up using a range of -1 (left) to 1 (right) and checking the agents position in relationship to where they were and applying left/right within that range. That meant the animations would always -1 or 1 on the X axis in the animator. This worked pretty smoothly. I'm using it for animal AI though, so the player is never controlling the animal. It may not be the best solution for people trying to applying root motion to a player controlled character.

    • @songerk7102
      @songerk7102 ปีที่แล้ว

      @@willthomas4909 thank you for the suggestion but that way it would work only if the animator have only one kind of turn, so it wouldn't have accuracy turn

  • @danyka6974
    @danyka6974 ปีที่แล้ว +1

    for the interruption source, you actually dont need to set it at all for this specific case as it makes no difference i believe. probably it could be useful when there are more than 1 transition from idle animation otherwise pointless.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      I think you are right, good call out

  • @paulr3001
    @paulr3001 8 หลายเดือนก่อน

    Hello, When I put my script into a child component that references the navmesh agent and Root parent Transform. My character Stutters but when I put everything in the root transform everything is smooth. Any insights?

    • @paulr3001
      @paulr3001 8 หลายเดือนก่อน

      further debugging. I noticed that when I put the movement script into the child component. The navmesh agent is moving faster than the root transform. so in the root I had a capsule collider and this was the one that was not catching up with the navmesh agent

  • @sebas1111_
    @sebas1111_ 2 หลายเดือนก่อน

    Sadly this doesn't work when you have a walking animation thrown in the mix. I'm doing a 2D blend tree with walk (half speed) - walk - run. If I do either walk or run it's perfect, but the two of them don't work.

    • @LlamAcademy
      @LlamAcademy  2 หลายเดือนก่อน

      What problem do you have adding in a run? There’s conceptually no difference between walk and run

  • @codequest194
    @codequest194 ปีที่แล้ว +1

    Great video's sir. i am using your this project for my game. i add dude as enemy and add walk animations in place of running. now i add in it he can see the player and chase him and add chasing on sound sound. but i don't know how i do in multi can you please guide me something .

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      If you mean multiplayer, you'll need to look into Mirror, Fishnet, NetCode for GameObjects, or maybe Photon

  • @shivamdas9895
    @shivamdas9895 9 หลายเดือนก่อน

    Thank you very much for this video!!
    Can you please help me how to rotate the agent with proper animations without changing its position.
    I mean I need a Function which will take a Vector3 point and the function will only rotate the agent towards that position without changing its position, not SetDestination. I can do transform.rotation, I have seen the LookAt coroutine in the Enemy Attacking video, but that's not using turning animations, how to do this, what value need to pass for velX, velY ? Pls help me. Or give me the function pls.

    • @LlamAcademy
      @LlamAcademy  9 หลายเดือนก่อน

      I think you can just play your Root Motion animation to turn. That can probably be achieved with some turn left/right floats provided to the Animator that play in-place root motion turning animations.
      If you provide velX/velY the agent will move because that's tied to an animation that moves the enemy!

  • @paulr3001
    @paulr3001 10 หลายเดือนก่อน

    Is there a way to add a speed boost to the root motion? Say my sprinting speed is 2 and when I get a boost it will go to 7. How can I accomplish that?

    • @LlamAcademy
      @LlamAcademy  10 หลายเดือนก่อน +1

      I think for root motion animation this requires either different animations or adjusting the animator playback speed.

  • @kylestan5874
    @kylestan5874 ปีที่แล้ว

    How do i make the agent walk towards a chair and sit down properly. Currently what happens is the agent moves towards the chair and constantly bumps into the collider of the chair.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +2

      "Sit down" is a non-navigation function. So I would recommend to have a scripted sequence to control the sit down process. If you have a Root Motion animation to sit down, you just have to get the character into the right position to start the sit down sequence, then disable the NavMeshAgent (maybe colliders too) and perform the sit down animation.

  • @newbossbro3180
    @newbossbro3180 ปีที่แล้ว

    Does this work for Horses/Cars?(can we map velocity to root motion in similar manner?) Where you don't have the independence of moving in all direction?

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      I think it could work by limiting the angularSpeed of the NavMeshAgent

    • @newbossbro3180
      @newbossbro3180 ปีที่แล้ว

      @@LlamAcademy how do you predict angularSpeed from let's say car wheel got a limitation of 45 degree angle?

  • @fishgethirsty6377
    @fishgethirsty6377 ปีที่แล้ว +1

    I love the video but my navmesh agent doesnt move with the animation. Well... after 1 minutes the navmesh agent moves like an inch. Please help!!

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      are you sure your Animations have root motion and you have them configured on the Animation import window to still include root motion?

    • @fishgethirsty6377
      @fishgethirsty6377 ปีที่แล้ว +1

      @@LlamAcademy oh lol yea, sorry about that. I had my animations position and rotation baked. Oops we all have our bad days, thank you

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      @@fishgethirsty6377 No problem 😊! Glad it was an easy fix!

  • @riekumar6999
    @riekumar6999 ปีที่แล้ว

    How do you determine the beat values for the blend tree?

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      It’s based on the speed values you plan on using, the movement speed of your animation, and how you want the game to feel. I usually start at -1, 0, 1 for the 1D and see how it works. There’s some guesswork and checking the result involved.

    • @riekumar6999
      @riekumar6999 ปีที่แล้ว

      @@LlamAcademy Dang, that's pretty difficult since animations can come in a massive variety and speeds. So, would you normally just use the velocity on the animation itself?

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      @@riekumar6999 I think that would be a good starting point!

  • @lvulcanis
    @lvulcanis ปีที่แล้ว

    how to make this work with keyboard/gamepad input?

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      You would drive the Animator parameter based on the keyboard / game pad input in a similar way to how we are having the NavMeshAgent drive the Animator properties based on the desired velocity and direction.

  • @hardhue
    @hardhue 8 หลายเดือนก่อน +1

    I was having an incredibly hard time trying to figure out why my characters were not tracking the NavMeshAgent properly. They were always sliding to the left. Make sure you have the Root Transform Rotation of your animations Based Upon (at Start) Original rather than Body Orientation. If e.g. your character animation is walking forward but their root bone is rotated about the Y axis, root motion will apply relative to Z+ which is not necessarily forward.

  • @dibaterman
    @dibaterman ปีที่แล้ว

    So for my next trick, I am going to rebuild my enemy AI script to predominantly use RigidBody but use NavMesh to find pathing.
    I am not to where I want to use ragdolls quite yet, but I do want to use rigidbody to simulate knock back.
    In my case I noticed a few things, 1 the agent gets wonky in cases where the player is out of reach of any locations the AI can say is reachable but are still in range of the AI. So say my player jumps on a ledge, the AI will instead of disengaging they'll do random stuff.
    Now if they all disengaged or just all did the same things it would make sense. But they all do random things.
    Next is knock back, part of what makes them do random things is the interaction between rigidbody and navmesh. Simply these two things hate each other. The forces will be applied but the agent will attempt to go to a location at the same time.
    The enemies can hit each other so I guess they hit each other and do random things.
    To fix this I read a bit about putting the navmesh on a child object and using Rigidbody.Move to handle the rest.
    However upon researching I found a ton of stuff on ragdolls but not much on just enemy AI rb controllers.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว +1

      Hey! For a knockback effect, you can attach a rigidbody with IsKinematic = true and swap it to IsKinematic = false when the knockback should occur, apply the force and disable the NavMeshAgent the same frame. Once you want the knockback effect to be completed (maybe velocity has slowed down near zero?), do NavMeshAgent.Warp() to the current location and swap the Rigidbody back to IsKinematic = true. That should give you pretty close to what you are looking for.
      The enemies doing random stuff when the player moves to an unreachable location is something you have to handle in your code. A way to handle it is instead of naively setting NavMeshAgent.SetDestination to the player's location, you can first use NavMesh.SamplePosition to see if there is a point nearby. If not, you can handle that however you wish. It could be that you just let them continue on to their previous spot, or do something else entirely.
      I hope these suggestions can help you!

    • @dibaterman
      @dibaterman ปีที่แล้ว

      @@LlamAcademy
      Thank you, I got something a little different working so far.
      The agent is on but not in control of the AI. Instead it creates a path which I send a child of the AI to follow along with.
      The RB then adjusts its angle and velocity to the child's position.
      It still hasn't resulted in the knock back effect yet but right now the RB and it have great locomotion.

  • @jeronimocollares320
    @jeronimocollares320 ปีที่แล้ว +1

    Nice, pretty advanced tutorial, but nice :) Let me know if you have something in this subject at Udemy (im a subscriber that plataform). thanks so much.

    • @LlamAcademy
      @LlamAcademy  ปีที่แล้ว

      You're very welcome 😃. I do not have any Udemy course, everything I have is public and free on TH-cam and GitHub. If you want to support monetarily there is only the TH-cam SuperThanks and Patreon monthly or one time support options.

  • @ukaszgrabski2811
    @ukaszgrabski2811 5 หลายเดือนก่อน

    Thats a pitty I cannot run this project out of the box :| Its a bit of a problem for a begginer :(

    • @LlamAcademy
      @LlamAcademy  5 หลายเดือนก่อน

      Why not? You should be able to pull it off GitHub and run it out of the box.

    • @ukaszgrabski2811
      @ukaszgrabski2811 5 หลายเดือนก่อน

      @@LlamAcademy yea, i did and the white dudes are running around but the Big Daddy is gone and im not sure if i can replace him with something else not loosing nice animation fit :(

    • @ukaszgrabski2811
      @ukaszgrabski2811 5 หลายเดือนก่อน

      Oh dear, I managed to animate my own character and it works flawlesly :) Thanks!

  • @tdif3197
    @tdif3197 ปีที่แล้ว +2

    pretty sure this whole video was just an excuse for you to say "the dude" in a funny voice 100 times haha.