TIL(2024,07,10)최종 프로젝트 1차구현 하나씩 만들기

김보근·2024년 7월 10일

Unity

목록 보기
40/113

TIL: 스킬 시스템 구현 및 UI 업데이트

  1. 스킬 시스템 구현
    오늘 작업한 주요 내용은 Unity에서 스킬 시스템을 구현하는 것이었습니다. 두 가지 스킬 (LifeBoostSkill과 BubbleClickSkill)을 만들었고, 각각의 스킬은 발동 후 쿨타임을 가지도록 했습니다.

LifeBoostSkill: 터치 증가량의 5000배에 해당하는 생명력을 즉시 획득하고, 쿨타임이 돌아가는 스킬입니다.

BubbleClickSkill: 일정 시간 동안 버블을 자동으로 클릭하는 스킬입니다. 각 클릭마다 버블이 하나씩 사라지며, 스킬이 끝나면 쿨타임이 돌아갑니다.

  1. UI 업데이트
    스킬의 쿨타임을 사용자에게 시각적으로 표시하기 위해 텍스트와 이미지를 사용했습니다.

쿨타임 텍스트: 스킬이 쿨타임 중일 때 남은 시간을 초 단위로 표시합니다.

쿨타임 이미지: 스킬이 쿨타임 중일 때 남은 쿨타임을 시각적으로 나타냅니다.

  1. 적용된 디자인 패턴
    오늘 작업에서 몇 가지 디자인 패턴을 적용했습니다.

템플릿 메소드 패턴 (Template Method Pattern):
Skill 클래스를 추상 클래스로 정의하고, 스킬의 기본 동작을 정의했습니다. 구체적인 스킬 구현은 ApplySkillEffect 메소드에서 서브 클래스가 구현하도록 했습니다.

싱글톤 패턴 (Singleton Pattern):
LifeManager 클래스는 게임 내 생명력을 관리하는 싱글톤 패턴으로 구현되었습니다. 이 패턴은 생명력 관리 객체가 전역에서 하나만 존재하도록 보장합니다.

상태 패턴 (State Pattern):
스킬의 상태(발동 중, 쿨타임 중)를 관리하기 위해 상태 패턴을 활용했습니다. 스킬이 발동되면 onCooldown 플래그를 통해 상태를 관리하고, 쿨타임이 끝나면 다시 발동할 수 있도록 했습니다.

Skill 클래스(추상 클래스)

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

// 스킬의 기본 동작을 정의하는 추상 클래스
public abstract class Skill : MonoBehaviour
{
    public float cooldownTime = 15.0f; // 기본 쿨타임
    public Text cooldownText; // 쿨타임을 표시할 텍스트
    public Image cooldownImage; // 회전할 이미지

    protected bool onCooldown = false; // 쿨타임 상태를 나타내는 플래그
    protected float cooldownRemaining; // 남은 쿨타임 시간

    protected virtual void Start()
    {
        // 각 스킬의 지속시간과 쿨타임은 서브 클래스에서 설정됩니다.
    }

    private void Update()
    {
        // 쿨타임 중일 때 남은 시간을 감소시키고 UI를 업데이트
        if (onCooldown)
        {
            cooldownRemaining -= Time.deltaTime;
            if (cooldownRemaining < 0) cooldownRemaining = 0;

            UpdateCooldownUI(cooldownRemaining);
        }
    }

    // 스킬을 활성화하는 추상 메서드
    public abstract void ActivateSkill();

    // 스킬의 효과를 발휘하고 쿨타임을 적용하는 코루틴
    protected IEnumerator SkillEffect()
    {
        onCooldown = true;
        cooldownRemaining = cooldownTime;

        // 스킬의 구체적인 효과를 발휘
        yield return StartCoroutine(ApplySkillEffect());

        // 쿨타임이 끝날 때까지 기다림
        while (cooldownRemaining > 0)
        {
            yield return null;
        }

        onCooldown = false;
        UpdateCooldownUI(0); // 쿨타임이 끝났음을 UI에 반영
    }

