본문 바로가기
프로그래밍/Unity

내가 유니티에선 왕초보? - 1주차 - 기본기

by 리나그(ReenAG) 2021. 4. 3.
728x90
반응형

오늘은 유니티 과제를 풀어보려고 한다. 사실 어제 기본적인 틀은 다 짜놓았고, 오늘 어떻게 제출할까 궁리하는 중.

 

유니티는 게임을 만들기 위한 툴로, 이벤트처리, 스프라이트 렌더링, 오브젝트 레이캐스트(내가 이 기능 마인크래프트 블록 하나 부순답시고 한 달 걸려서 만들었다.) 등의 방대한 기술을 지원한다. 게다가 초보는 돈을 안내도 되는 특수한 기믹 덕에, 쉽게 이용할 수 있는 것은 덤이다.

 

이 글에서는 유니티가 뭐다~ 라고 소개하기 보다는 그냥 바로 예제로 뛰어 들어가보려고 한다.

 

스프라이트(텍스쳐)는 선배님이 제공해 주셨다. 버튼 이미지 1개, 슬라임 이미지 1개.

선배님이 친절히 허락해 주셨당...

우선 Sprites / Scripts라는 폴더를 각각 만든다.

Assets 안에 2개의 폴더를 만든다. Prefabs는 아직 안쓰니까 신경안써도 된다.

Sprites에 2개의 이미지를 넣어 놓고(드래그 앤 드롭!), 오른쪽의 Inspector를 이용해서 Texture Type를 Sprite 2D로 만든다. 이렇게 하면 이제 Scene에다가 슬라임을 던져 넣을 수 있다!

선배님이 이건 자세히 설명 안해주셔서 혼났다... ㅠㅠ

슬라임을 Sprites창에서 드래그 앤 드롭으로 Scene에 넣고, Inspector창에 Add Component를 클릭해서 RigidBody 2D를 추가한다.

 

필자는 이미 RigidBody2D를 추가한 상태이다.

 

이젠 대망의 스크립트를 만들어보자! Scripts 폴더에 Slime 이란 이름의 C#스크립트를 하나 만든다.

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

public class Silme : MonoBehaviour
{

    [SerializeField] public float speed;
    private Vector3 finalTransformVector;
    public Vector3 eventAddVector;
    public float horizontal, vertical;
    public Rigidbody2D rigidBody;
    //public bool is_horizontal_moving;

    void cage_slime()
    {
        float limit_x = 9.0f, limit_y = 3.0f;
        if (rigidBody.position.x > limit_x)
            rigidBody.position = new Vector3(limit_x, rigidBody.position.y, 0);
        else if (rigidBody.position.x < -limit_x)
            rigidBody.position = new Vector3(-limit_x, rigidBody.position.y, 0);

        if (rigidBody.position.y > limit_y + 2.0f)
            rigidBody.position = new Vector3(rigidBody.position.x, limit_y + 2.0f, 0);
        else if (rigidBody.position.y < -limit_y)
            rigidBody.position = new Vector3(rigidBody.position.x, -limit_y, 0);
    }

    // Start is called before the first frame update
    void Start()
    {
        rigidBody = GetComponent<Rigidbody2D>();
        eventAddVector = new Vector3(0, 0, 0);
    }

    // Update is called once per frame
    void Update()
    {
        horizontal = Input.GetAxisRaw("Horizontal");
        vertical = Input.GetAxisRaw("Vertical");

        finalTransformVector = new Vector3(horizontal * speed, vertical * speed, 0) + eventAddVector;

        rigidBody.velocity = finalTransformVector;
        cage_slime();
    }
}

 

cs에 위의 내용을 박아 넣고 본다. 이미 나는 프로그래밍을 배웠으므로 이게 이런 역할을 하는 것이라고 그냥 몸소 알아버렸다. 하는 김에 심심해서 slime을 화면 밖으로 나갈 수 없게 만들어 버리기도 했다. (이게 과제의 중요한 부분은 아닌지라 설명은 안하겠음.)

 

Start()는 게임이 시작할 때 한번 불리는 코드이다. 아두이노의 setup()과 비슷한 격이다.

