I think you’ve answered your own question. UpdateAnimator is never being called…
Try adding UpdateAnimator(); to Update();
Thank you Brian, I completely forgot about that part.
Working now ^.^
Hi there,
I’m having problems getting my animation to blend.
I’ve got it to the point that my character will idle when in play mode and move around, but it won’t transition/blend into any run animations. I feel like I’ve double checked my code to be the same as the course and I can’t see what I’m doing wrong.
I’ve come up with this error in the console, but I’m not sure what the fix is. Any help would be appreciated.
Sorry about the quick double post - I explored some more and kind of fixed the problem, but have another query in the process.
I realised that after changing the layer name from “Blend” to “forwardMotion”, that didn’t update in the Blend Tree - which remained with “Blend” (When Rick did it in the video, the name updated to forwardMotion"). So I tried updating the script and replaced “forwardMotion” with “Blend”, and that got the animation working fine.
I’m clearly just learning about the animation system, but this seems like the sort of thing that might cause issues down the line. Is there any trick to getting both to update? Or does it not matter?
Here’s a screenshot to hopefully clarify what I mean.
If you look carefully at the tabs in your inspector, you’ll see that there is a “Layer” tab, and a “Parameters” tab. Your “forwardMotion” was added in the Layer tab. (Animation Layers are for more complicated animation setups, and are not covered in this course). You need to add the forwardMotion as a float parameter in the Parameters tab.
Anyone knows why my character is shaking after moving? It seems to halt if somehow i hover over with the mouse at the Scene window: https://www.youtube.com/watch?v=Eq4BA-mubTI
Turn off the air conditioning, the poor bloke is clearly freezing!
On a more serious note, try this in Mover’s Update:
if(navMeshAgent remainingDistance < 1.0f) navMeshAgent.isStopped=true;
Then in MoveTo() make sure that navMeshAgent.isStopped=false; is in the method.
Thank you, it didn’t work but it’s a new tool in the box. After 1 more hours of debugging, i found the problem. It was something related to the terrain or baking the navMesh. Mine had some fold on itself when i was baking. Unfortunately, it got deleted in the long process of debug and i cannot show to others that may find the same problem. Somehow, there were some 90º folds in the blue baked mesh.
Try the following: Go to Animator and there you will find a tab for Layer and another for Parameter. Select Parameter and there you will find a label for animation, that one should match “forwardSpeed”.
Oh… This is 4 months ago. Well, maybe it will help someone else
Here is my understanding about transforming the velocity from global to local using InverseTransformDirection. I hope this helps everyone else understand this concept,
The transform.InverseTransformDirection is used because the Vector3 velocity = GetComponent().velocity; gives the speed in x, y and z coordinates in a global reference, so you could end up with a speed such as (5.7, 0, 0), but this is speed in the local reference is actually (0, 0, 5.7) because the player is moving in the Z axis locally.
Using visual studio and I am getting 2 error messages, 1 is for using private void the other is in update calling meathod UpdateAnimator();
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class mover : MonoBehaviour
{
[SerializeField] Transform target;
Vector3 destination;
NavMeshAgent agent;
Ray lastRay;
// Use this for initialization
void Start()
{
agent = GetComponent<NavMeshAgent>();
destination = agent.destination;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
MoveToCursor();
}
UpdateAnimator();
}
private void MoveToCursor()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
bool hasHit = Physics.Raycast(ray, out hit);
if (hasHit)
{
GetComponent<NavMeshAgent>().destination = hit.point;
}
if (Vector3.Distance(destination, target.position) > 1.0f)
{
destination = target.position;
agent.destination = destination;
}
private void UpdateAnimator()
{
Vector3 velocity = GetComponent<NavMeshAgent>().velocity;
Vector3 localVelocity = transform.InverseTransformDirection(velocity);
float speed = localVelocity.z;
GetComponent<Animator>().SetFloat("forwardMove",speed);
}
}
}
Your private void UpdateAnimator is embedded into the end of your MovetoCursor() method.
It should read like this:
private void MoveToCursor()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
bool hasHit = Physics.Raycast(ray, out hit);
if (hasHit)
{
GetComponent<NavMeshAgent>().destination = hit.point;
}
if (Vector3.Distance(destination, target.position) > 1.0f)
{
destination = target.position;
agent.destination = destination;
}
}
private void UpdateAnimator()
{
Vector3 velocity = GetComponent<NavMeshAgent>().velocity;
Vector3 localVelocity = transform.InverseTransformDirection(velocity);
float speed = localVelocity.z;
GetComponent<Animator>().SetFloat("forwardMove",speed);
}
Hi guys!
I have one question, that is if I use navMeshAgent.velocity.magnitude to control Blendtree(I think it can describe the real velocity’s value of the object, but i dont Know whether there will be some unpredictable problem), what different between navMeshAgent.velocity.magnitude and using transform.inverseTransformDirection. Thanks
Actually, they should yield the same result in most cases.
I am already finished with the Inventory system integration to the RPG project and everything is doing well. except when I am trying and using the code to my own personal project.
I had a similar issue with Felipe where my character seems to stutter when in range of the enemy.my player is like trying to move fwd.
I applied the code you gave and just changed the value to use instead of < 1.0f I used a smaller one which is 0.1f in my case and it fixed the issue that I am having.
I want to know what could be causing this? and will it have some impact or conflict on my code down the line. do I need to search for the root cause and apply a better fix to this?
Thank you.
It’s all a matter of scale. If 0.1f is working for you, then you should be fine. The issue is caused when the NavMeshAgent can’t quite get to the actual location… we use an affordance to say “this is close enough”.
Thanks for this! big help!
Just Curious why we’re using GetComponent within update, rather than on start and referencing later, wouldn’t this be faster?
This happens often when prototyping. No sense caching a value only to discover that you’re going in the wrong direction. Once you know the code is working well, then it is generally best to Cache references like these where appropriate.
As a general rule of thumb: You can always cache references to components on the same GameObject as the component you’re working on. GetComponent<NavMeshAgent>()
is a great example of this. You should think carefully before caching references on other gameobjects where the underlying GameObject reference could change.
Hi,
I made two mistakes. Putting the UpdateAnimator code inside the MoveToCursor. I realized that the if condition doesn’t allow it enough time to complete the animation.
The other mistake was the localVelocity was using x instead of z. The characters blue (facing) arrow is pointing in z direction.
Inspiration
- How can i access blend tree in animator controller from script ? - Questions & Answers - Unity Discussions
- Unity - Scripting API: Animator (unity3d.com)
- Character Movement Demo
Let me know if I’m missing anything. Thank you ^^
private void MoveToCursor()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(drawRayCast) {
Debug.DrawRay(ray.origin, ray.direction * 100, Color.red);
}
bool hasHit = Physics.Raycast(ray, out RaycastHit hit);
if (hasHit) {
GetComponent<NavMeshAgent>().destination = hit.point;
UpdateAnimator();
}
}
private void UpdateAnimator()
{
Vector3 velocity = GetComponent<NavMeshAgent>().velocity;
// globel x vs local x. Make it meaningful to the animator. Otherwise the scale is off.
var localVelocity = transform.InverseTransformDirection(velocity);
GetComponent<Animator>().SetFloat("fowardSpeed", localVelocity.x);
}