공부중

[Unity] modelViewer - 캐릭터 이동 구현. 본문

Project/modelViewer

[Unity] modelViewer - 캐릭터 이동 구현.

곤란 2018. 8. 20. 16:01
반응형

모델은 형님이 만들어서 fbx로 export해서 유니티 씬에 띄워놓은 상태이고...

 

캐릭터가 밖으로 빠져나가지 못하게 대충 box collider 만 주변에 씌워주고

캐릭터에는 capsule collider를 씌워주었다..

 

여기서 적어놓을것은 캐릭터 이동에 관한 스크립트를 적어볼려고 한다.

 

일단 여기(애니메이션)에서는 간단하게 Idle 상태가 기본 상태이며 isWalk라는 bool 변수를 하나 두고 이 변수를 통해서 Walk로 전환을 담당해주고 있다.

 

캐릭터를 움직이는데 w a s d 키를 이용해서 상하좌우 움직이게 해주어야 한다.

 

총 구현 코드는 아래와 같다.

 

 

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine;  
public class CharacterMovement : MonoBehaviour 
{ 
    public float speed = 1.0f; 
    private Vector3 movement; 
    private Animator anim; 
    private Rigidbody modelRigidbody; 
    private void Start() 
    { 
        anim = GetComponent<Animator>(); 
        modelRigidbody = GetComponent<Rigidbody>(); 
    } 
    
    private void Update() 
    { 
        float x = Input.GetAxis("Horizontal") * -1.0f; 
        float z = Input.GetAxis("Vertical") * -1.0f; 
        movement = new Vector3(x, 0.0f, z).normalized * speed * Time.deltaTime; 
    } 
    
    private void FixedUpdate() { Move(); } 
    private void Move() 
    { 
        if (movement.magnitude < 0.01f) 
        { 
            anim.SetBool("isWalk", false); 
            return; 
        } 
        modelRigidbody.velocity = movement; 
        modelRigidbody.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(movement), 0.15f); 
        anim.SetBool("isWalk", true); 
    } 
}

간단하다면 간단하고 길다면 긴... 아무튼 50줄 미만의 코드가 나왔다.

 

 

    public float speed = 1.0f;      
    private Vector3 movement;      
    private Animator anim;     
    private Rigidbody modelRigidbody;

변수 선언부를 보면...

유니티 에디터에서 바로 수정해 적용할 수 있도록 하기 위해서  public으로  speed를 만들어 두었고

 

나머지 부분은 딱히 외부에서 일일히 수정할 것들이 아니므로 private로 두었다.

movement는 최종 이동할 방향과 거리를 나타낸다.

 

private void Start () 
{         
	anim = GetComponent<Animator>();         
	modelRigidbody = GetComponent<Rigidbody>(); 	
}

Start에서는 GetComponent를 통해서 등록된 컴포넌트들을 받아오고 있다.

 

    private void Update()     
    {         
    	float x = Input.GetAxis("Horizontal") * -1.0f;
        float z = Input.GetAxis("Vertical") * -1.0f;
        movement = new Vector3(x, 0.0f, z).normalized * speed * Time.deltaTime;     
    }

Update에서는 수직(Vertical) 수평(Horizontal)의 기울기 값(키보드 입력은 -1, 0 1 이겠지만... 아무튼..)을 와서 x와 z에 넣어주고 있다

그리고 뒤에 각각 -1.0을 곱한 이유는..... 내가 씬에서 배치한것도 그렇고

아무튼 결과적으로 카메라 위치에서 보면...

 

캐릭터 기준으로 이동하는 방향(forward)과 카메라가 바라보는 방향이 다르기 때문에..

 

저 -1을 안곱해줬으면 w를 눌렀을떄 캐릭터는 카메라가 바라보는 기준으로 아래로 이동하게 된다. -_-;;

 

어찌되었든간에 카메라가 바라보는 기준으로 상하좌우 움직이게 하면 되는데

카메라는 일단 위치 고정이고 줌인 아웃만 할 예정이므로 저렇게 날(?) 코딩을 했다 -_-;;

(추후에 카메라가 바라보는 기준으로 상하좌우 이동하게끔 해야겠다... 크흑)

 

그리고 받아온 x,z의 값을 가지고 Vector3에 저장한 뒤에 normalized (단위벡터 - 크기가 1인 벡터)로 만들어 주고 (방향)

speed와 deltaTime을 통해서 (거리)

 

movement에 넣어주었다.

 

    private void FixedUpdate()     
    {
    	Move();     
    }      
    private void Move()     
    {         
    	if (movement.magnitude < 0.01f)
        {             
        	anim.SetBool("isWalk", false);
            return;
        }          
        modelRigidbody.velocity = movement;
        modelRigidbody.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(movement), 0.15f);
        anim.SetBool("isWalk", true);
    }

 

Update에서는 입력받아서 어디 방향으로 얼마나 이동할지를 구하였고

FixedUpdate에서는 실제로 이동하는것이 구현되어 있다.

FixedUpdate에는 간단하게 Move() 만 호출하고 있고

 

Move에는 먼저 이동할 크기가 0.01이하면 정지하는것으로 처리하였고

0.01보다 크면 모델의 rigidbody에 속도(방향+이동크기)을 주고 

(이동 방식을 가속방식이 아닌 바로 이동하게하기 위해서 velocity에 바로 값을 넣어주었다.)

 

회전은 이동하는 방향으로 넣어주는데...

조금 스무스하게 하기 위해서 Quaternion.Slerp를 이용하였다.

 

Quaternion.Slerp은 public static Quaternion Slerp(Quaternion a, Quaternion b, float t); 의 모습을 하고 있으며

유니티 문서에서도 살펴보면 이런 주석이 달려있다. - 문서 링크

// Interpolates rotation between the rotations "from" and "to" 

// (Choose from and to not to be the same as 

// the object you attach this script to)

위의 주석에서 a는 from이고 b는 to 이다.

a에서 b 사이를 보간한다는 내용이고 마지막 인자 t는 [0,1]의 범위이다.. 

( t의 값이 커질수록 from에서 to의 회전이 빠르게 전환한다고 보면 된다. )

 

아무튼 현재의 회전값에서 바라보는 회전값까지 보간을 해주면서 회전할 예정이기 때문에 위의 코드처럼 넣어주었고

임의로 값 0.15f 를 넣어주었다.

 

아래의 영상은 결과를 보여주고 있다.

 

음... 끝...

(유튜브로 바꿔야 하나... 고민을 해봐야 겠다...)

https://youtu.be/enho4WR9sOY

 

반응형