본문 바로가기
공허의 유산/표현의 자유

[심심풀이] 하늘의 왕자 스카웃!

by 바른생활머시마 2023. 7. 15.
728x90
반응형

스타크래프트 카툰으로 만들어 보는 유니티 공부 샘플

 

2D 게임의 스크롤형 게임의 배경은 스프라이트 이미지를 배경에 깔고, 이 스프라이트의 텍스쳐 좌표를 계속 바꿔주면 됩니다.

 

계속 반복 될 배경 패턴 이미지가 필요한데, 검색 된 이미지들 두 어개 조합해서 만들어 봅니다.

 

요렇게 정사각형으로 하나 만들었습니다. 휴대폰에서 하려면 한쪽으로 길어야 할텐데 그냥 화면 보다 큰 정사각형을 그려서 쓰면 되니까~

StarcraftCartoonRepeatPattern.zip
3.44MB

 

배경 이미지가 될 사각형 스프라이트를 추가 합니다.

 

게임 화면은 세로로 길게 9:16으로 해두고, 전체 화면을 덮는 정사각형으로 크기를 조정 해 둡니다.

이미지를 프로젝트 에셋에 추가하고 이것을 배경 스프라이트의 이미지에 할당 합니다.

 

비행기는 "하늘의 왕자" 스카웃을 해보겠습니다.

스카웃은 탑뷰로 카툰 랜더링 된 이미지가 잘 없네요.

 

실사형 모델링 이미지를 하나 받아서 카툰 스타일로 좀 만들어 보려고 했는데, 이쁘게 되지 않겠네요. 빠른 포기...

AILab Tools라는 온라인 서비스는 얼굴용인것 같고..

유튜브의 플레이 영상에서 캡쳐해서 쓰는 걸로~

 

쓸데 없는데 힘 뺀건 아닌지..ㅋㅋ

넣고 봐도 별로 폼나거나 귀엽지도 않네요. 쓸데 없는데 힘 뺐네.. 나중에 반짝이 파티클이나 좀...

배경 화면 스크롤을 하려면 배경 스프라이트를 재질에도 적용 해 줘야 합니다.

코드는~~~

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

public class Background : MonoBehaviour
{

    Material mat;
    float curOffset = 0.0f;
    float speed = 0.08f;

    // Start is called before the first frame update
    void Start()
    {
        mat = GetComponent<SpriteRenderer>().material;
        
    }

    // Update is called once per frame
    void Update()
    {
        curOffset += speed * Time.deltaTime;
        mat.mainTextureOffset = new Vector2(0, curOffset);
    }
}

요렇게까지만 하면 배경 화면 스크롤은 아래와 같이 됩니다.

 

간단히 키보드로 움직일 수 있게 해볼까욥~

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

public class Scout : MonoBehaviour
{
    public float speed = 10.0f;

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

    // Update is called once per frame
    void Update()
    {
        float dx = Input.GetAxis("Horizontal");
        float dy = Input.GetAxis("Vertical");

        transform.position += new Vector3(dx, dy, 0) * Time.deltaTime * speed;
    }
}

요렇게 하면 쉽게 움직임 처리가 됩니다.

그런데, 화면 밖으로 나가는 문제가 있군요. 음수로 나가지 못하는 것은 쉬운데, 화면 크기는 어떻게 알 수 있으려나요??

 

World좌표와 Screen좌표를 알아야 하겠네요.

World좌표는 말하자면 transform.position들이 존재하는 공간이고, Screen좌표는 화면의 픽셀 좌표입니다.

화면의 픽셀 좌표로 얻어지는 스크린의 크기는 Screen.Width, Screen.Height로 쉽게 얻을 수 있네요.

 

그래서, 월드 좌표 업데이트 후, 이것을 스크린 좌표로 변경하여 화면 밖인지 확인하고, 밖이면 화면 내부의 좌표로 조정한 후, 이것을 다시 월드 좌표로 변환 해 주면 되겠네요.

    void Update()
    {
        float dx = Input.GetAxis("Horizontal");
        //float dy = Input.GetAxis("Vertical");

        transform.position += new Vector3(dx, 0, 0) * Time.deltaTime * speed;


        // 범위 밖이면...
        Vector3 scrPos = Camera.main.WorldToScreenPoint(transform.position);
        if (scrPos.x < 0 || scrPos.x > Screen.width)
        {
            if (scrPos.x < 0)
            {
                scrPos = new Vector3(0.0f, scrPos.y, scrPos.z);
            }
            else if (scrPos.x > Screen.width)
            {
                scrPos = new Vector3(Screen.width, scrPos.y, scrPos.z);
            }

            //조정 된 범위의 스크린 좌표로 다시 World 좌표 설정
            transform.position = Camera.main.ScreenToWorldPoint(scrPos);
        }
    }

화면과 월드간 변환은 제법 비싼 연산 같은데, 화면의 크기가 바뀌지 않는다면 시작 할 때 화면의 끝점에 해당하는 월드 좌표를 구한 후, 계속 월드 좌표 내에서 비교하는 것이 훨씬 유리하겠네요.

   void Update()
    {
        float dx = Input.GetAxis("Horizontal");
        //float dy = Input.GetAxis("Vertical");

        transform.position += new Vector3(dx, 0, 0) * Time.deltaTime * speed;
        if (transform.position.x < minWorldX)
        {
            transform.position = new Vector3(minWorldX, transform.position.y, transform.position.z);
        }
        else if (transform.position.x > maxWorldX)
        {
            transform.position = new Vector3(maxWorldX, transform.position.y, transform.position.z);
        }

        /*
        // 스크린 좌표계에서 비교하는 방법
        // 범위 밖이면...
        Vector3 scrPos = Camera.main.WorldToScreenPoint(transform.position);
        if (scrPos.x < 0 || scrPos.x > Screen.width)
        {
            if (scrPos.x < 0)
            {
                scrPos = new Vector3(0.0f, scrPos.y, scrPos.z);
            }
            else if (scrPos.x > Screen.width)
            {
                scrPos = new Vector3(Screen.width, scrPos.y, scrPos.z);
            }

            //조정 된 범위의 스크린 좌표로 다시 World 좌표 설정
            transform.position = Camera.main.ScreenToWorldPoint(scrPos);
        }
        */
    }

좌우로만 움직이게 해서 만들어 보았습니다.

 

https://github.com/red112/startooned.git

 

GitHub - red112/startooned

Contribute to red112/startooned development by creating an account on GitHub.

github.com

 

728x90
반응형

댓글