본문 바로가기

Programming/유니티

유니티(Unity) 배경 UV 애니메이션

목표

DoTween을 이용하여 간단한 UV 애니메이션을 만들어보자

배경 이미지


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class Background : MonoBehaviour
{
    Material material;
    float uvHeightScale = 1;

    private void Awake()
    {
        material = GetComponent<Image>().material;
		
        //메터리얼에 사용된 텍스쳐의 스케일을 가져온다
        uvHeightScale = material.mainTextureScale.y;
        Debug.Log(material.mainTexture.width + " : " + material.mainTexture.height);
    }    

    public void ScrollUVOffset (float _moveDistance, float _duration, Ease _ease)
    {
    	//이동이 화면의비의 얼마나 이동하는지 계산한다.
        var screenHeightRate = _moveDistance / Screen.height;
        Debug.Log(screenHeightRate + " / " + uvHeightScale);

		//화면비에 텍스쳐 스케일을 곱한다.
        screenHeightRate *= uvHeightScale;

        material.DOOffset(new Vector2(0, screenHeightRate), _duration).SetEase(_ease);
    }
}

----

----

이미지의 UV 좌표를 이용하여 이미지가 스크롤되는 것 처럼 연출을 하였습니다.

기본 셋팅은 설명된 아래의 글을 확인하시면 도움이 됩니다.

 

유니티 애드몹 부업 프로젝트 : 프로젝트 생성

목표 프로젝트를 생성하고 운동장과 캐릭터를 만들어 스크립트를 붙이자 프로젝트 생성 유니티 허브를 실행시켜 프로젝트를 생성합니다. 'New project'를 선택합니다. '2D'를 선택하고 'Project name'을

moblieandlife.tistory.com

 

유니티 DoTween 추가하기

목표 DoTween Package를 추가시켜보자. DoTween 패키지 추가 DoTween은 애니메이션 연출을 로직으로 쉽게 구현할 수 있도록 도와주는 패키지입니다. 유니티 에셋스토어로 접속합니다. 에셋스토어 여러분

moblieandlife.tistory.com

 

먼저 UI Image를 생성해서 Background 를 만드는 것부터 합니다.

'Hierarchy' 영역에서 오른쪽 버튼을 눌러 Image 를 생성하고 이름을 'Background' 로 변경합니다.

그리고 캐릭터가 'Background'에 가려지지 않기 위해 'Canvas'를 카메라 영역안으로 설정해줘야 합니다.

'Canvas'를 눌러 카메라를 셋팅합니다.

'Inspector' 창에서 보이는 Canvas의 Render Mode 를 Overlay에서 Camera로 변경시켜 줍니다.

그리고 'Hierarchy' 영역에 있는 카메라를 Render Camera 영역에 드래그 앤 드랍하면 됩니다.

이제 'Background' 를 클릭해서 전체 화면을 덮도록 설정해 줍니다.

하얀 배경이 캐릭터 뒤에 펼쳐진 것을 볼 수 있습니다.

메터리얼 생성

이제 벽돌이미지를 입히고 UV 셰이더가 적용된 메터리얼을 만들어보자

'Project' 영역에서 'Material' 이라는 폴더를 하나 만들고 그 안에 메터리얼을 생성하고 이름을 'Background' 로 수정합니다.

'Material' 폴더에 'Background' 메터리얼을 생성하였습니다.

이제 'Background' 메터리얼을 선택해서 셰이더를 변경해 줍니다.

'Standard'로 표시되어 있는 부분을 누르면 단계별로 UI -> Unlit -> Transparent 를 선택하면 됩니다.

이제 메터리얼에 사용될 텍스쳐를 선택합니다.

저는 적당히 벽돌무늬의 이미지를 구해서 사용했습니다.

wall.png
0.00MB

'wall' 이미지를 'Assets' 영역에 드래그 앤 드롭해 주고 Wrap Mode를 Repeat로 변경해 줍니다.

그리고 'Background' 메터리얼의 빨간색 영역에 'wall'을 드래그 앤 드롭해 줍니다.

이제 'Background' 메터리얼을 'Background' 이미지 안의 'Material'에 삽입해 줍니다.

'wall'이 적용된 화면을 보실 수 있습니다.

----

----

이제 테스트 코드를 작성해서 적용해 볼까요?

public class PlayGround : MonoBehaviour
{
    //캐릭터 지정
    Unit unit;
    //백그라운드 지정
    Background background;

    private void Awake()
    {
        //제일 먼저 자동으로 시작되는 함수
        //기본 정보들을 초기화 해주자
        //오브젝트가 활성화 되고 한반만 호출된다.
        //스크립트가 비활성화 되어있어도 호출된다.
        Debug.Log(gameObject.name +  " : Awake");
    }

    private void OnEnable()
    {
        //오브젝트가 활성화 될 때 마다 호출
        Debug.Log(gameObject.name + " : OnEnable");
    }

    private void Start()
    {
        //스크립트가 활성화 될때 한반만 호출된다.
        Debug.Log(gameObject.name + " : Start");

        FindBackground();

        FindUnit();
        FindUnitStartPosition();
    }
    
    private void Update()
    {
        //프레임마다 호출
        TouchScreenEvent();
    }

    private void OnDisable()
    {
        //오브젝트가 비활성화 될 때 마다 호출
        Debug.Log(gameObject.name + " : OnDisable");
    }

    private void OnDestroy()
    {
        //오브젝트가 파괴될 때 호출
    }

    void FindUnit()
    {
        //캐릭터를 찾는다
        unit = GameObject.Find("character").GetComponent<Unit>();
    }

    void FindUnitStartPosition()
    {
        //screen 의 위치와 오브젝트가 존재하는 위치는 계산되는 단위가 다르다.
        var bottomPosition = Camera.main.ScreenToWorldPoint(new Vector2(Screen.width * 0.5f, 0));

        //스크린 상의 하단 중앙의 위치를 오브젝트가 존재하는 위치로 환산하여 유닛에게 적용될 위치를 보여준다.
        Debug.Log("BottomPosition : " + bottomPosition);

        //유닛에게 적용시킨다. - 주의 할점은 z 값을 0으로 지정해 줘야 화면에 표시된다.
        unit.transform.position = new Vector3(bottomPosition.x, bottomPosition.y, 0);
    }

    void TouchScreenEvent()
    {
        //update 함수 안에서 터치 이벤트를 감지한다

        //화면을 눌렀을 때 이벤트
        if (Input.GetMouseButtonDown(0))
        {

        }

        //화면을 눌렀다가 땔때 이벤트
        if (Input.GetMouseButtonUp(0))
        {
            StartCoroutine(Jump());
        }
    }

    void FindBackground()
    {
        background = GameObject.Find("Background").GetComponent<Background>();
    }

    IEnumerator Jump()
    {
        var bottomPosition = Camera.main.ScreenToWorldPoint(new Vector2(Screen.width * 0.5f, 0));

        background.ScrollUVOffset(960, 1, Ease.OutQuad);
        unit.transform.DOMoveY(bottomPosition.y + 3, 1).SetEase(Ease.OutQuad);
        yield return new WaitForSeconds(1);
        unit.transform.DOMoveY(bottomPosition.y, 1).SetEase(Ease.InQuad);
        background.ScrollUVOffset(-960, 1, Ease.InQuad);
    }
}

이전 작업에서 만들어 두었던 'Playground'에 추가 코딩을 하였습니다.

이제 마우스를 클릭하면 배경이 스크롤 되며 상승하는듯한 연출을 볼 수 있습니다.

결과화면입니다.