How to program a bunch of 1st person animations at different speeds - c#

I have made 4 different types of animation clips in an animator for an an empty gameobject called "Animator". The main camera is a child of this.
The animations feature a running cycle, a walking cycle, a crouch cycle, and an idle cycle. They all have a trigger that let's them play.
How am I able to measure the speed of the player and execute these animations when the player reaches a certain speed. I have found someone else trying to do this and it works but only for idle and walk. But unfortunately I can't get the sprint and crouch to work. I'm not sure what to do, either have the sprint and crouch animations or just change the speed of the walk animation depending on whether the player is sprinting or crouching. I'll leave a comment where the code I found is.
Here's what I have in my player controller (thge trigger stop is for the idle animation):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
Animator _ar;
public float speed;
[Range(-5, -20)]
public float gravity = -9.81f;
public float sprintSpeed = 6f;
public float walkSpeed = 4f;
public float crouchSpeed = 2f;
public float standHeight = 1.6f;
public float crouchHeight = 1f;
Vector3 velocity;
bool isGrounded;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public Light _l;
//Set this to the transform you want to check
public Transform objectTransfom;
private float noMovementThreshold = 0.0001f;
private const int noMovementFrames = 1;
Vector3[] previousLocations = new Vector3[noMovementFrames];
public bool isMoving;
//Let other scripts see if the object is moving
public bool IsMoving
{
get { return isMoving; }
}
void Awake()
{
//For good measure, set the previous locations
for (int i = 0; i < previousLocations.Length; i++)
{
previousLocations[i] = Vector3.zero;
}
}
void Start()
{
_ar = GameObject.Find("Animator").GetComponentInChildren<Animator>();
}
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
//Below here is the code I found. The if statements for isMoving, is what I put in to see if
//this worked.
//Store the newest vector at the end of the list of vectors
for (int i = 0; i < previousLocations.Length - 1; i++)
{
previousLocations[i] = previousLocations[i + 1];
}
previousLocations[previousLocations.Length - 1] = objectTransfom.position;
//Check the distances between the points in your previous locations
//If for the past several updates, there are no movements smaller than the threshold,
//you can most likely assume that the object is not moving
for (int i = 0; i < previousLocations.Length - 1; i++)
{
if (Vector3.Distance(previousLocations[i], previousLocations[i + 1]) >= noMovementThreshold)
{
//The minimum movement has been detected between frames
isMoving = true;
break;
}
else
{
isMoving = false;
}
}
if(isMoving == true)
{
if (Input.GetKeyDown(KeyCode.LeftShift))
{
speed = sprintSpeed;
_ar.SetTrigger("WalkSprint");
}
else if (Input.GetKeyUp(KeyCode.LeftControl))
{
speed = crouchSpeed;
_ar.SetTrigger("WalkCrouch");
//transform.localScale = new Vector3(0.8f, 0.5f, 0.8f);
}
else
{
speed = walkSpeed;
_ar.SetTrigger("Walk");
//transform.localScale = new Vector3(0.8f, 0.85f, 0.8f);
}
}
else
{
_ar.SetTrigger("Stop");
}
}
}

Unfortunately, as with many issue in Game Dev, this could be a number of different issues (or all of them!). Here is where you can start to debug:
Check your error log to see if there is anything obvious that jumps out at you, like a bad reference to a Game Object/Componenet.
Watch the animator. You should be able to have the Animator open, side-by-side with your game window while the game is running. You should be able to see the animations running and transitioning. See if something is not linked properly, or if an animation time is configured incorrectly, etc.
Add some debug statements, like outputting the current trigger being set. I would even verify that your inputs are configured correctly. Maybe add some additional conditionals at the beginning that debug what inputs are being pressed.
As #OnionFan said, your Input check is for KeyUp for the Crouch key. That should probably be KeyDown.

Related

In Unity player movement speed is not being added to the first bullet fired

