현재 위치에서 목표 위치로 이동시키기

 

Unity에서는 키보드나 마우스 입력으로 이동하는 방법 외에도 지정된 지점으로 이동하게 해주는 방법들을 제공해 준다. 그 방법들에 대해서 하나씩 알아보자. 실제로 내가 만들어서 구글 스토어에 올린 배리어 라우트라는 게임은 처음부터 끝까지 오늘 알아볼 방법들을 이용하여 움직인다.

 

처음으로 만들어본 내 게임 배리어라우트 : 빨간색과 파란색 원들은 처음부터 끝까지 오늘 알아볼 방법을 이용하여 움직인다.

 

 

자 그럼 본격적으로 알아보기 전에 유니티 에디터를 켜고 사전 세팅을 먼저 해보자.

 

하이어라키 창에서 아래와 같이 이동에 필요한 오브젝트들을 생성하자.

 

1. 3D Object → Plane 생성 후 Transform을 아래와 같이 입력한다.

Plane Transform 정보

 2. 3D Object → Capsule 생성 후 Transform을 아래와 같이 입력한다.

Capsule Transform 정보

3. Create Empty 생성 후 이름을 'TargetPosition'으로 변경 후 Tranform을 아래와 같이 입력한다.

TargetPosition(Create Empty) Transform 정보

4. TargetPosition 아래 자식 오브젝트로 큐브를 생성한다. 3번에서 생성한 TargetPosition에 마우스를 가져가서 우클릭 → 3D Object → Cube 생성 후 Transform을 아래와 같이 입력한다.

Cube Transform 정보

5. 파란색과 빨간색 Material 생성 후 각각 Capsule과 Cube에 드래그하여 넣는다. 

 

위의 작업을 완료하면 아래와 같은 세팅이 될 것이다. 그럼 이제 본격적으로 이동하는 방법에 대해서 알아보자.

 

목표지점 이동연습 세팅이 완료된 모습

 

 

■ 일정한 속도로 목표지점으로 이동(MoveToward)

 

Vector3의 function 중 MoveToward라는 함수는 일정한 속도로 목표지점까지 이동하도록 명령한다.

프로젝트 창에 C# 스크립트를 하나 생성하고 이름을 'MoveToTarget'으로 만들자. 그리고 C# 스크립트를 캡슐 안에 드래그하여 넣는다. C# 스크립트를 열어서 아래와 같이 입력해 보자.

using UnityEngine;
 
public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
 
    void Update()
    {
        transform.position = Vector3.MoveTowards(gameObject.transform.position, targetPosition.transform.position, 0.1f);        
    }
}
 
cs

코드를 살펴보면 우리가 목표지점의 Transform.Position 정보를 가져올 GameObject 변수를 public으로 선언했다. 그리고 Update 메서드에 목표지점까지 등속으로 이동하도록 코드를 작성하였다.

 

Vector3.MoveToward(시작 지점, 목표지점, 이동속도)

 

이동속도는 입력하는 숫자에 비례하여 증가하거나 감소한다.

 

유니티 에디터 창에 돌아와 캡슐을 클릭해보면 우리가 드래그하여 넣은 C# 스크립트에 TargetPosition GameObject를 넣으라고 나올 것이다. TargetPosition(C# 스크립트)에 TargetPsotion(Create Empty)를 드래그하여 넣자.

 

TargetPosition을 드래그하여 넣자.

이제 유니티를 실행시켜보자. 아래와 같이 등속으로 움직이는 캡슐을 볼 수 있다.

 

MoveToward : 일정한 속도로 목표지점을 향해 움직인다.

 

■ 목표지점 근처에서 감속하며 이동(SmoothDamp)

 

목표지점까지 이동하는 방법 중 목표지점 근처에서 감속하여 도달하는 SmoothDamp에 대해서 알아보자.

C# 스크립트를 아래와 같이 수정하고 저장하자.

 

using UnityEngine;
 
public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
    Vector3 vel = Vector3.zero;
 
    void Update()
    {
        transform.position = Vector3.SmoothDamp(gameObject.transform.position, targetPosition.transform.position, ref vel, 1f);        
    }
}
cs

 

Vector3.SmoothDamp(시작 위치, 목표 위치, 참조 속도, 스무스 타임)

 

여기 참조 속도라는 것이 들어가 있는데, 이것은 솔직히 정확히 어떤 원리로 되는 것인지 모르겠다. 현재 변화량을 기록해 넣을 수 있는 값을 변화량(속도)을 저장하는 변수라고 한다. 이 내용에 대해 아시는 고수분들이 이 글을 보시게 된다면 한 수 가르쳐 주십시오.

 

