using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
[RequireComponent (typeof(CharacterController), typeof(Animator), typeof(AudioSource))] // 컴포넌트 생성 스크립트
public class CharacterMove : MonoBehaviour
{
private CharacterController controller;
private Animator animator;
public AudioClip walkingSound;
private AudioSource audioSource;
[SerializeField]
float gravity = -9.81f; // 중력의 크기
float yVelocity = 0f; // 캐릭터의 현재 y축 속도
[SerializeField]
public float walkSpeed = 2f;
[SerializeField]
public float runSpeed = 5f;
[SerializeField]
public float rotationSpeed = 5f; // 회전 속도를 조절하는 변수
[SerializeField]
public float walkSoundInterval = 0.5f;
[SerializeField]
public float runSoundInterval = 0.3f;
float hAxis;
float vAxis;
float nextStepTime = 0f;
Vector3 moveVec;
public Transform cameraTransform;
// Start is called before the first frame update
void Start()
{
controller = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
audioSource = GetComponent<AudioSource>();
if (cameraTransform == null)
{
cameraTransform = Camera.main.transform;
}
nextStepTime = Time.time; // 첫 걸음소리 타이밍
}
// Update is called once per frame
void Update()
{
hAxis = Input.GetAxisRaw("Horizontal");
vAxis = Input.GetAxisRaw("Vertical");
Vector3 inputDirection = new Vector3(hAxis, 0f, vAxis).normalized;
Vector3 CameraForward = cameraTransform.forward;
Vector3 CameraRight = cameraTransform.right;
CameraForward.y = 0f;
CameraRight.y = 0f;
Vector3 moveDirection = CameraForward * inputDirection.z + CameraRight * inputDirection.x;
bool isWalking = Input.GetKey(KeyCode.LeftShift);
float movementState = 0f;
float speed = 0f;
// 애니메이터 상태 설정
if (moveDirection != Vector3.zero) {
movementState = isWalking ? 0.5f : 1f;
speed = isWalking ? walkSpeed : runSpeed;
// 목표 회전 값 계산
Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
// 현재 회전 값과 목표 회전 값을 선형 보간하여 부드럽게 회전
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
controller.Move(moveDirection * speed * Time.deltaTime);
float soundInterval = isWalking ? walkSoundInterval : runSoundInterval;
if ( Time.time >= nextStepTime)
{
audioSource.PlayOneShot(walkingSound);
nextStepTime = Time.time + soundInterval;
}
}
animator.SetFloat("MovementState", movementState);
if (controller.isGrounded)
{
yVelocity = 0f;
}
else
{
yVelocity += gravity * Time.deltaTime;
}
Vector3 verticalVelocity = new Vector3(0, yVelocity, 0);
controller.Move(verticalVelocity * Time.deltaTime);
}
}
AudioSource 컴포넌트를 추가하여 걸음소리를 재생할 준비를 한다.
walkingSound를 클립으로 설정한다.
walkSoundInterval 변수와 runSoundInterval 변수를 추가해 걸음 소리 간격을 설정한다.
nextStepTime변수를 추가해 다음 걸음 소리가 재생될 시간을 추적한다.
Time.time >= NextStepTime을 통해 현재 시간이 다음 걸음 소리 재생 시간에 도달했는지 확인한다.
걸음 소리를 audioSource.PlayOneshot(walkingSound)로 재생하고, 다음 걸음 소리 시간을 현재 시간에 소리 간격을 더한 값으로 설정한다.
걷기와 달리기에 따라 soundInterval을 다르게 설정하여, 걷는 소리는 느리게, 달리기 소리는 빠르게 재생하도록 한다.
'게임개발 > 드림랜드' 카테고리의 다른 글
2024.09.04 npc 상호작용 (1) | 2024.09.04 |
---|---|
2024.09.03 블렌드 트리를 활용한 걷기 애니메이션 (0) | 2024.09.03 |
2024.09.02 NPC 애니메이션, 카메라 스크립트와 플레이어 스크립트 그리고 커서 (0) | 2024.09.02 |
2024.08.27 NPC 만들기 (0) | 2024.08.27 |
2024.08.23 드림랜드 개발 과정(2) (0) | 2024.08.23 |