I'm trying to make a 2D top-down shooter in Unity. I want it so when the you hold down the left mouse button the player fires a series of bullets until you run out of ammo. The player's movement speed is slowed while firing and the players movement speed should be added to the bullet's movement speed. For some reason the players movement speed is only applied to the bullets AFTER the first bullet is fired. The first bullet always seems to keep the slightly faster 'sprint' movement speed.
Weapon script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour
{
private GameObject bulletPrefab;
private Transform firePoint;
private PlayerControls player;
public float fireForce = 10f;
private bool cooldown = false;
private int bullets;
public int bulletDamage;
public int maxAmmo;
public float fireRate = 0.5f;
public float reloadRate = 2.5f;
public bool noAmmo = false;
public float walkSpeed = 2f;
private float timeSinceLastShot = 0f;
void Update()
{
// increase time since last shot
timeSinceLastShot += Time.deltaTime;
// if left-click is held down
if (Input.GetMouseButton(0))
{
// if enough time has passed since last shot
if (timeSinceLastShot >= fireRate && noAmmo == false)
{
player.moveSpeed = walkSpeed;
bullets -= 1;
cooldown = true;
if (bullets <= 0)
{
noAmmo = true;
player.moveSpeed = player.baseSpeed;
}
// instantiate a bullet
GameObject bullet = Instantiate(bulletPrefab, firePoint.transform.position, Quaternion.identity);
bullet.GetComponent<Bullet>().bulletDamage = bulletDamage;
// add player movement speed to bullet's speed
bullet.GetComponent<Rigidbody2D>().velocity = player.GetComponent<Rigidbody2D>().velocity;
bullet.GetComponent<Rigidbody2D>().AddForce(transform.up * fireForce, ForceMode2D.Impulse);
// reset time since last shot
timeSinceLastShot = 0f;
}
}
// if left-click is not held down
else
{
cooldown = false;
// restore player movement speed
player.moveSpeed = player.baseSpeed;
}
}
public void FillMag()
{
bullets = maxAmmo;
noAmmo = false;
}
}
PlayerControls:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControls : MonoBehaviour
{
public float moveSpeed = 5f;
public float baseSpeed = 5f;
public int health;
public Weapon weapon;
private Rigidbody2D rb;
Vector2 mousePosition;
Vector2 moveDirection;
public float walkSpeed = 2f;
void Update()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveY = Input.GetAxisRaw("Vertical");
moveDirection = new Vector2(moveX, moveY).normalized;
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rb.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
Vector2 aimDirection = mousePosition - rb.position;
float aimAngle = Mathf.Atan2(aimDirection.y, aimDirection.x) * Mathf.Rad2Deg - 90f;
rb.rotation = aimAngle;
}
}
The player is moving from left to right.
Player firing
According to Unity's lifecycle, inputs are only calculated just before the Update method is called, but physics are applied during the FixedUpdate method. Is this what is causing my problems? I've tried moving some calculations into FixedUpdate and LateUpdate but nothing seems to make any difference.
Any help is appreciated. I've been banging my head against this for a few days now. I'm an amature, so feel free to explain like I'm 5.
So there are 2 problems with your code:
if you are not holding down left mouse, but multiple click instead:
the else statement in the Update() will immediately set it player back to base speed, which is not really matter if you intent to holding your mouse.
There are 2 concurrent things happen
first, you set player moveSpeed in Weapon Update()
at the same time, you calculate player velocity in Player Update()
But it TAKES TIME for player to update velocity before you get it right to your weapon.
Therefore, I recommend you to use IEnumerator to delay the fire action.
public class Weapon : MonoBehaviour
{
void FixedUpdate()
{
// increase time since last shot
timeSinceLastShot += Time.deltaTime;
// if left-click is held down
if (Input.GetMouseButton(0))
{
// if enough time has passed since last shot
if (timeSinceLastShot >= fireRate && noAmmo == false)
{
//player.moveSpeed = walkSpeed;
StopAllCoroutines();
StartCoroutine(SetSpeed());
bullets -= 1;
cooldown = true;
if (bullets <= 0)
{
noAmmo = true;
player.moveSpeed = player.baseSpeed;
}
// instantiate a bullet
StartCoroutine(FireBulelt());
// reset time since last shot
timeSinceLastShot = 0f;
}
}
// if left-click is not held down
}
IEnumerator SetSpeed()
{
player.moveSpeed = walkSpeed;
yield return new WaitForSeconds(0.5f);
cooldown = false;
// restore player movement speed
player.moveSpeed = player.baseSpeed;
yield return null;
}
IEnumerator FireBulelt()
{
yield return new WaitForSeconds(0.05f);
GameObject bullet = Instantiate(bulletPrefab, player.transform.position, Quaternion.identity);
print(" player.GetComponent<Rigidbody2D>().velocit " + player.GetComponent<Rigidbody2D>().velocity);
// add player movement speed to bullet's speed
Rigidbody2D bulletRB = bullet.GetComponent<Rigidbody2D>();
print(" bulletRB.velocit " + bulletRB.velocity);
bulletRB.velocity = player.GetComponent<Rigidbody2D>().velocity;
print(" after bulletRB.velocit " + bulletRB.velocity);
bulletRB.AddForce(transform.up * fireForce, ForceMode2D.Impulse);
}
}
And you should add print() like I did to keep track of code behavior when you're debugging.

