유니티 new input system 뉴 인풋 시스템 이동,애니메이션 구현
walk 걷기 , run 달리기 , 애니메이션 구현
- 아래 코드는 가만히 있는 상태에서(방향키를 안누르고, 움직이지 않을때) 왼쪽 쉬프트를 눌러도 run 애니메이션이 동작하지 않음. 그러나 1. 왼쪽 쉬프트를 먼저 누르고 이동하기위해 2. 방향키를 입력하면 Run 애니메이션이 동작하지 않음.
이동감지코드 때문에 isRunning이 false로 되기 때문.
if( movementDirection.magnitude > 0 )
{
speed = runSpeed;
isRunning = true;
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
PlayerControlls playerControlls;
CharacterController characterController;
Animator animator;
[SerializeField] float walkSpeed = 3f;
[SerializeField] float runSpeed;
[SerializeField] Transform aim;
[SerializeField] LayerMask aimLayerMask;
float speed;
bool isRunning = false;
Vector3 lookingDirection;
float verticalVelocity;
Vector3 movementDirection;
Vector2 moveInput;
Vector2 aimInput;
private void Awake()
{
playerControlls = new PlayerControlls();
playerControlls.Character.Movement.performed += context => moveInput = context.ReadValue<Vector2>();
playerControlls.Character.Movement.canceled += context => moveInput = Vector2.zero;
playerControlls.Character.Aim.performed += context => aimInput = context.ReadValue<Vector2>();
playerControlls.Character.Aim.canceled += context => aimInput = Vector2.zero;
playerControlls.Character.Run.performed += context =>
{
if( movementDirection.magnitude > 0 )
{
speed = runSpeed;
isRunning = true;
}
};
playerControlls.Character.Run.canceled += context =>
{
speed = walkSpeed;
isRunning = false;
};
}
private void Start()
{
characterController = GetComponent<CharacterController>();
animator = GetComponentInChildren<Animator>();
isRunning = false;
speed = walkSpeed;
}
private void Update()
{
ApplyMovement();
AimTowardMouse();
AnimatorControllers();
}
private void AnimatorControllers()
{
float xVelocty = Vector3.Dot(movementDirection.normalized, transform.right);
float zVelocty = Vector3.Dot(movementDirection.normalized, transform.forward);
animator.SetFloat("xVelocity", xVelocty, 0.1f, Time.deltaTime);
animator.SetFloat("zVelocity", zVelocty, 0.1f, Time.deltaTime);
animator.SetBool("isRunning", isRunning);
}
private void AimTowardMouse()
{
Ray ray = Camera.main.ScreenPointToRay(aimInput);
if(Physics.Raycast(ray, out var hitInfo, Mathf.Infinity, aimLayerMask))
{
lookingDirection = hitInfo.point - transform.position;
lookingDirection.y = 0;
lookingDirection.Normalize();
transform.forward = lookingDirection;
aim.position = new Vector3(hitInfo.point.x, transform.position.y, hitInfo.point.z);
}
}
private void ApplyMovement()
{
movementDirection = new Vector3(moveInput.x, 0, moveInput.y);
ApplyGravity();
if (movementDirection.magnitude > 0)
{
characterController.Move(movementDirection * speed * Time.deltaTime);
}
}
private void ApplyGravity()
{
if(characterController.isGrounded == false)
{
verticalVelocity -= 9.81f * Time.deltaTime;
movementDirection.y = verticalVelocity;
}
else
{
verticalVelocity = -0.5f;
}
}
private void OnEnable()
{
playerControlls.Enable();
}
private void OnDisable()
{
playerControlls.Disable();
}
}
해결방법
- Run 애니메이션 bool값을 이동이 있을때에만 true로 조절한다.
- Awake에서 Run에 if문은 빼도 된다.
private void AnimatorControllers()
{
float xVelocty = Vector3.Dot(movementDirection.normalized, transform.right);
float zVelocty = Vector3.Dot(movementDirection.normalized, transform.forward);
animator.SetFloat("xVelocity", xVelocty, 0.1f, Time.deltaTime);
animator.SetFloat("zVelocity", zVelocty, 0.1f, Time.deltaTime);
bool playRunAnimation = isRunning && movementDirection.magnitude > 0;
animator.SetBool("isRunning", playRunAnimation);
}
- 수정한 스크립트
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
PlayerControlls playerControlls;
CharacterController characterController;
Animator animator;
[SerializeField] float walkSpeed = 3f;
[SerializeField] float runSpeed;
[SerializeField] Transform aim;
[SerializeField] LayerMask aimLayerMask;
float speed;
bool isRunning = false;
Vector3 lookingDirection;
float verticalVelocity;
Vector3 movementDirection;
Vector2 moveInput;
Vector2 aimInput;
private void Awake()
{
AssignInputEvents();
}
private void AssignInputEvents()
{
playerControlls = new PlayerControlls();
playerControlls.Character.Movement.performed += context => moveInput = context.ReadValue<Vector2>();
playerControlls.Character.Movement.canceled += context => moveInput = Vector2.zero;
playerControlls.Character.Aim.performed += context => aimInput = context.ReadValue<Vector2>();
playerControlls.Character.Aim.canceled += context => aimInput = Vector2.zero;
playerControlls.Character.Run.performed += context =>
{
speed = runSpeed;
isRunning = true;
};
playerControlls.Character.Run.canceled += context =>
{
speed = walkSpeed;
isRunning = false;
};
}
private void Start()
{
characterController = GetComponent<CharacterController>();
animator = GetComponentInChildren<Animator>();
isRunning = false;
speed = walkSpeed;
}
private void Update()
{
ApplyMovement();
AimTowardMouse();
AnimatorControllers();
}
private void AnimatorControllers()
{
float xVelocty = Vector3.Dot(movementDirection.normalized, transform.right);
float zVelocty = Vector3.Dot(movementDirection.normalized, transform.forward);
animator.SetFloat("xVelocity", xVelocty, 0.1f, Time.deltaTime);
animator.SetFloat("zVelocity", zVelocty, 0.1f, Time.deltaTime);
bool playRunAnimation = isRunning && movementDirection.magnitude > 0;
animator.SetBool("isRunning", playRunAnimation);
}
private void AimTowardMouse()
{
Ray ray = Camera.main.ScreenPointToRay(aimInput);
if(Physics.Raycast(ray, out var hitInfo, Mathf.Infinity, aimLayerMask))
{
lookingDirection = hitInfo.point - transform.position;
lookingDirection.y = 0;
lookingDirection.Normalize();
transform.forward = lookingDirection;
aim.position = new Vector3(hitInfo.point.x, transform.position.y, hitInfo.point.z);
}
}
private void ApplyMovement()
{
movementDirection = new Vector3(moveInput.x, 0, moveInput.y);
ApplyGravity();
if (movementDirection.magnitude > 0)
{
characterController.Move(movementDirection * speed * Time.deltaTime);
}
}
private void ApplyGravity()
{
if(characterController.isGrounded == false)
{
verticalVelocity -= 9.81f * Time.deltaTime;
movementDirection.y = verticalVelocity;
}
else
{
verticalVelocity = -0.5f;
}
}
private void OnEnable()
{
playerControlls.Enable();
}
private void OnDisable()
{
playerControlls.Disable();
}
}
유니티 탑다운 게임 개발 Version.1 (1) | 2024.10.10 |
---|---|
유니티 애니메이터 레이어(Animator layer) 껐다 키기 (1) | 2024.10.08 |
유니티 Chain Ik, 체인 IK, 애니메이션 리깅 (0) | 2024.10.04 |
유니티 랜덤으로 리스트안의 값을 섞기 (0) | 2024.10.02 |
유니티 자동 큐브타워 만들기 테스트중_V1 (1) | 2024.10.02 |