NPC Idle 애니메이션과 Hello 애니메이션을 완성하고 fbx모델에 적용한 다음 캐릭터 프리팹스를 만들었다.
서치와 챗 gpt의 도움을 통해 Main Camera 코드와 CharacterMove 코드를 손봤다.
MainCameraAction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainCamera_Action : MonoBehaviour
{
public Transform target; // 따라갈 캐릭터
public float distance = 5.0f; // 캐릭터와의 거리
public float height = 2.0f; // 캐릭터 위의 높이
public float horizontalOffset = 1.0f; // 캐릭터 정면에서의 수평 오프셋
public float rotationSpeed = 5.0f; // 마우스 회전 속도
public float zoomSpeed = 2.0f; // 줌 속도
public LayerMask collisionLayers; // 카메라 충돌을 처리할 레이어
private float currentX = 0.0f;
private float currentY = 15.0f; // 살짝 아래를 바라보게 하기 위해 초기값을 설정
private float currentDistance;
private CursorManager cursorManager;
void Start()
{
currentDistance = distance; // 초기 거리 설정
cursorManager = GetComponent<CursorManager>();
if ( cursorManager != null)
{
cursorManager.LockCursor();
}
}
void LateUpdate()
{
HandleCameraRotation();
HandleCameraZoom();
HandleCameraPosition();
}
void HandleCameraRotation()
{
// 마우스 입력 받기 (드래그 중이 아닐 때도)
float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");
// X축 회전 (좌우)
currentX += mouseX * rotationSpeed;
// Y축 회전 (상하)
currentY -= mouseY * rotationSpeed;
currentY = Mathf.Clamp(currentY, 5, 60); // 상하 회전 각도 제한
}
void HandleCameraZoom()
{
// 줌 인/아웃 처리
float scroll = Input.GetAxis("Mouse ScrollWheel");
currentDistance = Mathf.Clamp(currentDistance - scroll * zoomSpeed, 2.0f, 10.0f);
}
void HandleCameraPosition()
{
// 카메라 회전 계산
Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
// 카메라 위치 계산
Vector3 offset = new Vector3(horizontalOffset, height, -currentDistance);
Vector3 desiredPosition = target.position + rotation * offset;
// 충돌 처리: 카메라가 벽이나 장애물에 겹치지 않도록 처리
RaycastHit hit;
if (Physics.Linecast(target.position + Vector3.up * height, desiredPosition, out hit, collisionLayers))
{
desiredPosition = hit.point; // 충돌한 지점으로 카메라 위치 조정
}
transform.position = desiredPosition;
// 캐릭터를 바라보도록 카메라 설정
transform.LookAt(target.position + Vector3.up * height);
}
}
Character Move
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
[RequireComponent(typeof(CharacterController), typeof(Animator))]
public class CharacterMove : MonoBehaviour
{
private CharacterController controller;
private Animator animator;
[SerializeField]
float gravity = -9.81f; // 중력의 크기
float yVelocity = 0f; // 캐릭터의 현재 y축 속도
[SerializeField]
public float moveSpeed;
[SerializeField]
public float rotationSpeed = 5f; // 회전 속도를 조절하는 변수
float hAxis;
float vAxis;
Vector3 moveVec;
public Transform cameraTransform;
// Start is called before the first frame update
void Start()
{
controller = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
if (cameraTransform == null)
{
cameraTransform = Camera.main.transform;
}
}
// 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;
// 애니메이터 상태 설정
animator.SetBool("IsRunning", moveDirection != Vector3.zero);
// 캐릭터 회전
if (moveDirection != Vector3.zero)
{
// 목표 회전 값 계산
Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
// 현재 회전 값과 목표 회전 값을 선형 보간하여 부드럽게 회전
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
controller.Move(moveDirection * moveSpeed * Time.deltaTime);
}
if(controller.isGrounded)
{
yVelocity = 0f;
}
else
{
yVelocity += gravity * Time.deltaTime;
}
}
}
이를 통하여 카메라 방향에 따라 캐릭터의 입력방식이 할당되고, 커서를 움직이면 카메라가 회전한다.
캐릭터 컨트롤러를 통한 중력 작용도 스크립트에 적용했다.
테스트 화면
'게임개발 > 드림랜드' 카테고리의 다른 글
2024.09.03 플레이어 걷는 소리 구현 (0) | 2024.09.03 |
---|---|
2024.09.03 블렌드 트리를 활용한 걷기 애니메이션 (0) | 2024.09.03 |
2024.08.27 NPC 만들기 (0) | 2024.08.27 |
2024.08.23 드림랜드 개발 과정(2) (0) | 2024.08.23 |
2024.08.22 드림랜드 개발과정 (1) - 시작 (0) | 2024.08.22 |