프로그래밍/Unity C#

[Unity] Tutorial 05 - Beginner Gameplay Scripting (Translate)

김잉장 2019. 6. 7. 11:36

목표

  • 이동 방법에 대해 알아보자.

Translate

이동 스크립트 만들기

  • unity에서 물체를 움직이기 위한 가장 일반적인 방법은 transform의 Translate를 이용하는 것이다.
  • 다음은 물체를 x축으로 이동하시키는 예제 코드를 생성해 보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TransformFunctions : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    public void FixedUpdate()
    {
        this.transform.Translate(new Vector3(1, 0, 0));
    }
}
  • 위와 같이 코드를 생성하고 cube를 생성한 뒤, Add Component를 사용하여 물체에 이동 스크립트를 추가한다.

  • 이후 Play 버튼을 누르면, 물체가 x축으로 이동하는 모습을 볼 수 있을 것이다.

입력 이벤트로 물체 이동

  • 키의 입력 이벤트를 받기 위해서, Input.GetKey 함수를 이용하였다.
  • 키의 종류는 KeyCode를 이용하여 W,A,S,D 키를 입력 받아 상하좌우로 움직이게 하였다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TransformFunctions : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.W))
        {
            this.transform.Translate(new Vector3(0, 0, 1));
        }
        if (Input.GetKey(KeyCode.S))
        {
              this.transform.Translate(new Vector3(0, 0, -1));
        }
        if (Input.GetKey(KeyCode.A))
        {
            this.transform.Translate(new Vector3(-1, 0, 0));
        }
        if (Input.GetKey(KeyCode.D))
        {
            this.transform.Translate(new Vector3(1, 0, 0));
        }
    }

    public void FixedUpdate()
    {

    }
}

방향을 통한 물체 이동

  • Move Tool이 선택되어 있는 상태(Scene창을 클릭하고 W를 누른 상태)에서, Hierarchy창에서 물체를 선택하면 물체는 아래와 같이 자신의 XYZ 성분을 표시한다.

  • 이때 Z축은 물체의 forward (앞쪽)이되고, X축은 물체의 right(오른쪽), Y축은 물체의 up(윗쪽)이 된다.

  • 또한 변수를 생성하여 물체의 속도를 조절할 수 있다.

  • 이 정보를 참고하여 물체를 움직이는 스크립트를 제작해 보면 아래와 같다.

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

public class TransformFunctions : MonoBehaviour  
{ 

public float MoveSpeed = 10;

  // Use this for initialization  
  void Start()  
  {

  }

  // Update is called once per frame  
  void Update()  
  {  
    if (Input.GetKey(KeyCode.W))  
    {  
        this.transform.Translate(this.gameObject.transform.forward * MoveSpeed);  
    }  
    if (Input.GetKey(KeyCode.S))  
    {  
        this.transform.Translate(this.gameObject.transform.forward * -1 * MoveSpeed);  
    }  
    if (Input.GetKey(KeyCode.A))  
    {  
        this.transform.Translate(this.gameObject.transform.right * -1 * MoveSpeed);  
    }  
    if (Input.GetKey(KeyCode.D))  
    {  
        this.transform.Translate(this.gameObject.transform.right * MoveSpeed );  
    }  
  }
  public void FixedUpdate()  
  {

  }  
}

Time.deltaTime을 이용한 물리 제어하기

  • 위 스크립트를 적용하면, 물체가 너무 빨리 움직이는 문제점을 발견할 수 있을 것이다.
  • 이때 사용하는 것이 Time.deltaTime이다.

Time.delaTime

  • update의 경우 매 frame에 update가 일어난다. 최대한 빠른 처리를 요구하는 작업은 update에서 처리하는 것이 옳겠지만, 모든 사용자에게 일정한 시간이 지난 후 일어나야 하는 이벤트 물리, 시간 등의 처리는 update에서 처리하지 않는 것이 좋다.
  • 이말인즉, 디바이스의 사양이 좋은 A 사용자(60fps)와 사양이 좋지 않은 B 사용자(20fps)의 디바이스가 있을 때, 1frame에 1cm를 이동한다고 update에 구현한 경우, 1초가 지난 경우 A사용자는 60cm, B 사용자는 20cm만큼 이동하였을 것이다.
  • 이경우 Time.delaTime을 사용한다. Time.delaTime은 1/frame rate로 동작하기 때문에, frame rate에 독립적인 계산을 할때 유용하다.
  • 위 예로 설명하면 60fps의 사용자는 1frame에 0.01666cm를 이동할 것이고, 30fps의 사용자는 1frame에 0.0333cm를 이동할 것이다.
  • 또한 이러한 문제를 해결하고자 일정한 update 주기를 가지는 FixedUpdate를 제공하고 있다.

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

public class TransformFunctions : MonoBehaviour  
{ 
  public float MoveSpeed = 10;

  // Use this for initialization  
  void Start()  
  {

  }

  // Update is called once per frame  
  void Update()  
  {

  }

  public void FixedUpdate()  
  {  
    if (Input.GetKey(KeyCode.W))  
    {  
        this.transform.Translate(this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);  
    }  
    if (Input.GetKey(KeyCode.S))  
    {  
        this.transform.Translate(this.gameObject.transform.forward * -1 * MoveSpeed * Time.deltaTime); 
    }  
    if (Input.GetKey(KeyCode.A))  
    {  
        this.transform.Translate(this.gameObject.transform.right * -1 * MoveSpeed * Time.deltaTime);  
    }  
    if (Input.GetKey(KeyCode.D))  
    {  
        this.transform.Translate(this.gameObject.transform.right * MoveSpeed * Time.deltaTime);  
    }  
  }  
}