How to make the character move a certain distance when a button is pressed or tapped

So I'm working on a 2D game right now just to learn different stuff or codes related to making 2D games.
So I've come to a trouble where I got curious on how to make a character move a certain distance like per say 1 block per tap of button. I will give an example here. So take imagine the grid as a land.
Move a certain distance.
This one is the one my character is doing with my current code
and here's my movement code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class keycontrol : MonoBehaviour
{
private float moveSpeed;
private Rigidbody2D rb2d;
private Vector2 change;
private Animator animator;
bool isXMoving;
bool isYMoving;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
void Update()
{
change.x = Input.GetAxisRaw("Horizontal");
change.y = Input.GetAxisRaw("Vertical");
if (Mathf.Abs(change.x) > Mathf.Abs(change.y))
{
change.y = 0;
}
else
{
change.x = 0;
}
animator.SetFloat("walk_right", change.x);
animator.SetFloat("walk_left", -change.x);
animator.SetFloat("walk_down", -change.y);
animator.SetFloat("walk_up", change.y);
}
void FixedUpdate()
{
rb2d.MovePosition(rb2d.position + change * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 150;
animator.speed = 1.5f;
}
else
{
moveSpeed = 70;
animator.speed = 1f;
}
}
}
Thanks a lot for help
I think the problem is just your movement speed. You multiply your speed with Time.fixedDeltaTime but that isn't necessary because that value will be constant. Instead, try just setting the speed to 1 and remove the Time.fixedDeltaTime.
Note: Time.deltaTime is used to make the character move a certain amount per frame because the shorter the time between frames, the less the character will move. Time.fixedDeltaTime stays constant because it is the time between each physics frame.
If I'm understanding correctly, the reason it keeps moving is because the input stays greater than zero. You could add a variable to check if the keys are already down to stop the movement.
There are two options here I think,
Make the user click everytime then want to move (press key, lift finger, press key, etc)
Add a timer to make it move every Nth second
For (1) we could just add an variable to say we are moving already.
//Changes IsXMoving and IsYMoving to a single boolean
bool isMoving = false;
///Start, Update, etc
void FixedUpdate()
{
//Check if we are already moving - if we are not, update movement
if (!isMoving)
{
rb2d.MovePosition(rb2d.position + change * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 150;
animator.speed = 1.5f;
}
else
{
moveSpeed = 70;
animator.speed = 1f;
}
}
//Check we are moving by getting the magnitude - if it zero, we are still
isMoving = (change.magnitude != 0);
}
The second option (2) would basically replace this with a basic timer.
//Removed IsXMoving and IsYMoving
//lastMove will store the time we last allowed movement and delay is
//the minimum time between movements in seconds
float lastMove;
float delay = 1; //1 second
void FixedUpdate()
{
//Check if enough time has passed to be allowed to move
if (lastMove + delay < Time.time)
{
rb2d.MovePosition(rb2d.position + change * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 150;
animator.speed = 1.5f;
}
else
{
moveSpeed = 70;
animator.speed = 1f;
}
//Only update the time if we are moving
if (change.magnitude > 0)
lastMove = Time.time;
}
}

How to Prevent sliding in 2d movement

