Root Motion + NavMeshAgent (and Nav Mesh Links!) | Unity Tutorial

Поділитися
Вставка

КОМЕНТАРІ • 62

  • @willcotter7410
    @willcotter7410 Місяць тому +2

    I must admit, the music paired with your voice, was pretty sleep stuffs, but then ... this golden gem ... "Like I totally didnt do the first time i recorded this..." Damn i laughed, Good vid. Well done.

  • @nameno7032
    @nameno7032 Місяць тому +4

    Part2 is needed in this world man. Good job, your explanation is the best

  • @leo8292
    @leo8292 Місяць тому +1

    I came here after following another tutorial, but this approach seriously improved my AI behaviour. The logic is much cleaner, and the off mesh link feature is excellent. I've been wondering how to achieve this for months, and here's the answer. Good job!

  • @birahe1810
    @birahe1810 5 місяців тому +7

    That was perfect, nice explanation and actually teaching something. You are gold man I wish you luck

  • @james_freeman
    @james_freeman 5 місяців тому +4

    The Bob Ross of game development!
    Loved the video. Please make one on a catenary implementation of a non-quantum turboencabulation matrix.

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  5 місяців тому +1

      Great idea! That topic will pair great with my upcoming tutorial on non-Euclidian parallax membranes.

  • @ziedsioud3313
    @ziedsioud3313 2 місяці тому +1

    This video is so underrated! It was really well explained, simple to follow and to understand with pretty amazing result, way far better than any other video that I've seen. I hope you get the attention that you deserve.
    Keep going Champ!

  • @dankingswell7082
    @dankingswell7082 6 днів тому +1

    I’d love a video on preventing agents from colliding or clumping up when a large amount of agents are near each other

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  6 днів тому

      I'll look into it! A lot of the ways I get around that now are a little bit of using the agent priority, but mostly working with level designers to give multiple paths (including off mesh stuff like vaulting over or sliding under stuff) instead on one doorway when you know the encounter will have multiple enemies. Good level flow is easier for me since it means less code, and less code means less bugs, haha. I requested in the forums forever ago to have the ability to adjust navmesmodifier's weights at runtime without needing to rebake the navmesh which would help a lot to reduce congestion since longer paths would look better to other agents if there's too many agents near a particular door, but I don't think my request got any traction.

  • @ep1417
    @ep1417 Місяць тому +1

    Great tutorial, precise, easy to understand and very knowledgeable. I picked up on a few points about navigation that I didn't know about, so it was very helpful, thank you.

  • @XxTheArtisaNxX
    @XxTheArtisaNxX 4 місяці тому +3

    a part 2 would be rad man! I havent been able to find a solid tutorial on calculating rotation for pivot animations

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  4 місяці тому +2

      This video from 10 years ago is actually still relevant: ua-cam.com/video/zy9E-w4QM2o/v-deo.html
      The basics are you need a blendtree with pivot L 180, pivot L 90, walk forward start, pivot R 90, pivot R 180 where it blends on a pivotAngle parameter from -180 to 180. Then you manually set the pivotAngle to Vector3.SignedAngle(transform.forward, (desiredPosition - transform.position), Vector3.up) and CrossFade to your pivot state. Then, make sure to stop doing the manual rotation that the NavMeshAgent is doing in this tutorial during the pivot, otherwise they'll overshoot the turn. Hopefully that makes sense and the code works, I'm not in front of my desktop right now.
      You can get more advanced by doing things like having in-place pivots and walking and running in-motion pivots, ability to adjust pivot angle during the pivot (which you will need to be careful about), ability to cancel out of a pivot if this is a third person game the player stops trying to move midway through the pivot, etc. There's lots of little things to take into consideration, but you can work on those once you get the basics done.
      It's also really hard to find good pivoting animations. I've been using this pack for about 5 years now and it has most of what I want: assetstore.unity.com/packages/3d/animations/movement-animset-pro-14047

    • @XxTheArtisaNxX
      @XxTheArtisaNxX 4 місяці тому

      LEGEND! Thank you!! More or less got it working! Thank you for the video rec! I dont know how I didnt come across it before. Ive been searching for a solid Tut on pivots for about a year and a half now. Would still definetly watch an idepth Tut on your approach. Your tut on using root motion with navmesh was very thourough and easy to follow. Best on the subject IMHO@@GameDevelopmentBeyondTheBasics

  • @TheSankSound
    @TheSankSound 4 місяці тому +3

    i hope you get the attention you deserve. simply well explained, thanks dude

  • @rickfreeman3028
    @rickfreeman3028 5 місяців тому +1

    Lots of great information. Thanks for an excellent tutorial!

  • @Luvseatshawty
    @Luvseatshawty 2 місяці тому +1

    Thank you so much for this tutorial. You made it far more simple than the other one I referenced. For my project, all I really needed was "' var dir = (Agent.steeringTarget - transform.position).normalized" because I had the pivot logic setup already. I just needed to convert the movement to match my new root motion animations. Now the jitter is gone!

  • @andreydoroschenko2499
    @andreydoroschenko2499 Місяць тому +1

    This tutorial is awesome, please continue

  • @chrisnevin2928
    @chrisnevin2928 Місяць тому +1

    You're an absolute living legend! Thanks for the amazing video!

  • @simonwhitehead8878
    @simonwhitehead8878 4 місяці тому +1

    This was a great video. I don't know how I stumbled across it.. but it has definitely helped me! Thanks!

  • @johnnythesilverhand
    @johnnythesilverhand 4 місяці тому +2

    Best tutorial for navmesh keep it up❤

  • @paracosmic1066
    @paracosmic1066 4 місяці тому +1

    Excellent video. Solid pacing and good use of iteration. The quick reference to some free resources and ways it can be expanded are appreciated.
    I submit this comment to the Algo Gods. I hope you(s) stick with it.

  • @yacineyacine2951
    @yacineyacine2951 2 місяці тому +1

    So simple and lovely and easy to understand and everything you need video ❤❤❤❤

  • @renatowisockijunior
    @renatowisockijunior Місяць тому +1

    thank you for the tutorial

  • @ratz34
    @ratz34 5 місяців тому +1

    This is great! You got a subscriber!

  • @Tyrolia111
    @Tyrolia111 Місяць тому +1

    Great tutorial. Does what it says on the tin.

  • @yocliwood
    @yocliwood 3 місяці тому +1

    Thank you!I learned a lot!😀

  • @litt3rGames
    @litt3rGames Місяць тому +1

    thanks, thanks, thanks!!!!!!

  • @JoeDelory
    @JoeDelory 4 місяці тому

    Very nice tutorial. It would be interesting to see how you could solve interaction with other interactable with different animations. Pickup, Click on Buttons, drag lever etc. Thanks again. Yes, please also consider not to having so loudly music in the background. Thank you! Great Explained.

  • @BrunoBozicB
    @BrunoBozicB 5 місяців тому +2

    Great information here.
    Would love to see you implement head pivoting while standing up to a certain angle, above which the body begins moving (lower body movement animations playing) to "pivot in place".
    That would obviously entail possessing bought animation packs with the neccessary RM and IPC animations.
    Then following this, tranistion(s) from standing still (and pivoting) into directional jogging (these transitions usually are included into mocap pack(s)), the included animations usually having several "angles" like 35, 90, 135, 180 (or similiar).
    The challenge here is how to handle low angle input (lets say starting angle of 20 deg) and then switch to (lets say) a 90 degree movement-specific animation.
    The animation in the example (90 degree pivor) will turn the character by 90 degrees (RM) but what if the angle was 110? Would we play a 90 degree RM animation and then do rotation by the remaining 20 degrees?
    What if we need to "abort" a RM animation that is "in progress" and switch quickly to another? example: the player moves the mouse cursor to 90 degree left, this animation begins playing (and moving the character) and then moves the mouse into another heading 110 degree left, would we be aborting the animation that is in progress or how would we solve the problem?
    And then as a final problem, changing direction while "en route" with RM enabled where the challenge is turning around corners -> the RM animations will most likely end up colliding with the walls as its the animation that is actually driving the movement (being RM).

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  5 місяців тому +4

      Great questions! The way I handled this in Samurai Unicorn is I only trigger pivot animations if the angle is greater than 90 degrees, and then I have two different pivot blendtrees for in-place and in-motion. I capture the pivot angle at the time it's triggered because otherwise the angle you want to pivot keeps decreasing over the course of the animation, so it causes the blendtree to act funny if you don't cache the intended angle first and let the whole blend play out. The blendtrees themselves have an idle or forward jog at 0 degrees, and then spread the 90 L at -90, 180 L at -180, 90 R at 90, and 180 R and 180. This way if the pivot angle is -110 it will blend between the 90 L and 180 L and result in the correct animation you want. I also have an animation curve on all the pivot animations of a parameter called SuppressRotation which I set to 1. I multiply (1 - SuppressRotation) by my desired turnspeed so this way the whole rotation is preformed by the animation and the character won't "over turn" by having that additional script turning.
      For your second question about changing direction "en route", I don't currently allow the enemies to do this because there's a 1 s timer between when an NPC is allowed to pivot again. However, if this was for something like a player character where the user could spam a gamepad stick with some changing inputs mid-pivot, this can be accomplished with calling Animator.CrossFade() from code. By default, you can't CrossFade to the current animation state, however, there's an overload method call of CrossFade(animName, transitionTime, layerIndex, normalizedStartTime) so if you pass 0 in for normalizedStartTime, you can actually CrossFade a state to itself. This *might* look a little weird since you'll update the pivot angle parameter while it's still fading out that first pivot, but in practice it might be short enough of a time that a player won't notice.
      There hasn't been any collision with walls in-practice for me. Let me know if this all makes sense! And for the head pivoting, I'm not quite sure I understand what you mean, but is this for having the head turning to face the goal rotation before the body is done pivoting? If so, you can probably do that without animations or IK by updating the bone's rotation in LateUpdate().

    • @BrunoBozicB
      @BrunoBozicB 3 місяці тому

      Thank you for you answer.
      I am currently playing around with pivoting in place using mocap anims and some IK based head tracking.
      The animations I bought are root motion so I have been busy implementing turning the avatar towards the mouse position continually as the mouse moves.
      I first turn the avatars head towards the mouse position (but I clamp that to not go beyond some 170 degrees) and then the pivot anims kick in and these will eventually pivot the avatar to the mouse position.
      Theres some deadzone and LERPing there to avoid jitters.
      It looks nice at the moment but I am still confused by compositioning of blend trees, in order to keep things simple I currently transition from start to "standing idle and fidgeting" animation and then I transition to a 1D blend tree that takes the angle as the input (the angle between the current facing of the avatar and the mouse location), this directs the blends between my mocap pivoting animations, I got animation for pivots at 90 135, 180 and 45 degrees R and L.
      I am caching the angle that was set when the animation begins playing. Theres quite of bit of "if else" code there that makes sure the movements are natural-like.
      I am unsure if I would better do with 2D blend tree (as opposed to 1D) with perhaps an override to speed of the animation as the second input param, will have to see about that in the future.
      I will deal with aiming via IK even though I do have mocap anims for this, IK seems to be snappier and more natural (!).
      The next problem that I need to think about is transitioning from pivoting to walking, again I have walking animations and "turning while walking" animations, so I need to figure out if this will be another blend tree (I am especially worried about sharp turns) or maybe I just access the sharp turns directly from code (.PlayAnimation with .Crossfade), I have gotten several tips from game devs who claim that for sharp turns blend trees dont work all that well.
      Actually a lot of people tell me not to use the animator canvas (at all) but to actually do everything from code -> and to crossfade everything, I dont have enough experience to decide on this yet, it still seems to me that blend trees are a godsend for when you have sets of animations and you need to well, blend between them :)
      Any tips on how you would setup the pivot-in-place blend tree in terms of 1d or 2d (and what would be the best input params)? and then, how to go from this blend tree into walking blend, from walking to jogging and from jogging to running?
      I have seen some people put all of these into the same 2D blend tree and decide on whether we are walking or running based on the 2nd parameter that is speed.
      Thanks in advance.@@GameDevelopmentBeyondTheBasics

  • @ukaszgrabski2811
    @ukaszgrabski2811 4 місяці тому +1

    This is awesome, the best video about this subject so far. Simply works! Easy to grasp! Looking forward for more :) [maybe crouching?]

    • @ukaszgrabski2811
      @ukaszgrabski2811 4 місяці тому +1

      Or maybe rotating animation? 😊

    • @ukaszgrabski2811
      @ukaszgrabski2811 4 місяці тому +1

      And how to walk the slope? ;)

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  4 місяці тому

      @@ukaszgrabski2811 All great ideas! Crouching isn't too bad if you use the blendtree-of-blendtrees approach where each state in your main locomotion blendtree is actually another simple 2D blendtree blended on the parameter IsCrouching and then you have your normal walk and crouch walk for each of the 8 directions. So you need all 16 animations for 8 way movement both standing and crouching, but once you have them it's actually pretty straightforward to setup!
      And for slopes, is that more about how to limit movement if the slope is too steep, rotate the body based on the normal of the slope, or foot IK to position feet correctly on the slope?

    • @ukaszgrabski2811
      @ukaszgrabski2811 4 місяці тому

      @@GameDevelopmentBeyondTheBasics as it comes to slopes - yeah, in fact im looking for any general advices regarding it :) I would reeeealy appreciate any hints :) :) I tried my character on the small slope and it works pretty well but for instance I'm not able to make him climb up the stairs - for some reason it just goes trough it as its not there at all hehe

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  4 місяці тому +1

      @@ukaszgrabski2811 Are you using a CharacterController, Rigidbody, or NavMeshAgent based system for the character? If it's CharacterController then there's a parameter for step height. If it's NavMeshAgent, then the agent definition will have the parameters for slope and step. If it's Rigidbody, then you have to do a lot more advanced work. I recommend having an invisible plane that sits on top of the stairs, so really the character slides up a hidden slope instead of each step of the stair. You also have to do work to make sure you don't slide down slopes with the rigidbody solution that you don't have to think about for CharacterController/Rigidbody approach. Hope that helps, but I'm happy to answer any other questions you have!

  • @richardellingson7056
    @richardellingson7056 2 місяці тому +1

    I've been looking for a way to smoothly animate NPCs being able to strafe (looking in one direction, while moving in another). Undoing the 'isFacingMoveDirection' code:
    animator.SetFloat("InputY", aniDir.z, 0.5f, Time.deltaTime);
    animator.SetFloat("InputX", aniDir.x, 0.5f, Time.deltaTime);
    and changing rotation code to:
    var lookDir = (lookTarget.position - transform.position).normalized; // where the lookTarget some transform in the scene
    transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(lookDir), 180.0f * Time.deltaTime);
    does the trick, the result is so smooth! Add in some animation rigging, and the result looks great.
    I love this video. Fantastic pace and explanation that goes beyond basics. Thank you!

  • @ukaszgrabski2811
    @ukaszgrabski2811 4 місяці тому +2

    Been just wondering... let's say I have a dedicated character animation just for starting the walk, so the animation starts with a guy standing still and then smoothly starts walking. Would it possible to use this animation when the agent starts walking? So it will just play this animation first, non looped, and then switch to normal walk.

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  4 місяці тому

      Absolutely, but it takes slightly more work. You'll need an additional parameter called "Speed" which will just be the magnitude of your animDir vector or 0 when the horizontal/vertical are also set to 0. Then you need two new states, one Idle and one for Start Walking (both of them are regular states, not blendtrees). Now have your Idle transition to Start Walking when Speed > 0, Start Walking transition to Locomotion with Exit Time of .8 and .2% blend (or whatever looks good), and Locomotion transition back to Idle when Speed < .001 (floats can be finicky, which is why I would check for a small number instead of exactly equals 0).
      There's a few problems with this solution, but this is the basics. Some other things to fix it up more:
      1) Add interrupt source on Idle -> Start Walking transition, and then add a transition back from Start Walking -> Idle. This way the character doesn't have to play out the entire Start Walking animation if the movement was canceled or the player just taps the move forward key.
      2) Start Walking will always be start walking forward in this example, but you might want to change start to a blendtree and add the whole range of start walking -180 L, -90 L, forward, 90 R, 180 R and blend between any of those depending on which way the character should actually be walking.
      Hope that helps!

    • @ukaszgrabski2811
      @ukaszgrabski2811 4 місяці тому +1

      @@GameDevelopmentBeyondTheBasics awesome :) many thanks!

  • @alikhatami6610
    @alikhatami6610 4 місяці тому

    thank you for the awsome tutrial. I don't know if it is just me or not , but if possible next time uploading the video, can you make the music sound a bit lower?

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  4 місяці тому +1

      Thank you! And yes, sorry about the volume issue. I immediately noticed it after listening to the video with speakers instead of headphones. My video on serialization doesn't have this issue in it. :)

  • @andaoking
    @andaoking Місяць тому +2

    i have this problem that a models animator root object doesnt match the root i think,it will just keep turning when near the destination,how may i solve this

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  Місяць тому

      It sounds like your Animator component isn't on the root object for your character. You can just move the component to be on the root instead (the Animator uses the Avatar to find the bones recursively in the child hierarchy, so you don't need to worry about moving it) or you can add a component with OnAnimatorMove next to your Animator component that handles moving the parent object based on the Animator's root motion delta positon/rotation: docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorMove.html I recommend the first approach, but either works.

    • @andaoking
      @andaoking Місяць тому +1

      @@GameDevelopmentBeyondTheBasics turns out i used the wrong dir in the code,fixed it 😘your tutorials are the best ive seen,wonder if there will be a future video on this for implementing turning blendtree,not sure how to make the feet not slide😨

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  Місяць тому

      @@andaoking Glad you got it working! For a basic turning blendtree, you'll need 3 new float parameters: startSpeed, currentSpeed, and turnDirection. StartSpeed is how fast the character is going at the beginning on the turn (from standstill or pivot during a run), current speed is how far the player is currently pressing the stick (since it might start where the character is walking, but pivot into a run), and then turn dir is the angle difference between character's forward at start of pivot - desired pivot direction. Then it's just a little blendtree of blendtrees of blendtrees: first blending on pivot angle, then blending on start speed, then blending on current speed. You'll need a decent animation library full of start walking turn L/R anims, mid run pivoting, in-place turn L/R, etc. You can also reduce complexity by maybe removing the start speed parameter and layer of blendtree because it really only effects the first few frames of the blend typically.
      After that, you'll need to do a couple checks for if you should exit the blendtree early for things like the player released the stick part way through the turn, the player kept moving the direction stick mid-pivot and now the character is facing the correct direction halfway through the turn, etc.
      Hopefully that makes sense! I know it's a little complex for in-motion pivoting, but turning in place can really just be a 2D blendtree that blends between a turn in place 90 L - idle - turn in place 90 R all on a turn parameter that you adjust in code. It's really the movement speed at the start of turn and end of turn that complicated the in-motion pivoting version.

    • @andaoking
      @andaoking Місяць тому +1

      @@GameDevelopmentBeyondTheBasics thanks so much for the long reply,ill look into it!🥰you're the best!

  • @Felixfors
    @Felixfors 3 місяці тому

    is it difficult to change this to 1 directional instead of 8th? I only have one variable Walkspeed instead of horizontal and vertical

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  3 місяці тому

      Try it and find out! The 8-way movement isn't used much after the turning is implemented. I just really like reinforcing useful concepts like that since there's many applications where 8-way is useful (player controller, enemies that can strafe around when shooting, etc).
      But in the end, yes, replace "Vertical" with "WalkSpeed" and it will work just fine. You can also switch the BlendTree from 2D Freeform Cartesian to 1D since there's only one property you're blending on.

  • @LiminalDreams91
    @LiminalDreams91 2 місяці тому +1

    Would this work with urban traffic? Cars following a path?

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  2 місяці тому +1

      Personally, I wouldn't use a NavMesh for cars. This would be a nice solution for pedestrians where you can weight sidewalks low, the road very high, and crosswalks gets weight adjusted depending on traffic light (so they can cross sometimes and not other times). This still has issues where NPCs would dart into traffic, so you'd need a slightly more advanced graph setup so they know how to traverse between city blocks. That said, here's an interesting video on NPC navigation which is also different than the approach I mentioned: ua-cam.com/video/MXCZ-n5VyJc/v-deo.html
      That said, for cars themselves, I would go with a spline based approach using Unity's built-in Spline component. Cars are mostly faked in video games where they don't use actual physics to get around (until there's a crash, since you turn them on then), but instead follow "lane" splines setup around the city. Samyam had an interesting approach for cars in this video ua-cam.com/video/CqamCl_5Xe4/v-deo.html where she manually assigned waypoints to each car that they'd follow. It's not realistic, but in an arcade style game where cars and NPCs are set-dressing, it's easy to not notice simple AI like that.

    • @LiminalDreams91
      @LiminalDreams91 2 місяці тому +1

      @@GameDevelopmentBeyondTheBasics
      Incredible, thank you so much for your advice, sincerely.

  • @jawa4755
    @jawa4755 20 днів тому

    prob should turn music vol down or use autoducking

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  20 днів тому

      Yeah, I realized that after listening to the video with my speakers instead of the headphones I used while editing the video. My other videos have much quieter background music.

  • @AJAYSWAN
    @AJAYSWAN 4 місяці тому +1

    music annoying

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  2 місяці тому

      Sorry about that! I cringed when I first played back the video on speakers instead of the headphones I mixed it on originally. This was my first tutorial video so there was bound to be some rough parts with it. Don't worry though, audio levels should be better in my future videos.

  • @epicmcdude
    @epicmcdude 3 місяці тому +1

    Hello! I'm using part of this script but I'm having an issue when the destination is at an inclined angle, like a slope or stairs. The agent jitters back and forth between aligning itself with the surface and staying upright and I don't know how to fix this.
    I'm guessing it's this part of the code " go.transform.rotation = Quaternion.RotateTowards(go.transform.rotation, Quaternion.LookRotation(dir, Vector3.up), TurnSpeed.Value * Time.deltaTime); " and I tried adding the Vector3.up to see if it would stay upright but it doesn't work. Would you have any insight on how to fix this?

    • @GameDevelopmentBeyondTheBasics
      @GameDevelopmentBeyondTheBasics  3 місяці тому +1

      I'm not in front of my computer to test, but try setting dir.y to 0 before that line. That should fix it. The problem is the direction vector isn't flat if the steering target is above the Agent's feet, it's going to tip the agent up to face the higher angle.

    • @epicmcdude
      @epicmcdude 3 місяці тому

      ​@@GameDevelopmentBeyondTheBasics That worked! I was so confused yesterday for such a simple fix. Thank you my friend!