-> 정확히는 이 객체가 인스턴스화 될 때, 즉 initializer에 한 번 불린다. 거의 비슷한 역할을 할 수는 있지만, 유니티와 관련된 코드는 여기서 처리를 하는 것이 안전할 것이다.

 

Start에서는 Silme에 있는 RigidBody2D를 가져온다. 그리고 eventAddVector를 영벡터로 초기화해준다. (Null참조할까봐)

 

Update에서는 첫째로, 유저에게서 Input(키보드에서)을 받는다. 방향키 오른쪽은 +1, 아래쪽은 -1하는 식으로 알아서 받아준다. 아주 편리하다. 이벤트 시스템에 일일히 키보드 마다 코드 등록 하던 시절은 갔군 ㅋㅋ.

둘째로, Input값들을 이용해서 finalTV를 계산해 준다. 이 값이 바로 이 슬라임의 속도값이 된다.

 

그런 다음 RigidBody 2D와 마찬가지로 Silme에 컴포턴트로 넣어준다.

 

여기서 바로 실행시키지 말고, Inspector 창에 들어가서 보자.

GravityScale 과 Speed를 조절해 준다.

처음이라면 Gravity Scale = 1, Speed = 0인 상태일 것이다. GravityScale은 캐릭터에게 중력을 부여해서 -y방향으로 떨어지게 만든다. 우리에겐 필요없는 기능이므로 0으로 만들어서 일단 끈다. 또 Speed값은 꼭 25일 필욘 없고 알아서 설정하면 된다. 이게 cs에서 보았던 [SerializeField]의 정체인데, 이 태그가 붙었다면, Unity의 Inspector에서 초기값을 지정할 수 있다. 역시 겁나 편리행...

 

이제 위의 플레이 버튼을 누르면 방향키로 슬라임이 움직일 것이다.

 

이젠 버튼을 만들 것이다. 기분이 좋으므로 버튼을 4개나 만들 것이다.

슬라임을 커지게, 작아지게 하는 버튼 2개, 양 옆으로 움직이게 만드는 버튼 2개를 만들 것이다.

 

이번에는 슬라임이 했던 것처럼 Scene에 그래그 앤 드롭을 하지 않을 것이다.

대신, Hierarchy 창(왼쪽 창이다!)에서 마우스 오른쪽 키->UI->Button 눌러서 만든다.

 

그러면 그냥 평범한 Button 하나가 만들어지는데, Canvas안에 만들어질 것이다. 거기에서 Button 드롭 다운 메뉴를 눌러서 남아 있는 Text를 제거해 준다.

이름이 조금 다른 점은 양해해 주세요!

그렇게 한 다음, 우리가 원하는 텍스쳐의 Sprite로 바꾸기 위해서 Inspector창에 들어가서 스프라이트를 살포시 바꾸어 준다.

체크된 버튼을 누르면 버튼의 스프라이트를 바꿔버릴 수 있다.

이제 버튼의 위치는 RectTransform을 이용해서 바꾸고, 이 버튼이 할 일이 있으니 이름도 살짝 바꾸어 준다.

솔직히... 일일히 설명하는 거 어렵단 말이지?

Width와 Height가 처음 설정했다면, 160에 30으로 설정되어있다. 위처럼 160으로 통일하든 30으로 통일하든 버튼에 맞는 너비 / 높이를 세팅해주자.

Pos X/Y/Z는 좌표평면을 배웠다면, 아마 이해하기 좋을 것이다. 왼쪽 위의 bottom/right가 보이는가? Game Screen의 최하단 오른쪽 점이 좌표평면의 원점이다 생각하고, 버튼의 정중앙의 위치를 (Pos X, Pos Y)에 놓는다고 생각하면 된다. (Z값도 마찬가지 이긴 한데 여기선 안 건드릴 것이다.)

Rotation도 스프라이트를 회전 시키는데 이용할 것이다. 나머지는 건드리지 말고 Z값만 건드리자. Z = 90으로 놓으면 버튼이 90도 돌아간다. Scale은 크기 조절에 쓰인다. 그냥 설명하는 거 보다는 그냥 아무 값나 넣어보자. 1보다 큰 숫자를 넣었다면 크고 아름다운 버튼을 볼 수 있을 것이다.(시간이 남으면 음수값도 넣어보자.)

 

