Client/Unity

Unity) 3D - 캐릭터 이동

Juzdalua 2024. 4. 26. 01:10

이동거리 계산)

캐릭터가 이동한 위치는 (방향 * 거리)이다.

다시 풀어쓰면, 방향 * 속력 * 시간이다.

코드로 풀어보면, nomalized Vector * speed * Time.deltaTime이다.

 

오브젝트 설정)

Character Controller는 Collider를 갖고 있기 때문에 따로 Collider가 필요하지 않다.

 

Slope Limit: 올라갈 수 있는 경사의 한계 각도

Step Offset: 오를 수 있는 최대 높이 (계단의 경우 인접한 계단의 높이)

Center: 캡슐 충돌 범위의 중심점

Radius: 캡슐 충돌 범위의 반지름

Hight: 캡슐 충돌 범위의 높이

 

이미지 변경)

3D 캡슐 플레이어의 경우, 이미지 변경을 위해서는 Material을 생성하고 이미지나 색상 변경을 한 후 해당 Material을 Player의 Mesh Renderer Material로 주입한다.

 

 

캡슐 오브젝트 생성 및 색상 변경이 완료되면 이동에 관한 스크립트를 추가한다.

 

기본적인 캐릭터 이동)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement3D : MonoBehaviour
{
    float moveSpeed = 5.0f;
    Vector3 moveDirection;

    CharacterController characterController;

    // Start is called before the first frame update
    void Start()
    {
        characterController = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
    }

    public void MoveTo(Vector3 direction){
        moveDirection = direction;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Movement3D movement3D;

    // Start is called before the first frame update
    void Start()
    {
        movement3D = GetComponent<Movement3D>();
    }

    // Update is called once per frame
    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float z = Input.GetAxisRaw("Vertical");

        movement3D.MoveTo(new Vector3(x, 0, z));
    }
}

 

중력을 계산한 캐릭터 이동)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement3D : MonoBehaviour
{
    float moveSpeed = 5.0f;
    Vector3 moveDirection;
    float gravity = -9.81f;

    CharacterController characterController;

    // Start is called before the first frame update
    void Start()
    {
        characterController = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        if(!characterController.isGrounded){ // 발이 충돌하면 true, 공중에 떠있으면 false
            moveDirection.y += gravity * Time.deltaTime; // 아래로 떨어지는 중력 적용
        }
        characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
    }

    public void MoveTo(Vector3 direction){
        // y축은 중력을 적용한다.
        moveDirection = new Vector3(direction.x, moveDirection.y, direction.z);
    }
}

 

 

점프하기)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement3D : MonoBehaviour
{
    float moveSpeed = 5.0f;
    Vector3 moveDirection;
    float gravity = -9.81f;
    float jumpForce = 3.0f;

    CharacterController characterController;

    // Start is called before the first frame update
    void Start()
    {
        characterController = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        if(!characterController.isGrounded){ // 발이 충돌하면 true, 공중에 떠있으면 false
            moveDirection.y += gravity * Time.deltaTime; // 아래로 떨어지는 중력 적용
        }
        characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
    }

    public void MoveTo(Vector3 direction){
        // y축은 중력을 적용한다.
        moveDirection = new Vector3(direction.x, moveDirection.y, direction.z);
    }

    public void JumpTo(){
        if(characterController.isGrounded){
            moveDirection.y = jumpForce;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Movement3D movement3D;
    KeyCode jumpKeyCode = KeyCode.Space;

    // Start is called before the first frame update
    void Start()
    {
        movement3D = GetComponent<Movement3D>();
    }

    // Update is called once per frame
    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float z = Input.GetAxisRaw("Vertical");

        movement3D.MoveTo(new Vector3(x, 0, z));

        if(Input.GetKeyDown(jumpKeyCode)){
            movement3D.JumpTo();
        }
    }
}

 

1인칭 카메라)

카메라를 플레이어의 자식으로 설정.

 

카메라 설정

캐릭터의 눈높이로 이동 후, 카메라컨트롤러 스크립트 주입.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    float rotateSpeedX = 3;
    float rotateSpeedY = 5;
    float limitMinX = -80;
    float limitMaxX = 50;
    float eulerAngleX;
    float eulerAngleY;

    public void RotateTo(float mouseX, float mouseY)
    {
        /*
        마우스를 좌우로 돌리면 카메라의 Y축이 회전되어야한다. 
        */
        eulerAngleY += mouseX * rotateSpeedX;
        eulerAngleX -= mouseY * rotateSpeedY;

        // x축 회전일 경우, 제한각도가 존재한다.
        eulerAngleX = ClampAngle(eulerAngleX, limitMinX, limitMaxX);

        // 카메라 회전 함수
        transform.rotation = Quaternion.Euler(eulerAngleX, eulerAngleY, 0);
    }

    float ClampAngle(float angle, float min, float max){
        if(angle < -360){
            angle += 360;
        } else if(angle > 360){
            angle -= 360;
        }

        // min <= angle <= max 유지하도록 변경.
        return Mathf.Clamp(angle, min, max);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Movement3D movement3D;
    KeyCode jumpKeyCode = KeyCode.Space;
    public CameraController cameraController;

    // Start is called before the first frame update
    void Start()
    {
        movement3D = GetComponent<Movement3D>();
    }

    // Update is called once per frame
    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float z = Input.GetAxisRaw("Vertical");

        movement3D.MoveTo(new Vector3(x, 0, z));

        if(Input.GetKeyDown(jumpKeyCode)){
            movement3D.JumpTo();
        }

        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        cameraController.RotateTo(mouseX, mouseY);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement3D : MonoBehaviour
{
    float moveSpeed = 5.0f;
    Vector3 moveDirection;
    float gravity = -9.81f;
    float jumpForce = 3.0f;

    CharacterController characterController;
    public Transform cameraTransform;

    // Start is called before the first frame update
    void Start()
    {
        characterController = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        if(!characterController.isGrounded){ // 발이 충돌하면 true, 공중에 떠있으면 false
            moveDirection.y += gravity * Time.deltaTime; // 아래로 떨어지는 중력 적용
        }
        characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
    }

    public void MoveTo(Vector3 direction){
        // y축은 중력을 적용한다.
        // moveDirection = new Vector3(direction.x, moveDirection.y, direction.z);

        Vector3 movedis = cameraTransform.rotation * direction;
        moveDirection = new Vector3(movedis.x, moveDirection.y, movedis.z);
    }

    public void JumpTo(){
        if(characterController.isGrounded){
            moveDirection.y = jumpForce;
        }
    }
}

 

이후 멤버변수 주입

 

'Client > Unity' 카테고리의 다른 글

Unity) Input system - 이동  (0) 2024.05.04
Unity) 3인칭 캐릭터 - 이동  (0) 2024.05.02
Unity) 3인칭 캐릭터 - 카메라  (0) 2024.05.02
Unity) Third Person Camera  (1) 2024.04.28
Unity 기초 속성  (1) 2024.04.26