[개발일지] 7. 점토 클릭 시 애정 얻기 & 점토 스프라이트 변경

2025. 1. 10. 18:22·유니티 프로젝트/점토게임

0. 들어가기 전에

점토를 클릭할 때 레벨에 맞는 애정을 획득할 수 있도록 했다. 점토를 클릭하다 보면 레벨업을 하는데 최고 레벨에 도달하면 점토의 모습이 동물로 변하도록 했다.

 

레벨업을 할 때마다 점토의 크기가 커지도록 하기 위해서 각 레벨에 맞게 애니메이터를 할당해주었다.

 

점토가 다 자라서 동물이 되면 스프라이트 이미지 상 움직이는 방향에 맞게 이미지를 좌우반전시켰다.

 

 


 

 

1. 스크립트

이번에 만든 스크립트는 ClayController 이고, ClayMove 스크립트에 변동사항이 생겼다.

 

1.1 ClayController 스크립트

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

public class ClayController : MonoBehaviour
{
    [Header("Clay Data")]
    public float[] loves; // 점토를 클릭했을 때 얻는 애정 수치(1~5 레벨)
    public int[] touchCnts; // 해당 요소만큼 클릭되면 레벨업
    public int clayLevel = 1; // 1레벨에서 시작(5레벨까지 있음)
    public int curTouchCnt = 0;

    [Header("Animation")]
    Animator anim; // 점토가 터치될 때 애니메이션 실행하기 위함
    public RuntimeAnimatorController[] animators;

    [Header("Sprites")]
    public Sprite clay; // 점토 모습
    public Sprite animal; // 다 자란 동물 모습


    private void Awake()
    {
        anim = GetComponent<Animator>();
    }

    // 점토가 터치되면 저절로 호출됨
    private void OnMouseDown()
    {
        Debug.Log("터치됨!");
        anim.SetTrigger("doTouch");
        GameManager.instance.GetLove(loves[clayLevel - 1]); // 레벨에 맞는 수치를 함수로 넘겨주기
        curTouchCnt++;

        // 이미 점토의 레벨이 최고 레벨에 도달했으면 밑으로 진입 안 하도록..
        if (clayLevel != 5)
        {
            if (curTouchCnt == touchCnts[clayLevel - 1])
            {
                clayLevel++; // 레벨 1 증가
                curTouchCnt = 0; // 초기화
                anim.runtimeAnimatorController = animators[clayLevel - 1]; // 레벨에 맞는 애니메이터로 바꿔주기

                if (clayLevel == 5)
                    gameObject.GetComponent<SpriteRenderer>().sprite = animal;
            }
        }
    }
}

 

1.2 ClayController 스크립트 설명

ClayController 스크립트에 대한 설명은 다음과 같다.

더보기
더보기

1. 변수

  • loves: 각 레벨마다 획득할 수 있는 애정의 수치가 다르도록 하기 위해서 선언했다.
  • touchCnts: 해당 요소만큼 클릭되면 레벨업 되도록 하기 위해 선언했다.
  • clayLevel: 현재 점토의 레벨을 나타내기 위한 변수이다.
  • curTouchCnt: 현재 레벨에서 점토를 클릭한 횟수를 나타내기 위한 변수이다.
  • anim: 점토가 터치될 때 애니메이션을 실행하도록 하기 위한 변수이다
  • animators: 각 레벨에 맞는 애니메이터를 할당해주기 위한 변수이다.
  • clay: 점토 모습 스프라이트
  • animal: 동물 모습 스프라이트
[Header("Clay Data")]
public float[] loves; // 점토를 클릭했을 때 얻는 애정 수치(1~5 레벨)
public int[] touchCnts; // 해당 요소만큼 클릭되면 레벨업
public int clayLevel = 1; // 1레벨에서 시작(5레벨까지 있음)
public int curTouchCnt = 0;

[Header("Animation")]
Animator anim; // 점토가 터치될 때 애니메이션 실행하기 위함
public RuntimeAnimatorController[] animators;

[Header("Sprites")]
public Sprite clay; // 점토 모습
public Sprite animal; // 다 자란 동물 모습

 

 

2. Awake()

anim 변수에 현재 게임 오브젝트의 Animator 컴포넌트를 할당했다.

private void Awake()
{
    anim = GetComponent<Animator>();
}

 

 

3. OnMouseDown()

이는 마우스로 게임 오브젝트를 터치했을 때 자동으로 호출되는 함수이다. 직접 호출할 필요가 없다.

 

터치 상태의 애니메이션을 실행하도록 하기 위해 anim.SetTrigger 메서드를 실행했다. 그리고 현재 점토 레벨에 맞는 애정을 얻게 하기 위해서 GetLove 메서드에 매개변수로 loves[clayLevel - 1] 값을 넣어주었다. 그 후, curTouchCnt 값을 +1 해주었다.

 

만약 점토의 레벨이 이미 최고 상태라면 더 이상 레벨업 할 수 없으므로 if (clayLevel != 5) 를 통해 걸러냈다. 만약 5레벨이 아니라면 진입할 수 있도록 했다.

 