MoveToward와 다른 또 한 가지는 바로 마지막 변수로 들어가는 숫자(스무스 타임). MoveToward는 오브젝트가 이동하는 속도를 입력했다. 하지만 SmoothDamp는 목표지점을 도달하기 위한 시간이 들어간다. 그래서 작은 값이 들어갈수록 이동속도가 빨라진다.

 

SmoothDamp : 목표지점 근처에서 속도가 줄어든다.

 

위에서 보는 바와 같이 목표지점에 가까워질수록 속도가 감소하는 것을 볼 수 있다. 마치 자동차가 서서히 브레이크를 밟는 그런 느낌이다.

 

■ 선형 보간을 이용한 목표지점 이동(Lerp)

 

용어부터 어려워서 하기 싫어질지 모르지만, SmoothDamp와 비슷한 효과가 나오며 사용법은 오히려 SmoothDamp보다 간단하다. 아래와 같이 C# 스크립트를 수정해보자.

 

using UnityEngine;
 
public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
 
    void Update()
    {
        transform.position = Vector3.Lerp(gameObject.transform.position, targetPosition.transform.position, 0.05f);        
    }
}
cs

Vector3.Lerp(시작 위치, 목표 위치, 0~1 사이의 숫자)

 

0~1 사이의 숫자는 목표 위치의 가중치를 나타내는 것으로 

0을 입력하면 움직이지 않으며, 1을 넣으면 빛의 속도로 목표지점까지 도달하게 됩니다. 

즉, 1에 가까울수록 빠른 속도로 이동하게 됩니다.

 

유니티 에디터로 돌아와 실행시켜보면 아래와 같이 진행됨을 볼 수 있습니다.

 

Lerp : 선형보간을 이용한 이동

 

■ 구형 보간을 이용한 이동(Slerp)

 

마지막으로 이 이동 방법은 위로 호를 그리면서 이동한다. 마지막이니 빠르게 수정해보자. C# 스크립트에 S 하나 추가해주면 된다.

 

using UnityEngine;
 
public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
 
    void Update()
    {
        transform.position = Vector3.Slerp(gameObject.transform.position, targetPosition.transform.position, 0.05f);        
    }
}
cs

함수의 구성은 Lerp와 동일하게 참조하면 된다. 

바로 유니티 에디터를 실행하여 어떻게 움직이는지 확인해 보자.

 

Slerp : 구형보간을 이용한 이동. 우주선 착률하는 느낌이 난다.

위의 그림과 같이 크게 호를 그리며 이동하며, 목표지점에 가까울수록 속력이 감소한다. 마치 우주선 착륙하는 느낌이 난다. 

 

이렇게 한 지점에서 다른 지점까지 이동하는 방법에 대해서 알아보았다. 

여러 가지로 유용한 방법들이니 참조하시고, 도움이 되었으면 좋겠다.

물리적 속성(Rigidbody)을 이용한 이동

 

지난 블로그에서 Transform을 이용한 오브젝트 이동을 알아보았다.

하지만 손오공처럼 순간이동 하는 이동을 많은 분들이 원했던 것은 아닐 것이다.

그래서 이번 블로그에서는 유니티 내 Rigidbody라는 물리적 속성을 이용하여 좀 더 자연스러운 이동이 이루어질 수 있도록 해보겠다. 

 

우선 지난 블로그에서 만들었던 유니티 프로젝트를 켜보자.

프로젝트 내 Capsule에 추가했던 C# 스크립트를 제거해주고,

새로운 C# 스크립트를 만들어서 'RigidbodyMove'라고 이름을 지었다.

그리고 Capsule 내 드래그하여 넣어 주자.

 

그리고 Rigidbody 컴포넌트를 추가하여 물리 속성을 사용할 수 있는 준비를 해놓자.

 

Capsule 클릭 후 Add Component를 클릭한다.

 

컴포넌트에서 Rigidbody를 선택하여 추가해준다.

 

 

■ 오브젝트에 힘을 가해줘서 이동해보자(AddForce)

 

먼저 Rigidbody 속성 중 AddForce라는 function이 있다.

오브젝트에 힘주 추가하여주는 function이다. 즉, 오브젝트에 일정한 힘을 주어 이동시키는 것이다.

그럼 코드를 작성하여 화살표 방향으로 움직일 수 있도록 해보자. 

그전에 먼저 할 일이 있다. 

 

이제 Capsule은 Rigidbody라는 물리적 속성을 가짐으로 인해 중력의 영향을 받고,

