Issue with FPS Animation

Alsow this problem starts in here:Play animation with FPS controller? - Questions & Answers - Unity Discussions

Find solution access Animation script with GetComponent command it worked well but still have a problem Script say it can’t find the animation, maybe some one have some idea about this

Vector3 targetVelocity =newVector3(Input.GetAxis(“Horizontal”), 0, Input.GetAxis(“Vertical”));

targetVelocity = transform.TransformDirection(targetVelocity);

targetVelocity *= speed;

// Apply a force that attempts to reach our target velocity

Vector3 velocity = rigidbody.velocity;

Vector3 velocityChange = (targetVelocity - velocity);

velocityChange.x =Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);

velocityChange.z =Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);

velocityChange.y =0;

rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);

GetComponent();

And we go to the animation scrip here it is:

using UnityEngine;

using System.Collections;

publicclassMainControlAnimation : MonoBehaviour {

publicAnimator PlayerController;

// Use this for initialization

void Start () {

PlayerController = GetComponent();

}

// Update is called once per frame

void Update () {

if (Input.GetAxis(“Vertical”) !=0)

{

animation.Play(“walkAnimation”);

}

elseif (Input.GetAxis(“Vertical”) !=0)

{

animation.Play(“walkAnimation”);

}

else

{

animation.Play(“idleAnimation”);

}

}

}

It send a request to play an animation but cant find it, also here is pic of Animation controller maybe an issue is there but I can’t understand where:

You’re using Animation and Animator components simultaneously. Those are two entirely different systems for animating and they do not interact well with one another. I highly suggest watching the tutorial videos on the Animator component and follow-ups for the Animator controller, scripts, etc… (also called the mecanim system btw) and using that exclusively, as it is 100x better.

You will not call to specific animations in the manner that you’re doing here, but rather giving the animator system some variables so that it can decide which animation to play internally.

using UnityEngine;
using System.Collections;

public class MainControlAnimation : MonoBehaviour {
   public Animator PlayerController;

   bool walk;
   bool idle;

    // Use this for initialization
    void Start () {

        walk = false;
         PlayerController = GetComponent<Animator>();
       
    }
   
    // Update is called once per frame
    void Update () {



        if (Input.GetAxis("Vertical") !=0)
        {
            walk = true;
            Player("walk");
            //animation.Play("walkAnimation");
        }
        else if (Input.GetAxis("Vertical") !=0)
            {
                walk = true;
                Player("walk");
                //animation.Play("walkAnimation");
           }
            else
          {
              idle = true;
              Player("idle");
               //animation.Play("idleAnimation");
            }
        }

    void Player(string direction)
    {
        PlayerController.SetTrigger(direction);
    }
       
      
   
    }

Just Tried to use code like this with adding some triggers in AnimController but it didn’t work too.