진입하면 점토의 레벨이 1 증가하고, curTouchCnt 값은 다시 0이 되고, 게임 오브젝트의 애니메이터가 레벨에 맞는 애니메이터로 변경될 수 있도록 했다.

 

최고레벨이 되면 점토의 스프라이트를 동물 모습으로 변경해주어서 다 자랐음을 표현하도록 했다.

// 점토가 터치되면 저절로 호출됨
private void OnMouseDown()
{
    Debug.Log("터치됨!");
    anim.SetTrigger("doTouch");
    GameManager.instance.GetLove(loves[clayLevel - 1]); // 레벨에 맞는 수치를 함수로 넘겨주기
    curTouchCnt++;

    // 이미 점토의 레벨이 최고 레벨에 도달했으면 밑으로 진입 안 하도록..
    if (clayLevel != 5)
    {
        if (curTouchCnt == touchCnts[clayLevel - 1])
        {
            clayLevel++; // 레벨 1 증가
            curTouchCnt = 0; // 초기화
            anim.runtimeAnimatorController = animators[clayLevel - 1]; // 레벨에 맞는 애니메이터로 바꿔주기

            if (clayLevel == 5)
                gameObject.GetComponent<SpriteRenderer>().sprite = animal;
        }
    }
}

 

1.3 ClayMove 스크립트

using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public enum MoveDirection
{
    Minus = -1, Plus = 1, Idle = 0 
}

public class ClayMove : MonoBehaviour
{
    [Header("ClayMovement")]
    public float moveSpeed; // 움직이는 속도

    public MoveDirection moveDirX; // x 축 방향
    public MoveDirection moveDirY; // y 축 방향

    public bool isMoving; // 돌아다니는지 여부 확인
    public bool isReturning; // 중점으로 돌아가는 중인지 여부 확인

    public GameObject targetPosObj; // 중점에 있는 게임 오브젝트 할당해주기

    private Coroutine randomMoveCoroutine;

    [Header("Animation")]
    public Animator anim;


    void Start()
    {
        // 코루틴의 핸들을 저장하고 이를 통해 중단하는 것이 좋음
        randomMoveCoroutine = StartCoroutine(RandomMove());

        anim = GetComponent<Animator>();
    }

    void Update()
    {
        if (!isReturning)
        {
            // Time.deltaTime 을 곱해주는 이유는 게임 오브젝트가 순간이동 하는 것을 막기 위함.
            transform.Translate(moveSpeed * Time.deltaTime * new Vector2((int)moveDirX, (int)moveDirY));

            // x 축 이동 방향이 오른쪽이면 sprite 를 뒤집도록..
            if (moveDirX == MoveDirection.Plus)
                gameObject.GetComponent<SpriteRenderer>().flipX = true;
            else if (moveDirX == MoveDirection.Minus)
                gameObject.GetComponent<SpriteRenderer>().flipX = false;
        }

        // Idle 상태가 아니라면 walk 애니메이션 수행하도록
        if (moveDirX != 0 || moveDirY != 0)
        {
            anim.SetBool("isWalk", true);
        }
        else
        {
            anim.SetBool("isWalk", false);
        }
    }

    // 3초에 한 번씩 이동 방향 바꾸도록 하는 코루틴..
    // 코루틴은 IEnumerator 를 반환함
    private IEnumerator RandomMove()
    {
        while (true)
        {
            // 방향 랜덤으로 설정
            moveDirX = (MoveDirection)Random.Range(-1, 2);
            moveDirY = (MoveDirection)Random.Range(-1, 2);

            yield return new WaitForSeconds(3f); // 3초 동안 기다령 
        }
    }

    private IEnumerator ReturnToCenter()
    {
        isReturning = true;

        float curTime = 0f;
        float duration = 5f; // 중점으로 돌아가는 시간 5초 만큼 줄 것..

        Vector2 targetPos = targetPosObj.transform.position; // 중점에 있는 오브젝트의 위치 할당

        while (curTime < duration)
        {
            // 현재 점토의 위치가 목표 지점보다 왼쪽에 있으면 오른쪽을 보도록..
            if (targetPos.x > transform.position.x)
                gameObject.GetComponent<SpriteRenderer>().flipX = true;
            else if (targetPos.x < transform.position.x)
                gameObject.GetComponent<SpriteRenderer>().flipX = false;

            transform.position = Vector2.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime * 1.5f);
            curTime += Time.deltaTime;

            yield return null; // 다음 프레임까지 대기
        }

        isReturning = false; // 랜덤 이동 재개
        randomMoveCoroutine = StartCoroutine(RandomMove()); // 다시 시작시키기
    }


    // 콜라이더 컴포넌트를 가진 게임 오브젝트랑 부딪히면 이 함수로 진입
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (isReturning) return; // 만약 이미 돌아가고 있는 중에 또 부딪히면 걍 나가라..

        // 부딪힌 게임 오브젝트의 태그가 Target 이면 ReturnToCenter 코루틴 호출하도록
        if (collision.gameObject.CompareTag("Wall"))
        {
            // 랜덤 이동 코루틴은 중단시키기
            StopCoroutine(randomMoveCoroutine);

            // 중앙 복귀 코루틴 호출
            StartCoroutine(ReturnToCenter());
        }
    }
}

 

 