가장 안정한 상태를 찾아가게 된다. 즉, 현재 유니티 창에 서 있는 Capsule은  플레이를 실행시키는 순간 기울어져 쓰러질 것이다. 그것을 방지하기 위해 X축과 Z축의 Rotation 값을 고정시켜 주겠다. 

추가로 우리는 점프는 구현하지 않을 생각으로 Position 도 Y축을 고정시켜 주겠다.

 

Rigidbody → Constraint

  : Position Y축 체크

  : Rotation X축 체크, Z축 체크

 

Rotation을 고정시켜 주지 않으면 이렇게 쓰러져 버린다.

 

Position 과 Rotation 을 위와 같이 체크해주자

이렇게 기본적인 설정을 마쳤으면 아래와 같이 아까 만들어 놓은 C# 스크립트에 입력해 보자.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class RigidbodyMove : MonoBehaviour
{
    Rigidbody rb;
    float power = 30f;
 
    void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
    }
 
    void Update()
    {
        if (Input.GetKey(KeyCode.LeftArrow) == true)
        {
            rb.AddForce(Vector3.left * power);
        }
 
        if (Input.GetKey(KeyCode.RightArrow) == true)
        {
            rb.AddForce(Vector3.right * power);
        }
 
        if (Input.GetKey(KeyCode.UpArrow) == true)
        {
            rb.AddForce(Vector3.forward * power);
        }
 
        if (Input.GetKey(KeyCode.DownArrow) == true)
        {
            rb.AddForce(Vector3.back * power);
        }
    }
}
cs

 

코드를 하나씩 살펴보면 Rigidbody 변수 rb를 선언해 주었다.

그리고 power라는 float 변수를 30이라는 값을 넣어 선언해 주었는데, 1 이라는 힘을 가해주면 정말 조금씩 움직이기 때문에 30이라는 숫자를 곱해 가해지는 힘을 올릴 수 있도록 하려 한다. 

 

Start 문에서는 변수 rb에 Rigidbody 컴포넌트를 가져왔다.

그리고 업데이트 문에서 방향키로 30의 힘이 가해지도록 작성하였다. 

이제 유니티를 재생시켜보자.

잘 된다. 잘 되긴 하는데, 방향전환이 바로바로 되지 않는다.

아마 잘 움직일 것이다. 그런데, 처음 움직일 때는 천천히 가다가 뒤로 갈수록 빨라진다. 그리고 움직이다 방향 전환을 해보면 바로 전환되지 않을 것이다. 마치 빙판위에서 방향전환하듯이 미끄러져 방향 전환이 되는 느낌일 것이다. 이것은 바로 Capsule 이라는 오브젝트가 Rigidbody라는 물리적 속성을 가지면서 현재상태를 유지하려는 관성이 반영되기 때문이다. 

 

가만히 있는 오브젝트에 오른쪽으로 30이라는 힘을 주면 바로 30의 힘이 반영되는 것이 아니라, 멈춰 있으려는 관성의 힘과 오른쪽으로 미는 힘이 서로 상쇄되면서 서서히 오른쪽으로 움직이게 된다. 오른쪽으로 30이라는 힘으로 가고 있는데, 왼쪽으로 방향전환을 한다고 생각해보자. 오른쪽으로 계속 가려는 관성으로 바로 왼쪽으로 방향전환이 되지 않고 오른쪽으로 천천히 속도가 줄어들다가 멈추고 서서히 왼쪽으로 움직이기 시작한다.

 

관성과 상관없이 오브젝트 방향을 바꾸고 싶은데, 방법이 없는 걸까?

 

■ GetAxis 메서드를 이용한 Velocity 수정

 

Rigidbody의 AddForce는 가해지는 힘을 누적시켜 속도를 증가시켰습니다. 그러다 보니 관성의 영향을 받게 되죠.

Rigidbody에는 Velocity라는 속도를 나타내 주는 변수가 있다. 이 변수를 수정해 주면 질량과 관성들을 무시하고 입력받은 속도로 방향 전환이 가능하다.

 

Velocity는 Vector3의 값으로 표현이 된다. 여기서 바로 피타고라스 정의에 의해 나오는 방향이 가고자 하는 방향이 되고, 여기서 발생되는 직석의 길이가 가고자하는 속도가 된다. (너무나 오랜만에 공부하는 수학이라 머리가 아팠다.)

 

바로 코드를 작성해 보겠다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class RigidbodyMove : MonoBehaviour
{
    Rigidbody rb;
    float speed = 10f;
 
    void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
    }
 
    void Update()
    {
        float xMove = Input.GetAxis("Horizontal");
        float zMove = Input.GetAxis("Vertical");
 
        Vector3 getVel = new Vector3(xMove, 0, zMove) * speed;
        rb.velocity = getVel;
    }
}
 
