- W/S/A/D 이동 구현
- 마우스 카메라 회전 구현
- Space 1단 점프 구현
준비
1. Player
Player 빈 오브젝트를 생성하고, 자식 오브젝트로 CameraContainer를 생성
CameraContainer 안에 Main Camera를 넣음
Main Camera 설정
Player 오브젝트에 Capsule Collider, Rigidbody 추가
2. Input System
* 앞 부분은 Input System(2D)와 동일 *
https://kkln2486.tistory.com/126
다음과 같이 Action 설정
- Send Messages : OnMove와 OnLook 함수를 현재 오브젝트에 있는 스크립트에서 찾음
- Broadcast Messages : OnMove와 OnLook 함수를 현재, 자식 오브젝트에 있는 스크립트에서 찾음
- Invoke Unity Events : Button과 같이 함수가 있는 스크립트를 가진 오브젝트를 추가해서 사용
3. 스크립트 작성
PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
[Header("Movement")]
public float MoveSpeed;
public float JumpForce;
public LayerMask GroundLayerMask;
private Vector2 _curMovementInput;
[Header("Look")]
public Transform CameraContainer;
public float MinXLook;
public float MaxXLook;
public float LookSensitivity;
private float _camCurXRot;
private Vector2 _mouseDelta;
[HideInInspector] public bool CanLook = true;
private Rigidbody _rigidbody;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody>();
}
void Start()
{
Cursor.lockState = CursorLockMode.Locked; // 게임 시, 마우스 없앰
}
private void FixedUpdate()
{
Move();
}
private void LateUpdate()
{
if (CanLook)
{
CameraLook();
}
}
// 이동
public void OnMoveInput(InputAction.CallbackContext context)
{
if (context.phase == InputActionPhase.Performed)
{
_curMovementInput = context.ReadValue<Vector2>();
}
else if (context.phase == InputActionPhase.Canceled)
{
_curMovementInput = Vector2.zero;
}
}
private void Move()
{
Vector3 dir = transform.forward * _curMovementInput.y + transform.right * _curMovementInput.x;
dir *= MoveSpeed;
dir.y = _rigidbody.velocity.y;
_rigidbody.velocity = dir;
}
// 카메라 조절
public void OnLookInput(InputAction.CallbackContext context)
{
_mouseDelta = context.ReadValue<Vector2>();
}
void CameraLook()
{
_camCurXRot += _mouseDelta.y * LookSensitivity;
_camCurXRot = Mathf.Clamp(_camCurXRot, MinXLook, MaxXLook);
CameraContainer.localEulerAngles = new Vector3(-_camCurXRot, 0, 0);
transform.eulerAngles += new Vector3(0, _mouseDelta.x * LookSensitivity, 0);
}
// 점프
public void OnJumpInput(InputAction.CallbackContext context)
{
if (context.phase == InputActionPhase.Started)
{
if (IsGrounded())
_rigidbody.AddForce(Vector2.up * JumpForce, ForceMode.Impulse);
}
}
private bool IsGrounded()
{
Ray[] rays = new Ray[4]
{
new Ray(transform.position + (transform.forward * 0.2f) + (Vector3.up * 0.01f), Vector3.down),
new Ray(transform.position + (-transform.forward * 0.2f) + (Vector3.up * 0.01f), Vector3.down),
new Ray(transform.position + (transform.right * 0.2f) + (Vector3.up * 0.01f), Vector3.down),
new Ray(transform.position + (-transform.right * 0.2f) + (Vector3.up * 0.01f), Vector3.down),
};
for (int i = 0; i < rays.Length; i++)
{
if (Physics.Raycast(rays[i], 0.1f, GroundLayerMask))
{
return true;
}
}
return false;
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawRay(transform.position + (transform.forward * 0.2f), Vector3.down);
Gizmos.DrawRay(transform.position + (-transform.forward * 0.2f), Vector3.down);
Gizmos.DrawRay(transform.position + (transform.right * 0.2f), Vector3.down);
Gizmos.DrawRay(transform.position + (-transform.right * 0.2f), Vector3.down);
}
}
4. 기타 설정
Player 오브젝트에 스크립트, Player Input 추가하고 다음과 같이 설정
Player를 누르고 Button 설정과 유사하게 함수를 등록
'유니티' 카테고리의 다른 글
아이템 정보 만들기 (ScriptableObject) (0) | 2023.12.14 |
---|---|
인벤토리 스크롤 설정 (Scroll View, Grid Layout Group) (0) | 2023.12.14 |
Rect Transform (앵커, 피봇) (0) | 2023.12.13 |
애니메이션 이벤트 (0) | 2023.12.13 |
GameObject 검색 (0) | 2023.12.11 |