hi i want to move my charachter i looked around but couldnt find solutions for my code i just want when my charachter moves and i not pressed move forward button then it stop but not instantly it just stops instantly after i unpressed d button here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public Rigidbody2D rb2d;
bool ismoving;
public float speed = 5f;
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
if (Input.GetButton("Horizontal"))
{
ismoving = true;
}
else { ismoving = false; }
if (ismoving)
{
rb2d.AddForce(new Vector2(horizontal, 0) * speed * Time.fixedDeltaTime *10);
}
else
{
while((rb2d.velocity) != (rb2d.velocity = Vector2.zero))
{
rb2d.AddForce(new Vector2(horizontal, 0) * Time.fixedDeltaTime *-1);
}
}
}
}
You can change the multiplier for your deceleration to a greater value
while((rb2d.velocity) != (rb2d.velocity = Vector2.zero))
{
rb2d.AddForce(new Vector2(horizontal, 0) * Time.fixedDeltaTime * -10);
}
Now it should decelerate 10 times faster than before
Currently, you stop adding force when the key is released. How about approaching a speed of 0 once the key is released? Like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public Rigidbody2D rb2d;
bool ismoving;
public float maxspeed = 5f;
private float currentSpeed = 0f;
private float movingDirection = 0f;
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
if (Input.GetButton("Horizontal"))
{
ismoving = true;
movingDirection = horizontal;
}
else
{
ismoving = false;
// keep the movingDirection as it is.
}
if (ismoving)
{
// accelerate
currentSpeed += 5 * Time.fixedDeltaTime;
currentSpeed = Mathf.Clamp(currentSpeed, 0, maxspeed);
}
else
{
currentSpeed -= 5 * Time.fixedDeltaTime;
currentSpeed = Mathf.Clamp(currentSpeed, 0, maxspeed);
// also fake some friction
rb2d.velocity = rb2d.velocity * 0.96f;
}
// always apply the force, it may be 0 though.
rb2d.AddForce(new Vector2(movingDirection, 0) * currentSpeed;
}
}
Maybe it works better when setting velocity instead of adding force with this approach. But you may get the point: Instead of instantly stopping to add force when the key is released, we simply decrease a variable currentspeed and continue to work with that until we stop. Since horizontal is getting 0 quickly after releasing the key, I added a helper variable to remember the direction we were going before releasing the key called movingDirection.
Also a nice-to-know tip: Try to do all Input... Calls in Update(), save states in variables that you then use in FixedUpdate(). Because otherwise, you may run into problems, when things like Input.GetButtonDown() is true for 2-3 FixedUpdate Calls, but you want things to happen once per click/press like shooting.

Unity: Animation looping while waiting for state transition