cs

 

갑자기 이상한 코드가 나와서 당황할 것 같다. 나도 처음 공부하면서 당황스럽고 이해가 안 되었다. 

여기서는 Horizontal 이 우/좌 +/-를 나타내고, Vertical이 상/하 +/-를 나타낸다는 정도만 알고 가자. 

다음 블로그에서 해당 내용에 대해서 좀 더 자세히 설명해 보도록 하겠다.

 

위의 코드에서 update 문을 살펴보면 상/하/좌/우 입력을 받아 Vector3 X, Z 값을 + / 0 / - 로 나타내 주었다.

그리고 내가 원하는 속도가 반영된 speed 변수를 곱하여 Vector3 getVel 변수에 입력 후 getVel의 값을 rb.velocity에 반영하여 Rigidbody 내 속도를 직접 접근하여 수정토록 하였다.

 

AddForce를 사용할 때보다 훨씬 이동이 자유롭게 진행된다.

다음 글에서 GetAxis 메서드와 같은 입력 매니저와 중간에 Vector3(0,0,1)을 Vector3.forward로 대체하였는데, 이 부분에 대해서 간단하게 살펴보도록 하겠습니다.

 

감사합니다.

키보드 입력으로 오브젝트 움직이기

 

오브젝트를 움직이게 만들 수 있는 방법은 여러 방법이 있다. 

이동하는 방법뿐만 아니라 여러 가지로 Vector를 많이 사용하게 되는데, 

학생 때 꼴도 보기 싫었던 Vector를 유니티 공부하면서 원없이 본 것 같다. 

 

우선 코드를 작성해서 연습해보기 전에 유니티를 켜고,

3D 프로젝트를 하나 만들어서 아래 그림과 같이 Plane과 Capsule을 하나 생성해 보자.

그리고 지난번 블로그에 나온 것처럼 Capsule을 알아보기 쉽게 파란색을 입혔다.

 

나는 아래와 같이 Plane의 크기로 Capsule의 position을 변경했다.

 

Plane Scale (X : 5, Y : 1, Z : 5)

Capsule Position ( X : 0, Y : 1, Z : 0)

 

연습을 시작할 준비가 되었다.

■ 지정된 좌표로 이동시키기(순간이동)

먼저 Tranform을 이용하여 이동시켜보자.

오브젝트를 어떤 키를 누르면 미리 지정된 좌표로 이동하도록 해보자.

아래 그림처럼 처음 Capsule 이 있던 지점으로 사각형 꼭지점으로 이동하는 스크립트를 작성해보자.

 

1번부터 4번 키를 누르면 동그라미 원 안으로 이동해보자.

 

C# Script를 열고, MovePosition이라고 스크립트 이름을 수정하고, Capsule에 드래그하여 넣자.

 

아래와 같이 코드를 입력해보자.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MovePosition : MonoBehaviour
{
 
    void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1) == true)
        {
            gameObject.transform.position = new Vector3(-212);
        }
 
        if (Input.GetKey(KeyCode.Alpha2) == true)
        {
            gameObject.transform.position = new Vector3(212);
        }
 
        if (Input.GetKey(KeyCode.Alpha3) == true)
        {
            gameObject.transform.position = new Vector3(21-2);
        }
 
        if (Input.GetKey(KeyCode.Alpha4) == true)
        {
            gameObject.transform.position = new Vector3(-21-2);
        }
 
    }
}
 
cs

코드를 살펴보면 숫자키 1~4번을 누를 때마다 사각형 꼭지점으로 이동하도록 좌표값을 넣었다.

그럼 아래와 같이 오브젝트가 이동하는 것을 볼 수 있다.

Alpha0~9를 넣으면 숫자 0~9까지의 키보드 자판을 인식하고, 

영문도 알파벳을 넣으면 알파벳을 인식하도록 되어 있다.

 

예를 들어 위의 소스코드에서 Alpha1~Alpha4 대신 A, B, C, D를 넣고

A, B, C, D를 누르면 아래와 동일하게 이동하는 것을 볼 수 있다.

 

사각형 꼭지점으로 순간이동하듯 움직이는 것을 볼 수 있다.

 

이렇게 지정된 좌표가 아닌 화살표 방향키를 눌렀을 때 이동하고 싶을 때는 어떻게 할까?

 

■ Translate를 이용한 이동

 

