개인 공부/디자인패턴

유니티 반복자 (Iterator)

smallship 2024. 7. 19. 15:26

정의

  • 컬렉션 구현 방법을 노출 시키지 않으면서 그 집합체 안에 들어있는 모든 항목에 접근할 방법을 제공하는 패턴
  • 내부 구조를 노출하지 않고 복합 객체의 원소를 순차적으로 접근 가능하게 하는 행위 패턴
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace _20240719
{
    // Iterator 인터페이스
    public interface IIterator<T>
    {
        bool HasNext();
        T Next();
    }

    // Iterable 인터페이스
    public interface IIterable<T>
    {
        IIterator<T> GetIterator();
    }

    // 구체적인 Iterable 클래스: 게임 레벨
    public class GameLevel : IIterable<GameObject>
    {
        private List<GameObject> enemies = new List<GameObject>();

        public void AddEnemy(GameObject enemy)
        {
            enemies.Add(enemy);
        }

        public IIterator<GameObject> GetIterator()
        {
            return new EnemyIterator(this);
        }

        // 구체적인 Iterator 클래스
        private class EnemyIterator : IIterator<GameObject>
        {
            private GameLevel level;
            private int index = 0;

            public EnemyIterator(GameLevel level)
            {
                this.level = level;
            }

            public bool HasNext()
            {
                return index < level.enemies.Count;
            }

            public GameObject Next()
            {
                if (HasNext())
                {
                    return level.enemies[index++];
                }

                return null;
            }
        }
    }

    // 반복자 패턴 사용 예시
    public class IteratorExample : MonoBehaviour
    {
        private GameLevel currentLevel;

        void Start()
        {
            // 게임 레벨 초기화 및 적 추가
            currentLevel = new GameLevel();
            currentLevel.AddEnemy(CreateEnemy("Enemy1"));
            currentLevel.AddEnemy(CreateEnemy("Enemy2"));
            currentLevel.AddEnemy(CreateEnemy("Enemy3"));


            // 반복자를 사용하여 모든 적에게 데미지 주기
            IIterator<GameObject> iterator = currentLevel.GetIterator();
            while (iterator.HasNext())
            {
                GameObject enemy = iterator.Next();
                DealDamage(enemy);
            }
        }

        private GameObject CreateEnemy(string name)
        {
            GameObject enemy = new GameObject(name);
            enemy.AddComponent<Enemy>();
            return enemy;
        }

        private void DealDamage(GameObject enemy)
        {
            Enemy enemyComponent = enemy.GetComponent<Enemy>();
            if (enemyComponent != null)
            {
                enemyComponent.TakeDamage(10);
                Debug.Log($"Dealt damage to {enemy.name}. Current health: {enemyComponent.Health}");
            }
        }
    }

    // 간단한 적 클래스
    public class Enemy : MonoBehaviour
    {
        public int Health { get; private set; } = 100;

        public void TakeDamage(int amount)
        {
            Health -= amount;
            if (Health <= 0)
            {
                Health = 0;
                Debug.Log($"{gameObject.name} is defeated!");
            }
        }
    }
}

 

게임 레벨 초기화 및 적 추가

  • currentLevel = new GameLevel(); 을 통해 GameLevel 인스턴스를 생성한다.
  • currentLevel.AddEnemy(CreateEnemy("Enemy1")); 과 같은 형태로 세 가지 적 (Enemy1, Enemy2, Enemy3)을 추가한다.

반복자를 사용하여 모든 적에게 데미지 주기

  • IIterator<GameObject> iterator = currentLevel.GetIterator(); 를 호출하여 GameLevel 클래스 내부에서 생성한 EnemyIterator 인스턴스를 얻는다.
  • while (iterator.HasNext()) 루프를 통해 각 적에게 데미지를 주는 과정을 진행한다.

적에게 데미지 주기

  • iterator.Next(); 를 통해 다음 적을 오고 DealDamage(enemy); 메서드를 호출하여 해당 적에게 10의 데미지를 준다.
  • 데미지가 적용된 후, Debug.Log를 통해 각 적의 이름과 현재 체력이 출력된다.

 

'개인 공부 > 디자인패턴' 카테고리의 다른 글

유니티 전략 패턴 (Strategy)  (0) 2024.07.19
유니티 중재자 (Mediator)  (0) 2024.07.19
유니티 메멘토  (1) 2024.07.19
유니티 옵저버  (1) 2024.07.19
유니티 FSM  (0) 2024.07.17