[C#/Unity] 크기가 변화하는 오브젝트 만들기

신지한·2023년 5월 1일
0

개발노트

목록 보기
2/13

📢 개발노트에 앞서서

본 개발노트는 혼자서 유니티 게임개발 독학하는 과정에서
유용하게 사용될만한 요소들을 구현 방법과 함께 기록&공유하는 게시글이며
부족한점이 있을 수 있어 참고해서 봐주시면 감사하겠습니다

크기가 변화하는 오브젝트 만들기


🔎 개요

게임안에서 깜빡거리는 요소들과 자주 등장하는 강조기법중에
오브젝트의 크기가 커졌다 작아졌다를 반복하면서 강조하는 방법이 있다고 생각하는데
바로 전 글인 깜빡거리는 오브젝트 만들기의 코드의 원리에서 조금 수정하여
크기가 변화하는 오브젝트를 만들어 보았습니다

구현에 사용된 Sprite는 현재 개발하고있는 게임에 사용된 Sprite를 사용했습니다
저희 팀원이 디자인한거 무단으로 사용해보았습니다ㅎㅎ;

버튼을 누르면 오브젝트의 크기변화가 시작하는 기믹을 넣어보았습니다

그럼 구현 과정에 대해서 설명드리겠습니다


📝 구현과정

#1 오브젝트 생성 및 스크립트 생성

전체 생성한 오브젝트와 스크립트입니다

오브젝트: Object(Image), Button(Button), ObjectManager(Empty)
스크립트: ButtonImage, ObjectManage

ButtonImage 스크립트는 기능이랑 관련없이 버튼이미지 바꾸려고 추가한겁니다!
ObjectManage : 오브젝트 변화 기능 관련 함수가 구현되어 있습니다

UI를 작업하는거라 Canvas 상에서 구현을 했습니다

#2 ObjectManage 스크립트 구현

ObjectManage 전체코드 입니다

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

public class ObjectManage : MonoBehaviour
{
    [SerializeField]
    private GameObject Object;
    private bool check = false;

    public void SetEmphasis()
    {
        if (!check)
        {
            StartCoroutine("Emphasis", Object);
            check = true;
        }
        else
        {
            StopCoroutine("Emphasis");
            check = false;
        }
    }

    private IEnumerator Emphasis(GameObject gameObject)
    {
        float increase = 0.1f;

        while (true)
        {
            while (gameObject.GetComponent<Transform>().localScale.x > 0.5f)
            {
                gameObject.transform.localScale = new Vector3(gameObject.transform.localScale.x - increase
                                                                , gameObject.transform.localScale.y - increase
                                                                , gameObject.transform.localScale.z - increase);
                yield return new WaitForSeconds(0.05f); #크기가 바뀌는 속도
            }
            yield return new WaitForSeconds(0.05f); #중간에 멈추는 텀
            while (gameObject.GetComponent<Transform>().localScale.x < 1f)
            {
                gameObject.transform.localScale = new Vector3(gameObject.transform.localScale.x + increase
                                                                , gameObject.transform.localScale.y + increase
                                                                , gameObject.transform.localScale.z + increase);
                yield return new WaitForSeconds(0.05f); #크기가 바뀌는 속도
            }
            yield return new WaitForSeconds(0.05f); #중간에 멈추는 텀
        }
    }
}

Button을 클릭시 SetEmphasis가 호출되고 SetEmphasis에선 코루틴으로 Emphasis 함수를 실행합니다

코드가 동작하는 방법은 다음과 같습니다

  • gameObjectscale값에 접근해야하므로 Object Component중에서 Transform 특성을 참조합니다
  • 지역변수 increase는 한틱에 이미지의 scale이 변경되는 비율입니다
  • Emphasis로 전달된 gameObjecttransform.localScale 을 스크립트 상에서 조절합니다
  • 만약 gameObject의 알파값이 0.5보다 클경우 increase(0.1f)값씩 줄어들게 하였습니다
  • 만약 gameObject의 알파값이 1보다 작을경우 increase(0.1f)값씩 커지게 하였습니다
  • 코루틴을 사용하는 이유는 scale값이 시간간격을 두고 변화되는걸 구현하기 위함입니다
gameObject.transform.localScale
= new Vector3(gameObject.transform.localScale.x - increase
    		, gameObject.transform.localScale.y - increase
         	, gameObject.transform.localScale.z - increase);
  • 위와같이 transform.localScale값을 변경하는 이유는
    gameObject.GetComponent<Transform>().scale.x -= 0.1f
    이런식으로 scale값에 바로 접근할수 없기 때문입니다(다음과 같은 오류 발생)

    따라서 변경될 때 마다 새로운 객체값을 수정해줍니다
    (객체값이 맞는 표현인지 모르겠습니다..! 수정의 여지가 있다면 댓글로 알려주세요!🙇‍)

  • 값이 모두 변경되었을때 다음 동작을 실행하기까지 0.05f의 텀을 두고 무한루프를 실행합니다

  • 이미지 크기 변화 속도나 중간사이의 멈추는 텀의 간격을 줄이고싶으면
    yield return new WaitForSeconds(); 안에 파라미터 값을 조정해주시면 됩니다

#3 ObjectManager, Button에 스크립트 Component로 추가하기

ObjectManagerObjectManage 스크립트를 Add Component를 하고 Object칸에 크기가 변화될 오브젝트를 추가합니다

OnClick()ObjectManager를 추가하고 해당 스크립트의 SetEmphasis 함수를 설정합니다
OnClick()의 첫번째는 기능과 관련이 없습니다!
캡쳐화면에 오타가 있습니다! SetEmphasize -> SetEmphasis 입니다~

📌 추가적인 설명

  • 코드의 개선의 여지가 있어보입니다
    • 무한루프 안에서 먼저 실행할 while문을 조건문으로 상황에 맞게 좀더 추가할 수 있을거 같습니다
    • 원래 있던 프로젝트의 코드를 인용하느라 추가적으로 설명할 부분이 있습니다
      • 한 오브젝트에 대해서 실행할거면 파라미터로 GameObject를 전달하지 않고 전역변수로 바로 변경할 수 있습니다
      • 해당 코드처럼 구현하게 될 경우 하나의 함수로 다양한 오브젝트에 적용이 가능합니다
      • [SerializeField]private으로 하여도 유니티 프로젝트와 직렬화를 시켜 오브젝트를 추가할 수 있어 유용하게 사용할 수 있습니다
  • 뭐든지 기능을 수행하는 ~Manager를 생성해서 사용하면 편하게 구현이 가능한거 같습니다
  • 실시간으로 변화하는 속도를 조정하고 싶으시면 전역변수 설정후 WaitForSeconds값을 조절하시면 될거같습니다

이전 게시글에서 조금의 수정이 들어간 내용이므로 게시글의 양식이 거의 비슷함을 알려드립니다!

이상으로 깜빡거리는 오브젝트 구현에 대해서 포스팅 해보았습니다
궁금하신 점이 있으시거나 코드가 좀더 좋은방향으로 수정될 수 있다면
관련된 댓글 남겨주시면 감사하겠습니다!!🙇‍

profile
게임 개발자 지망생

0개의 댓글