자... 그럼 똑같은 방식으로 나머지 3개 버튼도 만든다. 물론 위치와 회전은 다르게 해주자. bottom/right를 고집할 필욘 없다. 각 버튼 마다 맘에 드는 걸로 해주자. 게임 스크린 크기가 달라지는 경우도 많기 때문에 있는 기능이다.

다 만들었으면 이렇게 된다.

Left Right라고 써있는 건 Text제거 안해서 그런거다. 시간이 남으면 이것도 넣어보자.

이젠 버튼에 기능을 만들러 가보자. SlimeButton이라는 이름의 cs파일을 한 개 만들자.

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

public class SilmeButton : MonoBehaviour
{

    [SerializeField] Silme slime;

    public void OnClickBiggerButton()
    {
        slime.rigidBody.transform.localScale *= 1.5f;
    }

    public void OnClickSmallerButton()
    {
        slime.rigidBody.transform.localScale *= 0.7f;
    }

    public void OnClickRightButton()
    {
        float speed = slime.speed;
        slime.eventAddVector = new Vector3(speed, 0, 0);
    }

    public void OnClickLeftButton()
    {
        float speed = slime.speed;
        slime.eventAddVector = new Vector3(-speed, 0, 0);
    }

    public void OnPointerUpButtons()
    {
        slime.eventAddVector = new Vector3(0, 0, 0);
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

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

    }
}

이번엔 Start하고 Update는 이용 안하고 우리가 직접 만든 함수 5개를 이용할 것이다.

각각의 함수가 하는 일은 다음과 같다 :

 

OnClickBiggerButton,

Silme 객체의 ScaleVector에 1.5배를 곱한다. 쉽게 말해 Slime의 크기를 1.5배로 만든다.

 

OnClickSmallerButton,

Silme 객체의 ScaleVector에 0.7배를 곱한다. 쉽게 말해 Slime의 크기를 0.7배로 만든다.

 

OnClickRightButton,

Silme 객체의 eventAddVector를 (speed, 0, 0)으로 만든다. 쉽게 말해 Slime의 속도값을 오른쪽으로 가게끔 조작한다.

 

OnClickLeftButton,

Silme 객체의 eventAddVector를 (-speed, 0, 0)으로 만든다. 쉽게 말해 Slime의 속도값을 왼쪽으로 가게끔 조작한다.

 

OnPointerUpButtons,

Silme 객체의 eventAddVector를 (0, 0, 0)으로 만든다. 쉽게 말해 Slime의 속도값을 0으로 만든다(하지만 여전히 키보드로 조작하는 것은 가능~)

 

이젠 이걸 4개의 버튼에 전부 더해준다. cs파일을 Inspector창에 드래그 앤 드롭해도 좋고 Add Component해도 좋고 어떻게든 더하자. 그 후에는 꼭! Slime을 설정해주자.

누르면 선택가능한 옵션이 1개 밖에 없을 건데, 그걸 누르면 된다.

 

이젠 Inspector창에서 어느 상황에서 이 함수들이 불려야하는지만 정해주면 된다. 우선 좀 더 쉬운 OnClickBiggerButton부터 해보자.

Button의 OnClick 탭의 +를 눌러서 만들자.

 

드래그 앤 드롭으로 옮기고, 부르고 싶은 함수를 지정한다!

참고로 함수는 알아서! OnClickBiggerButton을 찾자! OnClickSmallerButton도 똑같이 해주자.

 

이제 Right / Left버튼은 조금 다르다. Inspector창에서 Add Component를 누르고 EventTrigger를 더해준다.

Add New Event Type을 누르고 보는 것과 같이 PointerUp / Down을 1개씩 만든다. 아까 했던 것처럼 드래그 앤 드롭을 Runtime아래에 있는 블록에다가 해주자. PointerUp에는 아까 만들었던 5번째 함수인 OnPointerUpButtons를 넣고, PointerDown에는 Right 버튼이므로 OnClickRightButton을 넣는다.

 

이걸 똑같이 Left버튼에도 해주자. 물론 함수는 OnClickLeftButton를 넣는다.

이제는 모든 기능이 완성되었다! 한 번 플레이 버튼을 눌러서 기능을 테스트해보자.

 

728x90
반응형