I have been struggling with this for too long, this blend tree is made to be used with the Unity built in third person controller, but I have my own already, and its a first person game…
This script kind of works but very inconsistently, for instance, when I strafe, (hold down only A, so forward is 0 and turn -1) sometime it plays the correct animation and strafes, but sometime it does nothing. Sometimes when I hold down only W is plays the walk animation, sometimes it does nothing.
The tree transitions from Grounded directional to Grounded strafe when isStrafing is true, which I set to trust when Mathf.Abs(Right) > 0.01, so whenever A or D are pressed, we should be strafing. All of my values are correct for a given input, as I have them public.
Blend Tree:
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimatorManager : MonoBehaviour
{
[Header("Animator")]
public Animator animator;
[Header("Animator Parameters")]
public string forwardParam;
public string rightParam;
public string turnParam;
public string strafe;
[Header("Blending")]
public bool blendMovement = true;
[Range(1, 100)] public float blendMoveSpeed = 5;
public bool blendTurning = true;
[Range(1, 20)] public float blendTurnSpeed = 5;
[Range(0, 0.25f)] public float strafeThreshold = 0.01f;
//
public float forward, right, turn;
public float forwardBlend, rightBlend, turnBlend;
public string currentAnimation;
// float forwardBlendAbsolute, turnBlendAbsolute;
public bool strafing;
//
Transform mTrans;
public void SetForward(float value) { SetFloatParameter(forwardParam, value); }
public void SetRight(float value) { SetFloatParameter(rightParam, value); }
public void SetTurn(float value) { SetFloatParameter(turnParam, value); }
// Update
void Update() {
float movementRange = Input.GetKey(KeyCode.LeftShift) ? 1 : 0.5f;
//
forward = Mathf.Clamp(Input.GetAxis("Vertical"), -movementRange, movementRange);
right = Input.GetAxis("Horizontal");
turn = Mathf.Clamp(Input.GetAxis("Mouse X"), -1, 1);
// Strafe
strafing = right != 0;
SetBoolParameter(strafe, strafing);
// Forward and Right (Movement)
if (blendMovement) {
forwardBlend = Mathf.Lerp(forwardBlend, forward, Time.deltaTime * blendMoveSpeed);
rightBlend = Mathf.Lerp(rightBlend, right, Time.deltaTime * blendMoveSpeed);
//
SetForward(forwardBlend);
SetRight(rightBlend);
} else {
SetForward(forward);
SetRight(right);
}
// Turning
if (blendTurning) {
turnBlend = Mathf.Lerp(turnBlend, turn, Time.deltaTime * blendTurnSpeed);
//
SetTurn(turnBlend);
} else {
SetTurn(turn);
}
//
currentAnimation = animator.GetCurrentAnimatorStateInfo(0).ToString();
}
// Animator
void SetFloatParameter(string param, float value) {
animator.SetFloat(param, value);
}
void SetBoolParameter(string param, bool status) {
animator.SetBool(param, status);
}
}