I previously posted this question on the gameDev SE but with no luck, therefore I am trying to see if I could find some help here.
I am having some troubles with the transitions in my animator. Specifically, I am trying to set up a some code to handle combo sequences, and to do so I am using coroutines that exploit the state machine given by the animations in the animator. Here is my script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityEngine.SceneManagement;
/*enum PlayerState is a list of states that can be taken by the player character. They will be used to implement a finite state machine-like
behavior with the actions it can take*/
public enum PlayerState {
walk,
attack,
interact,
dash,
stagger
}
public class Player_Base : MonoBehaviour {
//Basic parameters
Rigidbody2D myRigidBody; //These are to call the components of the Player GameObject
public static Transform playerPos;
public PlayerState currentState;
Animator myAnimator;
public HealthManager myStatus;
private bool isAlive = true;
//Sorting layers parameters
public CapsuleCollider2D myFeet;
public static float playerVertPos; // Need this to sort other objects layers in another script.
//Movement parameters
[SerializeField] float moveSpeed = 3f; // use [serfiel] or public in order to have something that you can modify from Unity UI
public Vector2 moveInput;
private bool isMoving;//Implementing the state machine and the *blend trees*, you need only to define one bool for all animations of a kind (eg walking anims)
//Combat parameters
private int comboCounter = 0;
private float comboTimer = 0;
//dash parameters
[SerializeField] float dashTimeMax = 1f;
[SerializeField] float dashTime = 0;
[SerializeField] float dashPush = 0.001f;
[SerializeField] float dashSpeed = 10f;
// Use this for initialization
void Start()
{
currentState = PlayerState.walk;//Initial default state of the player
myRigidBody = GetComponent<Rigidbody2D>(); /*the getcomp looks for the related component in the <> and uses it in the code*/
myFeet = GetComponent<CapsuleCollider2D>();
myAnimator = GetComponent<Animator>();
myAnimator.SetFloat("MoveX", 0);//If i do not set a default values for these, if player attacks without moving first, all colliders will activate and will hit all around him
myAnimator.SetFloat("MoveY", -1);
myStatus = GameObject.FindObjectOfType<HealthManager>();
}
// Update is called once per frame
void Update()
{
playerVertPos = myFeet.bounds.center.y;
moveInput = Vector2.zero;/*getaxis and getaxisraw register the input of the axes and outputs +1 or -1 according to the axis direction*/
moveInput.x = Input.GetAxisRaw("Horizontal");
moveInput.y = Input.GetAxisRaw("Vertical");
if (!isAlive)
{
return;
}
else {
if (currentState == PlayerState.walk)//It will consider walking only when in that state, this means that if it is attacking for instance,
//it needs to change its state. Good for compartimentalization of the actions (otherwise I could have changed the direction of the attacks)
{
if (moveInput != Vector2.zero)//This if statement is such that if there is no new input to update the movement with, the last (idle) animation
//will remain, so if you go right and stop, the player keeps facing right
{
Move();
myAnimator.SetFloat("MoveX", moveInput.x);
myAnimator.SetFloat("MoveY", moveInput.y);
myAnimator.SetBool("isMoving", true);
}
else {
myAnimator.SetBool("isMoving", false);
}
}
//Attack inputs
if (Input.GetKeyDown(KeyCode.Mouse0) && currentState != PlayerState.attack)//second clause because i do not want to indefinitely attack every frame
{
StartCoroutine(FirstAttack());
}
if (Input.GetKeyDown(KeyCode.Space) && currentState != PlayerState.dash)
{
StartCoroutine(Dashing());
}
DeathCheck();//check if player is still alive
}
}
public void Move()
{
moveInput.Normalize();
myRigidBody.MovePosition(myRigidBody.position + moveInput * moveSpeed * Time.deltaTime);
//If i want to work with the velocity vector: i have to use rb.velocity, not just taking the xplatinput times movespeed
}
public void MoveOnAnimation(int xMove, int yMove, float displacement)
{
moveInput.x = xMove;
moveInput.y = yMove;
moveInput.Normalize();
myRigidBody.MovePosition(myRigidBody.position + moveInput * displacement * Time.deltaTime);
}
private IEnumerator FirstAttack() {
//Start Attack
comboCounter = 1;
myAnimator.SetInteger("comboSequence", comboCounter);
currentState = PlayerState.attack;
yield return new WaitForSeconds(AttackTemplate.SetDuration(0.6f) - comboTimer);//Problem: if i reduce the time below the animation time of the second animation, the second animation won't go untile the end
comboTimer = AttackTemplate.SetComboTimer(0.4f);
//if combo not triggered:
while (comboTimer >= 0)
{
Debug.Log(comboTimer);
comboTimer -= Time.deltaTime;
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Debug.Log("Chained");
StopCoroutine(FirstAttack());
StartCoroutine(SecondAttack());
}
yield return null;
}
comboCounter = 0;
myAnimator.SetInteger("comboSequence", comboCounter);
currentState = PlayerState.walk;
}
private IEnumerator SecondAttack()
{
comboCounter = 2;
myAnimator.SetInteger("comboSequence", comboCounter);
currentState = PlayerState.attack;
yield return null;
//if combo not triggered:
yield return new WaitForSeconds(AttackTemplate.SetDuration(0.9f));
comboCounter = 0;
myAnimator.SetInteger("comboSequence", comboCounter);
currentState = PlayerState.walk;
}
private void Dash()
{
if (dashTime >= dashTimeMax)
{
dashTime = 0;
myRigidBody.velocity = Vector2.zero;
currentState = PlayerState.walk;
}
else
{
currentState = PlayerState.dash;
dashTime += Time.deltaTime;
moveInput.Normalize();
Vector2 lastDirection = moveInput;
myRigidBody.velocity = lastDirection * dashSpeed;
}
}
private IEnumerator Dashing()
{
currentState = PlayerState.dash;
for (float timeLapse = 0; timeLapse < dashTime; timeLapse = timeLapse + Time.fixedDeltaTime)
{
moveInput.Normalize();
Vector2 lastDirection = moveInput;
myRigidBody.velocity = lastDirection * dashSpeed;
}
yield return null;
myRigidBody.velocity = Vector2.zero;
currentState = PlayerState.walk;
}
private void DeathCheck() //if the player health reaches 0 it will run
{
if (HealthManager.health == 0) {
isAlive = false; // this is checked in the update, when false disables player inputs
myRigidBody.constraints = RigidbodyConstraints2D.FreezePosition; // if i don't lock its position, the last bounce with the enemy pushes the player towards inifinity
myAnimator.SetTrigger("death");//triggers the death animation
StartCoroutine(LoadNextScene());
}
}
[SerializeField] float LevelLoadDelay = 5f;
[SerializeField] float LevelSlowMo = 1f;
IEnumerator LoadNextScene()
{
Time.timeScale = LevelSlowMo;
yield return new WaitForSecondsRealtime(LevelLoadDelay);
Time.timeScale = 1f;
var CurrentSceneIndex = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(CurrentSceneIndex + 1);
}
}
What I am doing basically is to use enums to define the player states and on input, if the player is not already in the attacking state, perform an attack. Once the FirstAttack() is called, it will first of all update an integer, comboCounter, which handles the transitions between consecutive attacks, input said integer in the animator and then change my state to attack. After this, I created a while loop that goes on until the end of an established time interval during which the player would be able to press the same attack button to chain the combo. If this does not happen, the state and integer parameter are reset.
The problem I am facing is that while the player can actually perform the combo with the second attack, during all the interval in which the first animation is active it keeps looping. Furthermore, I noticed that the second animation does not reach the end, it seems like it stops once the interval that I previously set will end.
Update: This is the screenshot of my animator window:
The transitions any state -> 1stAttack and 1stAttack -> 2ndAttack is handled by the same integer parameter, comboSequence, which is set to 0 normally, to 1 for 1stAttack and to 2 for the second one. I observed that the transition any state -> 1stAttack is triggered multiple times whenever I press the hit button, in line with the looping problem I am facing.
I have tried a couple of things, for instance using normal functions instead of a coroutine, but in this way, I do not understand why, there are problems with the enums states, also I think that in the long term this approach would be more modular and customisable. I feel like I am missing something trivial but I do not understand what and it has been some time now, so any help would be much appreciated!
Disable Can Transition To Self = false