화살표를 눌렀을 때 일정한 간격으로 이동하는 방법은 어떻게 할까?

Transform에서는 Translate라는 function을 제공한다.

이것은 지정된 거리로 오브젝트를 이동시켜 주는 역할을 한다. 

그럼 바로 코드를 아래와 같이 수정해 보자.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MovePosition : MonoBehaviour
{
 
    void Update()
    {
        if (Input.GetKey(KeyCode.LeftArrow) == true)
        {
            gameObject.transform.Translate(new Vector3(-100));
        }
 
        if (Input.GetKey(KeyCode.RightArrow) == true)
        {
            gameObject.transform.Translate(new Vector3(100));
        }
 
        if (Input.GetKey(KeyCode.UpArrow) == true)
        {
            gameObject.transform.Translate(new Vector3(001));
        }
 
        if (Input.GetKey(KeyCode.DownArrow) == true)
        {
            gameObject.transform.Translate(new Vector3(00-1));
        }
 
    }
}
 
cs

잘 이동하는지 확인을 해보자.

 

잘 움직이기는 하지만 뭔가 부자연스럽고 엄청 빠르다.

 

움직이기는 잘하는 것 같지만 뭔가 부자연스럽다. 

유니티에는 Update라는 특별한 메서드가 있다. 이 메서드는 매 프레임마다 실행되는 함수이다. 

보통 컴퓨터는 1초당 프레임이 60번 실행이 된다. Update 메서드가 1/60초에 한 번씩 실행된다는 이야기다.

 

자세히 보면 화살표를 누르고 있는 동안 1 만큼씩 순간이동을 하는데 이게 1/60초라는 워낙 짧은 시간에 다음 좌표로 이동하기 때문에 연속된 것처럼 보이는 것이다.

 

그럼 위의 코드에서 Vector3 안의 숫자를 1 → 3으로 변경하면 어떻게 보일까?

 

3의 거리만큼 이동하기 때문에 좀더 끊겨서 이동하는 것이 잘 보인다.

 

빨리 움직이는 것처럼 보이기는 하지만 3의 거리만큼 순간 이동하면서 움직이고 있는 것이다.

일반 사람들이 게임을 플레이할 때 이렇게 움직이는 것을 원한 것이 아니었을 것이다.

그럼 연속된 움직임을 가지기 위해서는 어떻게 해야 할까?

 

Rigidbody라는 물리적 속성을 이용하여 움직이면 자연스러운 움직임을 만들어 낼 수 있다.

오늘은 여기까지 하고 다음 글에서 이어서 설명하도록 하겠다.

 

■ 2D Sprite Color 변경

 

지난번에 3D Object 에 이어 2D 에서는 Sprite Color 변경을 어떻게 할까?

 

결론부터 말하면, 

3D 오브젝트는 Material을 생성해서 변경해줘야 했지만, 

Sprite에 직접 접근하여 색을 변경한다. 

 

보통 2D 같은 경우 이미지 파일들을 많이 쓰기 때문에 색을 직접적으로 변경해야 하는 경우는 

그리 많아 보이지 않지만, 2D 퍼즐 게임같은 것을 만들때는 일부 필요할 수도 있을 것 같다.

 

그럼 한번 만들어보자

유니티 에디터에서 변경해보고, 스크립트로도 변경을 해보자.

 

2D Project를 새로 만들자.

 

2D Project

하이어라키 창에서 마우스 우클릭 → 2D Object → Sprite 를 선택해 준다.

 

Sprite 생성

 

그리고 가면 유니티 에디터 하이어라키 창에 Sprite 가 하나 생성된다. 

원하는 이름으로 바꿔주고 (나는 'Color'로 바꿨음) Scale을 X : 10, Y : 10 으로 바꾸고,

SpriteRenderer의 Sprite를 Background로 바꿔보자.

 

Sprite 설정

그러면 씬뷰에서는 보이지 않던 이미지가 아래와 같이 보이게 된다.

 

씬뷰에서 보이게 된 Sprite 2D 오브젝트

Sprite Renderer 의 Color를 클릭하고 원하는 색으로 바꿔주면 색이 변경된다.

 

유니티 에디터로 색 변경 완료

 

 

■ 스크립트로 Sprite 색 변경

 

2D Object Sprite는 스크립트로 어떻게 색 변경을 할까?

C# Script를 생성하고 아래와 C# Script를 Sprite 오브젝트에 드래그 해서 넣고,

아래와 같이 스크립트를 작성해 보자.

 

 
using UnityEngine;
 