I think I start fight vs air. And I am losing it(

Thanks for advise I try to use Float right now.

I can’t tell from the screenshot how you have the transitions set, but if you select your character while in play mode you’ll be able to see which animations are looping and maybe discover where it’s getting stuck. Are triggers the only condition, and are you positive the string you’re passing in corresponds to the names of the triggers exactly, capitalization and all?

Keep in mind that a trigger is a Parameter- it has to be added to the list of Parameters in the Animator window and then selected as a transition parameter, like in the attached image. You really need to watch all of the tutorial videos. Mecanim is not something you can stumble through without studying up on it first (nor is Unity, for that matter).

Thanks you my savior I just didn’t watch tutorials closely inuff ant the first time. I will upload full script after I finish with bool setup for idle anim. Thanks again.

Here is the control Script:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class rigBodyControl : MonoBehaviour {
    public float speed = 10.0f;
    public float gravity = 10.0f;
    public float maxVelocityChange = 10.0f;
    public bool canJump = true;
    public float jumpHeight = 2.0f;
    private bool grounded = false;



    void Awake()
    {
        rigidbody.freezeRotation = true;
        rigidbody.useGravity = false;
       
    }
   
    void FixedUpdate()
    {
        if (grounded)
        {
            // Calculate how fast we should be moving
            Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            targetVelocity = transform.TransformDirection(targetVelocity);
            targetVelocity *= speed;
           
            // Apply a force that attempts to reach our target velocity
            Vector3 velocity = rigidbody.velocity;
            Vector3 velocityChange = (targetVelocity - velocity);
            velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
            velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
            velocityChange.y = 0;
            rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
            GetComponent<MainControlAnimation>();
           
          
            // Jump
            if (canJump && Input.GetButton("Jump"))
            {
                rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
            }
        }

        // We apply gravity manually for more tuning control
        rigidbody.AddForce(new Vector3(0, -gravity * rigidbody.mass, 0));

        grounded = false;
    }

    void OnCollisionStay()
    {
        grounded = true;
    }

    float CalculateJumpVerticalSpeed()
    {
        // From the jump height and gravity we deduce the upwards speed
        // for the character to reach at the apex.
        return Mathf.Sqrt(2 * jumpHeight * gravity);
    }
}

It was taken at http://wiki.unity3d.com/index.php/Main_Page
And Animation play Script:

using UnityEngine;
using System.Collections;

public class MainControlAnimation : MonoBehaviour {
   public Animator PlayerController;

   int walkState = Animator.StringToHash("Base Layer.walkAnimation");
  
    // Use this for initialization
    void Start () {

       
         PlayerController = GetComponent<Animator>();
       
    }
   
    // Update is called once per frame
    void Update () {
        float move = Input.GetAxis("Vertical");
        PlayerController.SetFloat("walk", move);

        }
    }

Thanks to Lysander

When you start getting further into animating, you should stop using strings to set values to the Animator (for instance, you have “walk” there in the SetFloat function). What you should do instead is use a hash, which is an integer equivalent to that string and far far faster to access.

You’ll be accessing and/or setting mecanim parameters multiple times per frame in many cases, so it can make a big difference later. I attached an example of how I set up my hashes- you just replace the “walk” in your SetFloat with the hash variable and it’ll work (but faster).

Thanks for your help I will save it as a note for the future.

I am sorry for bothering you again, can you please check this script.

I tried to use your technique.

And its create this two errors:

  1. ArgumentException: GetKeyDownInt can only be called from the main thread.

Constructors and field initializers will be executed from the loading thread when loading a scene.

Don’t use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

UnityEngine.Input.GetKeyDown (KeyCode key) (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineInput.cs:471)

MainControlAnimation…ctor ()

  1. GetKeyDownInt can only be called from the main thread.

Constructors and field initializers will be executed from the loading thread when loading a scene.

Don’t use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

using UnityEngine;
using System.Collections;

public class MainControlAnimation : MonoBehaviour {
   private Animator AnimControl;
   private string MoveForvard = "walk";
   private string IdleState = "idle";
   private int hashMoveForvard;
   private int hashIdleState;
   //string buttonForvard = Input.GetKeyDown(KeyCode.W);
   bool forwardButton = Input.GetKeyDown(KeyCode.W);
   bool backButton = Input.GetKeyDown(KeyCode.S);
    // Use this for initialization
    void Start () {

      
         AnimControl = GetComponent<Animator>();
         hashIdleState = Animator.StringToHash(IdleState);
         hashMoveForvard = Animator.StringToHash(MoveForvard);
      
    }
  
    // Update is called once per frame
    void Update () {
        if (forwardButton)
        {
            forwardButton = true;
            AnimControl.SetTrigger(hashMoveForvard);
        }
            else if (backButton)
            {
                backButton = true;
                AnimControl.SetTrigger(hashMoveForvard);
            }
        else
        {
            forwardButton = false;
            backButton = false;
            AnimControl.SetTrigger(hashIdleState);
            }
        }

        }

Alsow I changed parameters on trigger

You can’t do this. Input.GetKeyDown is a function, and you can’t call a function from a class field initializer like this to begin with (a field initializer is assigning a value to a class field in the same line that you define the field). It has to be in an Awake or Start function to initialize to a non-constant value.

Even more importantly in this case though, this function would return a “false” value and the false value is what would get stored, not a reference to the function. So, you’d call forwardButton from then on and it would always be false, because that’s the value stored there. Get it? While it is possible to store a delegate to a function in the manner you’re thinking of here, it’s complicated and not at all intuitive- intermediate level programming, so you shouldn’t be messing with it yet IMO.

Instead, just put these back in your If statements like you had them before and remove the bools from the script.