Unity C# Animator Transitions

I'm trying to get my enemies run animation to play when he is moving, and switch back to idle when he has stopped. However my current code doesn't seem to be doing this and instead my enemy remains in the idle state constantly. I have checked that my variables are being set but they just don't seem to be getting filtered through to my animator to make the transitions. I also have an error which doesn't seem to stop the game from playing but pops up in the console. The error is Controller 'Pirate': Transition " in state 'Idle_Pirate' uses parameter 'walking' which is not compatible with condition type. I assume this is the culprit but after trying a few different suggestions from googling I am struggling to find a solution. This is the code from the script attached to my enemy. Apologies if it is a little crude I am still learning. Any help is greatly appreciated.
using UnityEngine;
using System.Collections;
public class AI : MonoBehaviour {
public float walkSpeed = 2.0f;
public float wallLeft = 0.0f;
public float wallRight = 2.0f;
float walkingDirection = 1.0f;
Vector3 walkAmount;
float timeCheck = 0.0f;
float walkCheck = 0.0f;
public float maxSpeed = 5f;
bool facingRight = true;
bool idle = true;
Animator anim;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void FixedUpdate () {
}
void Update () {
if (timeCheck >= 2.0f) {
walkAmount.x = walkingDirection * walkSpeed * Time.deltaTime;
if (walkingDirection > 0.0f && transform.position.x >= wallRight) {
walkingDirection = -1.0f;
Flip ();
} else if (walkingDirection < 0.0f && transform.position.x <= wallLeft) {
walkingDirection = 1.0f;
Flip ();
}
walkCheck = walkCheck + Time.deltaTime;
idle = false;
}
if (walkCheck >= 2.0f) {
idle = true;
walkAmount.x = 0;
timeCheck = 0.0f;
walkCheck = 0.0f;
}
timeCheck = timeCheck + Time.deltaTime;
transform.Translate(walkAmount);
anim.SetBool ("walking", idle);
}
void Flip () {
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
Managed to figure it out myself anyway, turns out I was using my animation in my animator instead of my sprites, must of dragged the wrong thing at some point. Thanks to those who took the time to read anyway.

Categories