    // 스킬의 구체적인 효과를 정의하는 추상 메서드
    protected abstract IEnumerator ApplySkillEffect();

    // 쿨타임 UI를 업데이트하는 메서드
    private void UpdateCooldownUI(float remaining)
    {
        if (cooldownText != null)
        {
            cooldownText.text = $"{Mathf.CeilToInt(remaining)}s";
        }

        if (cooldownImage != null)
        {
            float fillAmount = 1 - (remaining / cooldownTime);
            cooldownImage.fillAmount = fillAmount;
            
        }
    }
}

LifeBoostSkill 클래스

using System.Collections;
using UnityEngine;
using System.Numerics;

// 터치 증가량의 5000배에 해당하는 생명력을 즉시 획득하는 스킬
public class LifeBoostSkill : Skill
{
    public BigInteger skillMultiplier = 5000; // 스킬 배수

    private TouchData touchData;

    protected override void Start()
    {
        cooldownTime = 1800f; // 스킬 쿨타임 30분

        // TouchData 컴포넌트를 찾아서 참조합니다.
        touchData = FindObjectOfType<TouchData>();
        
        // 초기 UI 설정
        UpdateCooldownUI(0);
    }

    public override void ActivateSkill()
    {
        // 스킬이 쿨타임 중이 아닐 때만 활성화
        if (!onCooldown)
        {
            StartCoroutine(SkillEffect());
        }
    }

    protected override IEnumerator ApplySkillEffect()
    {
        // 터치 증가량의 5000배에 해당하는 생명력을 추가로 획득합니다.
        if (touchData != null)
        {
            BigInteger bonusLife = touchData.touchIncreaseAmount * skillMultiplier;
            LifeManager.Instance.IncreaseLife(bonusLife);
        }

        yield return null; // 즉시 완료
    }
}

BubbleClickSkill 클래스

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

// 일정 시간 동안 버블을 자동으로 클릭하는 스킬
public class BubbleClickSkill : Skill
{
    public float clickInterval = 1f; // 자동 클릭 간격

    private Queue<GameObject> bubbleQueue = new Queue<GameObject>();

    protected override void Start()
    {
        skillDuration = 300f; // 스킬 지속 시간
        cooldownTime = 1800f; // 스킬 쿨타임 30분

        // 초기 UI 설정
        UpdateCooldownUI(0);
    }

    public override void ActivateSkill()
    {
        // 스킬이 쿨타임 중이 아닐 때만 활성화
        if (!onCooldown)
        {
            StartCoroutine(SkillEffect());
        }
    }

    protected override IEnumerator ApplySkillEffect()
    {
        float elapsedTime = 0f;

        // 모든 버블을 큐에 추가
        GameObject[] bubbles = GameObject.FindGameObjectsWithTag("Bubble");
        foreach (GameObject bubble in bubbles)
        {
            bubbleQueue.Enqueue(bubble);
        }

        // 스킬 지속 시간 동안 버블을 클릭
        while (elapsedTime < skillDuration && bubbleQueue.Count > 0)
        {
            ClickNextBubble();
            yield return new WaitForSeconds(clickInterval);
            elapsedTime += clickInterval;
        }

        bubbleQueue.Clear(); // 스킬 종료 후 큐를 비움
    }

    private void ClickNextBubble()
    {
        if (bubbleQueue.Count > 0)
        {
            GameObject bubble = bubbleQueue.Dequeue();
            var heartButton = bubble.GetComponent<HeartButton>();
            if (heartButton != null)
            {
                heartButton.TouchHeartBubble();
            }
            else
            {
                Debug.LogError("HeartButton component not found on: " + bubble.name);
            }
        }
    }
}

각 스킬의 쿨타임을 표시하고, 쿨타임 동안 이미지에 반영하는 로직을 구현했으며, 템플릿 메소드 패턴, 싱글톤 패턴, 상태 패턴을 적용하여 스킬 시스템을 구성해보았습니다.

profile
게임개발자꿈나무

0개의 댓글