public class ChangeColor : MonoBehaviour
{
    SpriteRenderer sprite;
    void Start()
    {
        sprite = gameObject.GetComponent<SpriteRenderer>();
    }
 
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            sprite.color = Color.red;
        }
    }
}
cs

 

코드를 간단하게 살펴보면

 

1. Start 함수에서 sprite 라는 변수에 SpriteRenderer 컴포넌트를 넣어 주었다. 

2. Update 함수에서 마우스 왼쪽 버튼이 클릭되면 빨간 색으로 변하도록 해주었다.

 

Scripte로 색전환

 

3D와 마찮가지로 문자로 지원하는 색은 총 10가지이며,

동일하게 RGB를 이용하여 색을 전환할 수 있다.

(지원하는 색 종류는 지난 블로그를 참조 바란다.)

 

 

■ 3D 오브젝트 색 표현의 원리

 

동 내용은 내가 겪은 일화로, 재미로 봐주길 바란다. 

초보자들에게는 유익한 정보가 될 수도 있다고 생각한다.

 

처음 유니티 공부를 시작할 때, 여러 온라인상의 강좌들이나 책에서 봤을 때

일단 부딪혀서 실력이 는다는 이야기를 많이 들었다. 

그래서 나도 일단 부딪혔다. 공부하면서 내가 생각한 게임을 만들기 시작했다. 

 

왜 그렇게 작업을 했는지 자세히 기억이 나지는 않지만,

2D 프로젝트에 3D 오브젝트를 넣어서 작업했다. 

길찾기 로직인 3D의 Nav Mesh 와 2D A* 알고리즘 사이에서 왔다갔다 하면서

그렇게 된 것이 아닌가 싶다.

 

아무튼, 

마구잡이로 작업을 하다가 2D Project 로 이미지들을 생성하고 3D Object 들을 나열했는데,

3D 오브젝트들이 죄다 까맣게 나온다.

 

이걸로도 몇시간을 허비했는데,

해결방안은 바로 '빛' 이었다. 

 

2D Project와 3D Project를 처음 시작하게 되면 아래와 같이 창이 뜬다.

 

3D Project 시작화면

 

2D Project 시작화면

차이점을 찾으셨나요?

하이어라키 창을 좀 더 자세히 보도록 하죠.

 

3D Object 하이어라키
2D Project 하이어라키

 

3D Project에는 Directional Light 가 기본으로 생성이 되고, 

2D Project에는 카메라만 생성이 되고 Directional Light 가 생성되지 않습니다. 

이말은 즉, 2D는 빛이 필요없다는 얘기가 되겠고, 

3D에서는 빛이 필요한 존재라는 이야기죠.

 

지난 블로그에 올렸던 씬뷰로 비교를 해보겠습니다.

 

Capsule 옆에 Sprite 를 하나 생성했습니다.

 

3D Project 안의 2D Sprite

여기서 빛을 제거해 보겠습니다.

어떻게 될까요?

 

빛을 없애니 3D Object 들은 모두 블랙죠가 되었다.

3D 오브젝트들은 빛과 함께 사라져 버렸습니다.

바닥 오브젝트인 Plane도 3D Object로 같이 블랙으로 변했습니다.

여기서 Light 만 살려주면 다시 나타나게 됩니다.

 

제가 겪은 이러한 초보적인 실수들에 대해서 하나씩 짬짬이 공유하도록 하겠습니다.

 

감사합니다.

3D 오브젝트 Color 변경

 

내가 처음 유니티를 공부하면서 책도 찾아보고 유튜브도 돌아다니며 공부하다가, 

처음으로 띵하고 막혔던 부분이 게임 도중 어떤 이벤트가 발생 시

오브젝트의 색깔을 바꾸고 싶었는데 이 부분을 엄청나게 헤매었던 기억이 있다.

 

그래서 이 글에서는

유니티 창에서의 3D Object Color 변경 방법과 

Script 상에서의 변경 방법을 알아보고자 한다.

 

 

■ Unity 창에서의 3D 오브젝트 Color 변경

 

유니티를 열어 3D Project를 생성하고, Capsule과 Plane을 생성해 보자.

생성된 오브젝트 중 Capsule의 색을 빨간색으로 변경해 보자.

 

3D 오브젝트 Capsule 과 Plane 생성

 

생성 후 Project 창에서 우클릭 → Create → Material을 선택한다.

 

Project 창에서 우클릭 → Create → Material 선택

 

아래와 같이 파란 동그라미 아이콘이 생성될 것이다.

Material 아이콘

Material의 색을 빨강으로 변경할 것이기에 이름을 Red로 바꿔 봤다.

