ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RPG 액션 연습 01. Player 이동구현
    연습 프로젝트/RPG 연습

    안녕하세요. 

     


    오늘은 RPG 액션 까지는 아니지만... RPG를 한번 만들어 보고 싶어서

     

    빠르진 않더라도 천천히 다양한 동작들을 연습하는 과정을 보여드리려고 합니다.


    뭐니 뭐니 해도 게임을 생각하면 Player가 빠지면 섭하니 

     

    우선 player부터 만들어 보겠습니다.

     

    Player

    player 입니다. 유니티 에셋 스토어에서 다운로드하여왔습니다.

     

    우선 Player의 보는 시점부터 구현하겠습니다.

    캠의 기능은 2가지입니다.

    1. 마우스의 이동방향 대로 회전을 실시

    2. 줌 기능

     

    캠 이동 구현인 CamMove() 함수부터 보겠습니다.

     mouseX += Input.GetAxis("Mouse X");
            mouseY += Input.GetAxis("Mouse Y") * -1;

     

    유니티 자체에 내정되어있는 Input Manager -> Axes 들  중

    마우스의 좌/우를 담당하는 Mouse X

    마우스의 상/하 를 담당하는 Mouse Y

    입니다.

     

    자세히 보시면 Input.GetAxis("Mouse Y") * -1이 되어 있는데,

    한국인이 볼 때? 는 상하 적용이 반대로 되어있어 -1을 곱해주었습니다.

     

    이후 조건문으로 10 이상이라면 10을 / 0 이하라면 0으로 상/하 인 Mouse Y의 값에 제한을 걸어두었습니다.

     

    캠이 회전되는 방식은, Main Camera를 Player의 위치에 있는 빈 오브젝트의 자식 상태로 두고

    이 빈 오브젝트를 회전시켜 주는 방식으로 구현해 보았습니다.

     

    cam_Center.rotation = Quaternion.Euler(new Vector3(
                cam_Center.rotation.x + mouseY,
                cam_Center.rotation.y + mouseX, 0) * cam_Speed);

    여기서 주의할 점이 

    좌 / 우 이동은 x축이지만 좌 / 우 회전 은 Y축이 담당한다는 점입니다.

     

    cam_Center = player에 위치한 빈 오브젝트입니다.

    여기서 Euler는 파라미터로 들어오는 오일러의 값을 쿼터니언으로 바꿔주는 함수입니다.

     

    Euler angle과는 다르게 쿼터니언은 4개의 성분 x, y, z, w로 구성되어 있으며....

    좀 더 들어가면 수학적으로 복잡하게 구현되어있기에,, 음.... 착실히 공부하겠습니다....

     

    우선 cam_Center.rotation.x + mouseY 캠 x축엔 mouseY를

    cam_Center.rotation.y + mouseX 캠 Y축엔 mouseX를

    이용한 방법을 구현했습니다.

    Update문 에서 실행

    이후 휠 값과 마우스 Y축의 값을 설정해 주어서 실행될 때 매 번 같은 값으로 실행되게 하였습니다.


    이제 회전하여 보는 시점이 완료되었으니 

     

    Player의 Move를 보겠습니다

    선언된 변수들
    player 의 Move 동작 함수

    Player의 Move함수 전체 코드입니다.

     

    지난 프로젝트들을 작업해보며, 제가 직접 짠 코드도 못 찾는 경험을 적지 않게 한 초보자이기에..

    주석을 통해서 코드 정리를 해보려고 주석을 꼭 달려고 노력해봤습니다.

    역 효과?

    음.. 가독성을 떨어트리는 것 같기도 하고.. 아직 모든 코드들이 한눈에 들어오질 않아서

    조심스레 양해를 부탁드립니다..


    다시 돌아와 코드 설명을 이어가자면 Move 함수부터 살펴보겠습니다.

    변수로 선언한 Vector3 movement를 이용해 

    new vector3(x값 , 0 , z값)을 정해주었습니다.

    Horizontal도 Mouse X / Mouse Y와 같이 

     

    유니티 내부의 Input Manager에 있는 axes입니다.

    좌 / 우 방향으로 a, d 혹은 방향키 ←,→ 를 누르면

    -1.0f - 0 - 1.0f 값을 반환시켜 주는 Horizontal입니다.

     

    상 / 하 방향으로 w, s 혹은 방향키 ↑↓를 누르면

    -1.0f - 0 - 1.0f 값을 반환시켜 주는 Vertical입니다.

     

    철자가 틀리면 작동을 안 하기에 주의를 해야 하며

    Edit -> Project Settings -> Input Manager에 들어가셔서 복사 / 붙여 넣기

    를 해도 좋은 방법입니다.

     

    방향 백터라고도 불리는 nomalrized로 정규화를 해 주었습니다.

    이 1로 만드는 정규화를 하지 않고 대각선 이동 (한쪽 값이 아닌 양쪽 값)을 적용했다면

    원하는 값이 아닌 더 빠르게 이동한다거나 하는 상황이 발생하기에

    벡터를 1로 변환해 주며 정규화를 시켜 줘야 합니다.

     

    좀 더 찾아보니 보통 Direction(방향)을 줄여 dir로 쓴다고 합니다.

     

    //

    이후 이 받아온 값 Horizontal / Vertical의 반환 값이

    vector3.zero = 0 이 아니라면

    움직이고 있다는 뜻이니

     

    player_Center.rotation = Quaternion.Euler(
                    new Vector3(0, cam_Center.rotation.y + mouseX,0) * cam_Speed)로

    플레이어의 중심축을 카메라의 중심축과 함께 회전을 해주었습니다

     

    플레이어의 이동 부분입니다.

    player_Center.Translate(movement * player_Speed * Time.deltaTime)

    Translate를 사용하였고, movement의 값은 Horizontal과 Vertical의 반환 값입니다.

    * player의 스피드 * Time.deltaTime을 사용해

    PC의 성능과는 무관하게 동등한 조건이 되게 만들어 주었습니다.

     

    마지막으로 플레이어를 이동방향으로 회전시키는 데에 Quaternion.Slerp으로 구면 선형 보관법을 사용해 보았습니다.

    Quaternion.Slerp은 회전이나 방향을 보관할 때 주로 쓰이는 함수인데

    좀 더 부드러운 회전이 가능하며, 보간 결과로 만들어지는 방향을 나타내는 Quternion입니다.

     

    player.localRotation = Quaternion.Slerp(
                    player.localRotation, Quaternion.LookRotation(movement), 6 * Time.deltaTime)

    이 처럼 A벡터와 B벡터 사이를 퍼센트로 보강한 결과를 쿼터니언으로 리턴하기에

    A = player.localRotation

    B = Quaternion.LookRotation(movement)

    그리고 float t의 값으로 속도를 지정해 주었습니다.

     

    player.GetComponent <Animator>(). SetBool("Walk", true)

    플레이어의 Animator를 받아와 "Walk"를 true로 전환시켜 실행해 주는 코드입니다.

    반대로

    if (movement == Vector3.zero) 즉 반환 값이 0 일시 움직이지 않는 상태로 간주하기에

    player.GetComponent <Animator>(). SetBool("Walk", false) 

    로 Walk를 false로 전환시켜 Walk동작을 해제시켜 줍니다.

     

    Move함수의 마지막으로

    cam_Center.position = new Vector3(player.position.x, player.position.y + 1.5f, player.position.z) 코드입니다.

    캠 센터의 방향을 new vector3로 받아 플레이어의 x축 , 플레이어의 y축 + 1.5f (머리 쪽으로 위치), 플레이어의 z 축

    으로 지정해 주었습니다.

    빈 오브젝트인 캠 센터의 아이콘을 기즈모화 해서 시각적으로 보이게 해 두었습니다.

     

     

    댓글

김효겸 / Tel. 010-7735-0580 / E-mail. dollzzang2@hanmail.net