So I have to script that assigns moveDirection to a velocityX, and velocityY. I also have the second script that accesses it. I;m doing all this to create a 8 direction animation in unity.
So here's the code
private void ApplyFinalMovements()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
currentInput = new Vector2(_speed * verticalInput, _speed * horizontalInput);
#region CheckingInputsAnims
if (verticalInput>0)
isWalking = true;
else isWalking = false;
if (verticalInput<0)
isWalkingBackwards = true;
else isWalkingBackwards = false;
#endregion
float moveDirectionY = moveDirection.y;
moveDirection = transform.transform.TransformDirection(Vector3.forward * currentInput.x) (transform.TransformDirection(Vector3.right) * currentInput.y);
velocityZ = moveDirection.y;
velocityX = moveDirection.x;
moveDirection.y = moveDirectionY;
}
And the script that accesses the velocity in order to get it into animator
public class animationStateController : MonoBehaviour
{
Player player;
Animator animator;
private float velocityZ;
private float velocityX;
private void Start()
{
player = FindObjectOfType(typeof(Player)) as Player;
animator = GetComponent<Animator>();
}
void Update()
{
player.velocityZ = velocityZ;
player.velocityX = velocityX;
animator.SetFloat("VelocityZ", velocityZ, 0.1f, Time.deltaTime);
animator.SetFloat("VelocityX", velocityX, 0.1f, Time.deltaTime);
if (player.isWalking)
animator.SetBool("isWalking", true);
else animator.SetBool("isWalking", false);
if (player.isWalkingBackwards)
animator.SetBool("isWalkingBackwards", true);
else animator.SetBool("isWalkingBackwards", false);
if (player.isSprinting)
animator.SetBool("isSprinting", true);
else animator.SetBool("isSprinting", false);
if (player.startJump)
animator.SetBool("startJump", true);
else animator.SetBool("startJump", false);
if (player.midAir)
animator.SetBool("midAir", true);
else animator.SetBool("midAir", false);
if (player.endJump)
animator.SetBool("endJump", true);
else animator.SetBool("endJump", false);
if (player.isCrouching)
animator.SetBool("isCrouching", true);
else animator.SetBool("isCrouching", false);
}
}
Here's the whole code for Player:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine;
public class Player : MonoBehaviour
{
private CharacterController _controller;
private Camera playerCamera;
[Header("Stats")]
[Header("Functional Optons")]
[SerializeField] private bool canLook = true;
[SerializeField] private bool canMove = true;
[SerializeField] private bool canSprint = true;
[SerializeField] private bool canJump = true;
[SerializeField] private bool canCrouch = true;
[SerializeField] private bool WillSlideOnSlopes = true;
[SerializeField] private bool canUseHeadbob = true;
[SerializeField] private bool useFootsteps = true;
[SerializeField] private bool canInteract = true;
[SerializeField] private bool UseStamina = true;
public bool midAir;
private bool midAirLastFrame = false;
[Header("Animator Parameters")]
public float velocityZ;
public float velocityX;
[Header("Controls")]
public KeyCode sprintKey = KeyCode.LeftShift;
public KeyCode jumpKey = KeyCode.Space;
public KeyCode crouchKeyHold = KeyCode.LeftControl;
public KeyCode crouchKeySwitch = KeyCode.C;
public KeyCode interactKey = KeyCode.E;
[Header("Movement Parameters")]
[SerializeField] private float _speed = 3f;
[SerializeField] private float _sprintSpeed = 5f;
[SerializeField] private float _crouchSpeed = 2f;
[SerializeField] private float _slideSpeed = 12f;
public bool isWalking;
public bool isWalkingBackwards;
public bool isSprinting;
private bool SlidedLastFrame;
private Vector3 moveDirection;
private Vector2 currentInput;
[Header("Jumping Parameters")] // dźwięk spadania dodać po czasie się zwiększa
[SerializeField] private float _gravity = 9.81f;
[SerializeField] private float _jumpHeight = 3f;
[SerializeField] private float _fallSpeed;
[SerializeField] private float _fallDamage;
private float _landStartPos;
[SerializeField] private AudioClip[] jumpClips = default;
[SerializeField] private AudioClip[] landClips = default;
public bool startJump;
public bool endJump;
[Header("Crouching Parameters")]
[SerializeField] private float crouchHeight = 1f;
[SerializeField] private float standingHeight = 2.25f;
[SerializeField] private float timeToCrouch = 0.25f;
[SerializeField] private Vector3 crouchingCenter = new Vector3(0, 0f, 0);
[SerializeField] private Vector3 standingCenter = new Vector3(0, 0, 0);
public bool isCrouching;
private bool duringCrouchAnim;
[Header("Look Parameters")]
public float _sensitivity = 100f;
float xRotation = 0f;
private bool cursorShow = false;
[Header("Health Parameters")]
[SerializeField] private float maxHealth = 100f;
[SerializeField] private float timeBeforeRegenStarts = 8f;
[SerializeField] private float healthValueIncrement = 0.5f;
[SerializeField] private float healthTimeIncrement = 0.1f;
[SerializeField] private AudioClip[] hurtClips = default; //SZUKASZ AUDIO SOURCE ZYCIE
[SerializeField] private AudioSource playerAudioSource = default;
[SerializeField] private float currentHealth;
private Coroutine regeneratingHealth; //ogarnij couritine
public static Action<float> OnTakeDamage;
public static Action<float> OnDamage;
public static Action<float> OnHeal;
[Header("Stamina Parameters")]
[SerializeField] private float maxStamina = 100f;
[SerializeField] private float staminaUseMultiplier = 6f;
[SerializeField] private float timeBeforeStaminaRegen = 4.5f;
[SerializeField] private float staminaValueIncrement = 1.5f;
[SerializeField] private float staminaTimeIncrement = 0.1f;
[SerializeField] private float currentStamina;
private Coroutine regeneratingStamina;
public static Action<float> OnStaminaChange;
[Header("Headbob Parameters")]
private float walkBobSpeed = 14.65f;
private float walkBobAmount = 0.03f;
private float sprintBobSpeed = 20f;
private float sprintBobAmount = 0.06f;
private float crouchBobSpeed = 9.75f;
private float crouchBobAmount = 0.04f;
private float defaultYPos = 0;
private float timer;
[Header("Footstep Parameters")]
[SerializeField] private float baseStepSpeed = 0.5f;
[SerializeField] private float crouchStepMultiplier = 1.4f;
[SerializeField] private float sprintStepMultiplier = 0.6f;
[SerializeField] private AudioSource footstepAudioSource = default;
[SerializeField] private AudioClip[] woodClips = default;
[SerializeField] private AudioClip[] stoneClips = default;
[SerializeField] private AudioClip[] grassClips = default;
private float footstepTimer = 0;
private float GetCurrentOffset => isCrouching ? baseStepSpeed * crouchStepMultiplier : isSprinting ? baseStepSpeed * sprintStepMultiplier : baseStepSpeed; // ogarnij to i zaimplementuj do całego kodu
[Header("Sliding Parameters")]
private Vector3 hitPointNormal;
private bool IsSliding
{
get //dodaj to że po zakończeniu slide'a dalej cie wypycha w kierunek w który wcześniej zjeżdżałeś, abyś nie kończył na końcu.
{
if (_controller.isGrounded && Physics.Raycast(transform.position, Vector3.down, out RaycastHit slopeHit, 1.8f))
{
hitPointNormal = slopeHit.normal;
return Vector3.Angle(hitPointNormal, Vector3.up) > _controller.slopeLimit;
}
else
{
return false;
}
}
} // dodaj dźwięk ślizgania się
[Header("Interaction")]
[SerializeField] private Vector3 interactionRayPoint = default;
[SerializeField] private float interactionDistance = default;
[SerializeField] private LayerMask interactionLayer = default;
private Interactable currentInteractable;
private void OnEnable()
{
OnTakeDamage = ApplyDamage;
}
private void OnDisable()
{
OnTakeDamage -= ApplyDamage;
}
void Awake()
{
_controller = GetComponent<CharacterController>();
playerCamera = GetComponentInChildren<Camera>();
defaultYPos = playerCamera.transform.localPosition.y;
currentHealth = maxHealth;
currentStamina = maxStamina;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
Screen.SetResolution(1920, 1080, true);
}
void Update() // ogarnij machanie mieczem i niszczenie skrzynek
{
_speed = 3f;
isSprinting = false;
if (canLook)
MouseLook();
if (canSprint)
Sprinting();
if (canJump)
Jumping();
if (canCrouch)
Crouching();
if (canUseHeadbob)
HandleHeadbob();
if (useFootsteps)
HandleFootsteps();
if (canInteract)
{
HandleInteractionCheck();
HandleInteractionInput();
}
if (UseStamina)
HandleStamina();
if (Input.GetKeyDown(KeyCode.Tab) && cursorShow)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
cursorShow = false;
canLook = true;
}
else if(Input.GetKeyDown(KeyCode.Tab) && !cursorShow)
{
Cursor.lockState = CursorLockMode.Confined;
Cursor.visible = true;
cursorShow = true;
canLook = false;
}
if (canMove)
ApplyFinalMovements();
if (WillSlideOnSlopes && IsSliding)
{
moveDirection = new Vector3(hitPointNormal.x, -hitPointNormal.y, hitPointNormal.z) * _slideSpeed;
SlidedLastFrame = true;
}
_controller.Move(moveDirection * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
private void ApplyFinalMovements()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
currentInput = new Vector2(_speed * verticalInput, _speed * horizontalInput);
#region CheckingInputsAnims
if (verticalInput>0)
isWalking = true;
else isWalking = false;
if (verticalInput<0)
isWalkingBackwards = true;
else isWalkingBackwards = false;
#endregion
float moveDirectionY = moveDirection.y;
moveDirection = transform.transform.TransformDirection(Vector3.forward * currentInput.x) (transform.TransformDirection(Vector3.right) * currentInput.y);
velocityZ = moveDirection.y;
velocityX = moveDirection.x;
moveDirection.y = moveDirectionY;
}
private void MouseLook()
{
float mouseX = Input.GetAxis("Mouse X") * _sensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * _sensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90, 90);
playerCamera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
transform.Rotate(Vector3.up * mouseX);
}
private void Sprinting()
{
if (Input.GetKey(sprintKey) && Input.GetAxis("Vertical") > 0 && !IsSliding && !isCrouching && canSprint)
{
isSprinting = true;
_speed = _sprintSpeed;
}
}
private void Jumping() // dodaj dźwięk spadania przy wysokich prędkościach, którego głośność się będzie zwiększała
{
startJump = false;
if (SlidedLastFrame && !IsSliding)
{
moveDirection.y = -1f;
SlidedLastFrame = false;
}
_fallSpeed = moveDirection.y;
if (midAir)
midAirLastFrame = true;
if (_controller.isGrounded)
midAir = false;
if (_controller.isGrounded && Input.GetKeyDown(jumpKey) && !IsSliding && canJump)
{
startJump = true;
playerAudioSource.PlayOneShot(jumpClips[UnityEngine.Random.Range(0, landClips.Length - 1)]);
moveDirection.y = _jumpHeight;
midAir = true;
}
else if (_controller.isGrounded)
{
if(midAirLastFrame)
endJump = true;
if (midAirLastFrame && !IsSliding && _fallSpeed < -3.5f) // ogarnijjj toooo
{
midAirLastFrame = false;
_landStartPos = playerCamera.transform.localPosition.y;
if (_fallSpeed <= -3.5f)
{
playerAudioSource.PlayOneShot(landClips[UnityEngine.Random.Range(0, landClips.Length - 1)]);
if (_fallSpeed <= -8f) _fallDamage = -moveDirection.y * 1.7f;
if (_fallSpeed <= -9f) _fallDamage *= 2f;
if (_fallSpeed <= -10f) _fallDamage *= 1.5f;
if (_fallSpeed <= -11f) _fallDamage *= 1.5f;
if (_fallSpeed <= -8f) {
Player.OnTakeDamage(_fallDamage);
Debug.Log("Took fallDamage = " _fallDamage "with fallspeed = " _fallSpeed);
}
_fallDamage = 0f;
}
}
moveDirection.y = -1f;
}
else
{
midAir = true;
moveDirection.y -= _gravity * Time.deltaTime;
if (Physics.Raycast(playerCamera.transform.position, Vector3.up, 0.5f) && moveDirection.y > 0f)
{
moveDirection.y = 0f;
}
}
}
private void Crouching()
{
if (Input.GetKeyDown(crouchKeyHold) && !duringCrouchAnim && _controller.isGrounded)
{
StartCoroutine(CrouchStand());
}
else if (isCrouching)
{
_speed = _crouchSpeed;
}
}
private void HandleHeadbob()
{
if (!_controller.isGrounded)
{
return;
}
if (Mathf.Abs(moveDirection.x) > 0.1f || Mathf.Abs(moveDirection.z) > 0.1f)
{
timer = Time.deltaTime * (isCrouching ? crouchBobSpeed : isSprinting ? sprintBobSpeed : walkBobSpeed);
playerCamera.transform.localPosition = new Vector3(
playerCamera.transform.localPosition.x,
defaultYPos Mathf.Sin(timer) * (isCrouching ? crouchBobAmount : isSprinting ? sprintBobAmount : walkBobAmount),
playerCamera.transform.localPosition.z);
}
}
private void HandleStamina()
{
if (isSprinting && currentInput != Vector2.zero)
{
if (regeneratingStamina != null)
{
StopCoroutine(regeneratingStamina);
regeneratingStamina = null;
}
currentStamina -= staminaUseMultiplier * Time.deltaTime;
if (currentStamina < 0)
{
currentStamina = 0;
}
OnStaminaChange?.Invoke(currentStamina);
if (currentStamina <= 0)
{
canSprint = false;
}
}
if (!isSprinting && currentStamina < maxStamina && regeneratingStamina == null)
{
regeneratingStamina = StartCoroutine(RegenerateStamina());
}
}
private void HandleFootsteps()
{
if (!_controller.isGrounded) return;
if (currentInput == Vector2.zero) return;
footstepTimer -= Time.deltaTime;
if (footstepTimer <= 0)
{
if (Physics.Raycast(playerCamera.transform.position, Vector3.down, out RaycastHit hit, 3))
{
switch (hit.collider.tag)
{
case "Footsteps/STONE":
footstepAudioSource.PlayOneShot(stoneClips[UnityEngine.Random.Range(0, stoneClips.Length - 1)]);
break;
default:
footstepAudioSource.PlayOneShot(stoneClips[UnityEngine.Random.Range(0, stoneClips.Length - 1)]);
break;
}
}
footstepTimer = GetCurrentOffset;
}
}
private void ApplyDamage(float dmg) //ogarnij te float
{
currentHealth -= dmg;
playerAudioSource.PlayOneShot(hurtClips[UnityEngine.Random.Range(0, landClips.Length - 1)]);
OnDamage?.Invoke(currentHealth);
if (currentHealth <= 0)
{
KillPlayer();
}
else if (regeneratingHealth != null)
{
StopCoroutine(regeneratingHealth);
}
regeneratingHealth = StartCoroutine(RegenerateHealth());
}
private void KillPlayer()
{
currentHealth = 0;
if (regeneratingHealth != null)
{
StopCoroutine(regeneratingHealth);
Debug.Log("DEAD");
}
}
private void HandleInteractionCheck()
{
if (Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance))
{
if (hit.collider.gameObject.layer == 8 && (currentInteractable == null || hit.collider.gameObject.GetInstanceID() != currentInteractable.GetInstanceID()))
{
hit.collider.TryGetComponent(out currentInteractable);
if (currentInteractable)
{
currentInteractable.OnFocus();
}
}
else if (currentInteractable)
{
currentInteractable.OnLoseFocus();
currentInteractable = null;
}
}
else if (currentInteractable)
{
currentInteractable.OnLoseFocus();
currentInteractable = null;
}
}
private void HandleInteractionInput()
{
if (Input.GetKeyDown(interactKey) && currentInteractable != null && Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance, interactionLayer))
{
currentInteractable.OnInteract();
}
}
private IEnumerator CrouchStand()
{
if (isCrouching && Physics.Raycast(playerCamera.transform.position, Vector3.up, 0.5f))
{
yield break;
}
duringCrouchAnim = true;
float timeElapsed = 0;
float targetHeight = isCrouching ? standingHeight : crouchHeight;
float currentHeight = _controller.height;
Vector3 targetCenter = isCrouching ? standingCenter : crouchingCenter;
Vector3 currentCenter = _controller.center;
while (timeElapsed < timeToCrouch)
{
_controller.height = Mathf.Lerp(currentHeight, targetHeight, timeElapsed / timeToCrouch);
_controller.center = Vector3.Lerp(currentCenter, targetCenter, timeElapsed / timeToCrouch);
timeElapsed = Time.deltaTime;
yield return null;
}
_controller.height = targetHeight;
_controller.center = targetCenter;
isCrouching = !isCrouching;
duringCrouchAnim = false;
}
private IEnumerator RegenerateHealth()
{
yield return new WaitForSeconds(timeBeforeRegenStarts);
WaitForSeconds timeToWait = new WaitForSeconds(healthTimeIncrement);
while (currentHealth < maxHealth)
{
currentHealth = healthValueIncrement;
if (currentHealth > maxHealth)
{
currentHealth = maxHealth;
}
OnHeal?.Invoke(currentHealth);
yield return timeToWait;
}
regeneratingHealth = null;
}
private IEnumerator RegenerateStamina()
{
yield return new WaitForSeconds(timeBeforeStaminaRegen);
WaitForSeconds timeToWait = new WaitForSeconds(staminaTimeIncrement);
while (currentStamina < maxStamina)
{
if (currentStamina > 0)
{
canSprint = true;
}
currentStamina = staminaValueIncrement;
if (currentStamina > maxStamina)
{
currentStamina = maxStamina;
}
OnStaminaChange?.Invoke(currentStamina);
yield return timeToWait;
}
regeneratingStamina = null;
}
}
CodePudding user response:
First consider using an enum rather than multiple if...else statements for your current state.
Then, after reviewing the full code, i'm pretty sure the issue come from the fact that your not correctly assigning your values.
Try reverting player.velocityZ = velocityZ;
to velocityZ = player.velocityZ;
that should do the trick.
That might be it if i understand correctly.
public enum State
{
isWalking,
isWalkingBackwards,
isSprinting,
startJump,
midAir,
endJump,
isCrouching,
}
public class animationStateController : MonoBehaviour
{
Player player;
Animator animator;
private float velocityZ;
private float velocityX;
State lastAnim;
State currentAnim;
private void Start()
{
player = FindObjectOfType(typeof(Player)) as Player;
animator = GetComponent<Animator>();
}
void Update()
{
velocityZ = player.velocityZ;
velocityX = player.velocityX;
animator.SetFloat("VelocityZ", velocityZ, 0.1f, Time.deltaTime);
animator.SetFloat("VelocityX", velocityX, 0.1f, Time.deltaTime);
if (lastAnim != currentAnim)
{
animator.SetBool(currentAnim.ToString(), true)
animator.SetBool(lastAnim.ToString(), false);
}
lastAnim = currentAnim;
}
private void ApplyFinalMovements()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
currentInput = new Vector2(_speed * verticalInput, _speed * horizontalInput);
#region CheckingInputsAnims
if (verticalInput > 0)
currentAnim = State.isWalking;
else if (verticalInput < 0)
currentAnim = State.isWalkingBackwards;
#endregion
float moveDirectionY = moveDirection.y;
moveDirection = transform.transform.TransformDirection(Vector3.forward * currentInput.x) (transform.TransformDirection(Vector3.right) * currentInput.y);
velocityZ = moveDirection.y;
velocityX = moveDirection.x;
}
}