Material을 클릭해보면 인스펙터 창에 Main Maps 가 보일 것이다. 

Main Maps 바로 밑에 Albedo라고 하여 네모난 색깔 창과 스포이트 모양이 보일 것이다.

스포이드 모양 옆에 네모를 클릭해보자.

아래와 같이 RGB 색을 고를 수 있는 창이 뜬다.

이 중 자신이 Capsule에 적용하고 색깔을 지정한다. 필자는 빨간색으로 선택했다.

 

Material Inspector 창

 

Material의 색을 변경했으면 색을 Capsule 에 적용해보자.

Material을 드래그하여 Capsule에 갖다 넣자.

 

3D Object에 Material 적용

 

아래와 같이 Capsule의 색이 변경된 것을 확인할 수 있다.

 

 

Capsule 색상변경 완료

 

 

■ 스크립트(Script)로 색 변경하기

 

게임을 만들다 보면 처음 지정된 색을 게임 끝까지 가져가는 경우도 있지만, 

어떤 이벤트나 주변 상황에 따라 오브젝트의 색을 변경해야 할 때가 있다.

 

나는 기본이 없는 백지상태였기 때문에 이것을 해결하는데만 며칠을 고생했다.

 

간단하게 마우스 클릭 시 Capsule 색이 빨간색 ↔ 파란색으로 변하는 스크립트를 작성해 보자.

 

프로젝트 창에 마우스 우클릭 → Create → C# Script를 선택해서 C# 스크립트를 생성한다.

C# 스크립트 이름을 'ColorChange'로 변경하고 Capsule 오브젝트에 드래그하여 끌어다 넣는다.

 

스트립트 삽입

 

그리고 스크립트를 열어보자.

 

간단하게 아래와 같이 코드를 입력한다.

 

 
using UnityEngine;
 
public class ColorChange : MonoBehaviour
{
    Renderer capsuleColor;
 
    void Start()
    {
        capsuleColor = gameObject.GetComponent<Renderer>();
    }
 
 
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if(capsuleColor.material.color != Color.blue)
            {
                capsuleColor.material.color = Color.blue;
            }
            else
            {
                capsuleColor.material.color = Color.red;
            }
        }
    }
}
 
cs

 

스크립트를 간단히 살펴보면, 

 

1. Start 함수 안에 capsuleColor라는 변수에 Renderer Renderer 컴포넌트를 지정해 주었다. 

2. 업데이트 문에서는 마우스 버튼의 입력을 감지한다.

  - 버튼 입력이 감지가 될 경우 material의 색이 파란색이 아니라면 파란색으로,

  - 파란색일 경우 빨간색으로 변환되도록 입력하였다. 

 

저장하고 unity를 돌려보면 마우스 클릭 시마다 빨강, 파랑으로 왔다 갔다 하는 것을 볼 수 있다.

 

처음 무색에서 빨간색, 파란색으로 변경

 

 

■ 유니티에서 문자로 지원하는 색상

 

위 Script에서 보셨듯이,

Color.red를 치면 빨간색이 되고, Color.blue를 치면 파란색이 됩니다. 

 

이렇게 RGB 코드가 아닌 문자로 입력할 수 있는 Color는  투명까지 포함해서 총 10가지입니다.

아래 문자들을 Color. 뒤에 연결하여 적으면 해당되는 색깔이 나옵니다.

 

Unity에서 지원하는 문자 Color

 

여러분, 위의 Color를 지원하는 문자 중 혹시 이상한 점 발견하셨나요?

회색이 grey, gray 두 가지로 입력할 수 있게 되어 있네요.

 

그렇다면 문자열 외에 다른 색은 어떻게 표현할 수 있을까요?

아래 큰 따옴표(" ") 안의 노란색 숫자 부분에 RGB 숫자를 0~255까지 입력하면 됩니다.

 

gameObject.GetComponent<Renderer>().material.color = new Color("0~255"/255f , "0~255"/255f, "0~255"/255f);
 
cs

 

예를 들면 white 같은 경우 RGB가 (255, 255, 255) 이니까

 

gameObject.GetComponent<Renderer>().material.color = new Color(255/255f , 255/255f, 255/255f);
 
cs

 

이와 같이 입력하면 흰색으로 변경됩니다. 

 

2019년 11월 5일 화요일, 갑자기 간단한 게임 하나가 머릿속에서 생각이 났다. 

바둑이나 오목처럼 정말 쉽고 간단한데, 동일한 게임을 찾아보니 어디에도 없었다. 

내가 생각한 이 게임은 오프라인 보드게임보다는 온라인으로 하는 것이 더 좋을 것 같다는 생각이 들었다. 

 