1.4 ClayMove 스크립트 변경 사항 설명

더보기
더보기

1. Update()

x 축 이동 방향이 오른쪽이면 sprite 를 뒤집도록 하는 로직을 추가했다. 점토가 다 자라서 동물이 되면 방향이 구분된다. 이때 동물이 쳐다보는 방향과 이동 방향이 다르면 이상하기 때문에 이를 위해 추가했다.

// x 축 이동 방향이 오른쪽이면 sprite 를 뒤집도록..
if (moveDirX == MoveDirection.Plus)
    gameObject.GetComponent<SpriteRenderer>().flipX = true;
else if (moveDirX == MoveDirection.Minus)
    gameObject.GetComponent<SpriteRenderer>().flipX = false;

 

 

2. ReturnToCenter()

점토가 벽에 닿아서 중앙으로 돌아갈 때 스프라이트의 방향을 조정하기 위해 추가한 구문이다. 만약 점토가 중앙보다 왼쪽에 위치한다면 오른쪽을 쳐다보도록, 오른쪽에 위치한다면 왼쪽을 쳐다보도록 했다.

// 현재 점토의 위치가 목표 지점보다 왼쪽에 있으면 오른쪽을 보도록..
if (targetPos.x > transform.position.x)
    gameObject.GetComponent<SpriteRenderer>().flipX = true;
else if (targetPos.x < transform.position.x)
    gameObject.GetComponent<SpriteRenderer>().flipX = false;

 

 


 

 

2. 결과물

 

정상적으로 작동하는 모습을 확인할 수 있다.

 

 


 

 

3. 참고자료

RuntimeAnimatorContoller 에 대해 설명해놓은 글이 있길래 가져왔다.

 

3.1 RuntimeAnimatorController

유니티 기본기 : 애니메이터(Animator) 2편. 애니메이터 기초 | by Supercent.official | Supercent Blog 슈퍼센트 블로그 | Medium

 

유니티 기본기 : 애니메이터(Animator) 2편

애니메이터 기초

medium.com

 

 

 

 

 

 

 

'유니티 프로젝트/점토게임' 카테고리의 다른 글
  • [개발일지] 9. 풀 매니저 & 점토 데이터 저장&불러오기
  • [개발일지] 8. 점토 드래그 기능
  • [개발일지] 6. 재화, 점토 판매 UI
  • [개발일지] 5. 점토 구매, 집 업그레이드, 야생 UI 버튼 & 애니메이션
dubu0721
dubu0721
dubu0721 님의 블로그 입니다.
  • dubu0721
    dubu0721 님의 블로그
    dubu0721
  • 전체
    오늘
    어제
    • 분류 전체보기 (352) N
      • 프로그래밍언어론 정리 (5)
      • 컴퓨터네트워크 정리 (5)
      • 알고리즘&자료구조 공부 (64)
        • it 취업을 위한 알고리즘 문제풀이 입문 강의 (60)
        • 학교 알고리즘 수업 (3)
        • 실전프로젝트I (0)
      • 백준 문제 (204)
        • 이분탐색 (7)
        • 투포인트 (10)
        • 그래프 (11)
        • 그리디 (24)
        • DP (25)
        • BFS (21)
        • MST (7)
        • KMP (4)
        • Dijkstra (3)
        • Disjoints Set (4)
        • Bellman-Ford (2)
        • 시뮬레이션 (3)
        • 백트래킹 (15)
        • 위상정렬 (5)
        • 자료구조 (25)
        • 기하학 (1)
        • 정렬 (11)
        • 구현 (8)
        • 재귀 (8)
        • 수학 (8)
        • 트리 (1)
      • 유니티 공부 (11)
        • 레트로의 유니티 게임 프로그래밍 에센스 (11)
        • 유니티 스터디 자료 (0)
        • C# 공부 (0)
      • 유니티 프로젝트 (48)
        • 케이크게임 (13)
        • 점토게임 (35)
      • 언리얼 공부 (10)
        • 이득우의 언리얼 프로그래밍 (10)
      • 진로 (1)
      • 논문 읽기 (2) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    골드메탈
    오블완
    백준
    유니티 공부 정리
    레트로의 유니티 프로그래밍
    재귀
    그래프
    dp
    이분탐색
    백트래킹
    이벤트 트리거
    유니티
    그리디
    투포인터
    BFS
    시뮬레이션
    언리얼
    이득우
    해시
    정렬
    우선순위큐
    유니티 프로젝트
    수학
    바킹독
    큐
    맵
    자료구조
    티스토리챌린지
    스택
    C#
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dubu0721
[개발일지] 7. 점토 클릭 시 애정 얻기 & 점토 스프라이트 변경
상단으로

티스토리툴바