그러나, 난 다룰 줄 아는 프로그램이 하나도 없었다. 

 

비록 컴퓨터 관련 학과를 졸업하기는 했으나, 

대학교 입학 후 전공은 나와 전혀 맞지 않는다고 생각하고 공부를 하지 않았고,

전공필수 학점만 전공과목을 듣고, 나머지는 교양 및 다른 과목으로 학점을 채웠다. 

졸업작품도 포트폴리오를 만들고 프로그램을 만들어야 했지만 논문으로 대체하였다. 

대학 졸업 후 회사에 취직하였지만, 전공과는 전혀 무관한 업종으로 취업을 하였고, 

입사 10년 동안, 아니 졸업 후 한 번도 컴퓨터 프로그램이라는 것을 만져보지 않았다. 

 

그래서 생각한 것이 게임회사에 내 게임 제작을 제안해보자는 생각을 했다. 

이름만 대면 알 수 있는 게임회사는 답변이 없었으며,

스타트업 기업은 대표님께서 직접 회신을 주셨지만 협업의 risk를 가지고 가고 싶지는 않아했다. 

그럼 어떻게 해야 하는 것일까?

 

12월... 2019년도 다 지나가고 있었다.

내가 다니는 회사는 연말에 보통 일주일을 풀로 쉰다.

(물론 휴가를 공짜로 주지는 않고 자기 연차를 사용해야 하지만...)

이때 갑자기 내가 게임을 만들어볼까?라는 생각이 불쑥 들었다.

폭풍 인터넷 검색을 시작했고, 유니티라는 프로그램이 게임을 제작하는 데 있어 

초보자들도 다루기 쉽고 무엇보다 2018년 출시된 모바일 게임의 70프로 이상이 유니티로 만들어졌다는 글을 봤다. 

그 길로 바로 서점으로 달려갔다.

그리고 약 한 시간 정도 전체적인 관련 서적들을 둘러보고 그 자리에서 바고 구매.

이렇게 나의 유니티 공부는 시작되었다. 

 

뭔가 위의 사진처럼 아무도 알려주지 않는 길을 가는 것처럼 길을 개척해 나야가 할 것 같은 느낌이었다. - Pixabay로부터 입수된 composita님의 이미지 -

막상 낮에는 회사생활을 하고 집에서 아이들과 시간을 함께하고 잠들고 나면

얼마 되지 않는 시간에 공부를 한다는 것이 쉽지 않았지만,

사람이 뭔가 목적을 가지고 공부를 하다 보니 몸은 피로해도 재미를 느꼈다. 

내가 왜 대학시절에는 이런 재미를 느끼지 못했을까 하는 후회도 했다.

 

첫번째 게임<배리어 라우트>

현재까지 구글 플레이에 올린 게임은 총 3개...

이 3개 안에는 내가 유니티를 공부하게 된 계기를 만들어준 게임은 포함되어 있지 않다. 

겉으로 보기에는 쉬워 보였지만, 공부를 해보니 로직을 설계하는 것이 꽤나 복잡하더라. 

그래서 공부를 하면서 만들기 쉬운 게임부터 만들어봤다. 

 

두번째 게임<DBDR Dodge>

이 블로그를 시작하게 된 계기는

위에 게임들을 만들면서 구글링 하여 내가 원하는 정보들을 정확히 찾기 힘들었다. 

하루 동안 나에게 주어진 시간은 다른 사람들에 비해 적은데, 

어느 한 부분에서 막히면 그 문제를 해결하기 위해 정보를 찾는 시간 할애를 너무 많이 했다. 

그래서 현재 나의 유니티 실력은 매우 부족한 초보라고 할 수 있지만, 

내가 게임을 만들며 막혔던 부분들을 초보의 입장에서 정보를 전달하여 

게임을 만들고자 하는 사람들에게 조금이나마 도움이 되었으면 한다. 

세번째 게임<To the Earth>

두 번째, 세 번째 게임은 공부를 하기 위해서 연습용으로 만들었고,

첫 번째 게임인 배리어 라우트는 굉장히 공을 많이 들였다.

누군가에게는 매우 허접해 보일 수 있는 게임이지만,

첫발을 내딛는 나에게 부딪히는 난관이 매우 많았으며,

애착이 가는 게임이다.

 

내 블로그의 그림도 최초 배리어 라우트 이미지로 생각했던 그림이다.

 

이 블로그의 글들이 유니티에 첫발을 내딛는 사람들에게

조금이라도 도움이 되었으면 좋겠다.

+ Recent posts