갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • 유니티 그래프
  • C++ 소멸자
  • 자바
  • 게임매출순위
  • 게임 매출 순위
  • c# coroutine
  • 전세계게임매출순위
  • 유니티 골드그래프
  • c# collection
  • c# 코루틴
  • 알고리즘
  • 글로벌게임매출
  • 게임 디자인 패턴
  • c# Thread
  • C# 예외 처리
  • c# unboxing
  • 전세계 게임 매출
  • 강남 방탈출
  • pc게임 순위
  • pc 게임 순위
  • 모바일 게임 순위
  • 롤 골드그래프
  • C++ 상속
  • C++ virtual
  • C++
  • C# boxing
  • 2020년 게임 매출
  • 유니티 그래프 그리기
  • Unity Graph
  • c# delegate

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

컴포넌트 패턴 (Component Pattern)
프로그래밍/디자인 패턴

컴포넌트 패턴 (Component Pattern)

2020. 5. 17. 19:13
728x90
반응형

1. 컴포넌트 패턴 정의

  서로 다른 기능은 나누어 작성하여 서로간 커플링 없이 다룰 수 있게 하는 것

    => 로직을 기능별로 컴포넌트화 하는 것

 

2. 컴포넌트 패턴 사용 이유

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

enum MOVE {
    MOVE_RIGHT,
    MOVE_LEFT
}

public class AllAct : MonoBehaviour {
    GameObject player1;
    GameObject player2;
    MOVE move = MOVE.MOVE_RIGHT;
    
    void Start() {
        player1 = GameObject.Find("Player1") as GameObject;
        player2 = GameObject.Find("Player2") as GameObject;
        
        StartCoroutine("MixedAct");
    }
    
    IEnumerator MixedAct() {
        while(true) {
            player1.transform.Rotate(90.0f * Vector3.up);
            player2.transform.Rotate(90.0f * Vector3.up);
            
            if(player1.transform.position.x < -4) {
                move = MOVE.MOVE_RIGHT;
            }
            else if(player1.transform.position.x > 4) {
                move = MOVE.MOVE_LEFT;
            }
            
            if(move == MOVE.MOVE_RIGHT) {
                player1.transform.Translate(1.0f * Vector3.right, Space.World);
                player2.transform.Translate(-1.0f * Vector3.right, Space.World);
            }
            else {
                player1.transform.Translate(-1.0f * Vector3.right, Space.World);
                player2.transform.Translate(1.0f * Vector3.right, Space.World);
            }
            
            yield return new WaitForSeconds(0.5f);
        }
    }
}

 

위의 코드는 0.5초마다 회전을 하며 0.5초마다 좌우로 왔다갔다하는 동작을 하게하는 코드이다.

GameManager를 통해 움직이게 해놓았고 실행하면 아래와 같다.

문제 없이 잘 동작되는 것을 볼 수 있다.
하지만 해당 동작으로 게임을 만들어 서비스 하던 도중 요구사항이 달라졌다고 생각해보자.
지금은 회전과 이동을 0.5초 마다 동시에 하고 있는데
'회전은 0.3초마다, 이동은 두 배인 0.6초마다 하게 해달라' 라는 요구사항이 왔다고 해보자.
이렇게 짧은 코드도 막상 수정하려면 크게 뜯어 고쳐야 한다.

그래서 등장한 개념이 컴포넌트 패턴이다.
기능별로 코드를 분리시켜 놓고 동작을 할 오브젝트에 컴포넌트를 붙여 사용한다.

 

// RotateAct.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAct : MonoBehaviour {
    void Start() {
        StartCoroutine("Rotate");
    }
    
    // 회전은 0.3초마다
    IEnumerator Rotate() {
        while(true) {
            transform.Rotate(90.0f * Vector3.up);
            
            yield return new WaitForSeconds(0.3f);
        }
    }
}

 

// MoveAct.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

enum MOVE2 {
    MOVE_RIGHT,
    MOVE_LEFT
}

public class MoveAct : MonoBehaviour {
    MOVE2 move = MOVE2.MOVE_RIGHT;
    
    void Start() {
        StartCoroutine("Move");
    }
    
    // 이동은 0.6초마다
    IEnumerator Move() {
        while(true) {
            if(transform.position.x < -4) {
                move = MOVE2.MOVE_RIGHT;
            }
            else if(transform.position.x > 4) {
                move = MOVE2.MOVE_LEFT;
            }
            
            if(move == MOVE2.MOVE_RIGHT) {
                transform.Translate(1.0f * Vector3.right, Space.World);
            }
            else {
                transform.Translate(-1.0f * Vector3.right, Space.World);
            }
            
            yield return new WaitForSeconds(0.6f);
        }
    }
}

 

각 기능별로 코드를 분리해두었다.
이제 회전은 RotateAct.cs에서만 관리를 하며
이동은 MoveAct.cs에서만 관리를 하게 된다.
추후 요구사항이 다시 달라져도 대응하기 훨씬 간단해졌다.

GameManager가 사라지고 각 오브젝트에 직접 컴포넌트를 기능별로 부여했다.
동작 모습은 아래와 같이 회전은 0.3초마다, 이동은 0.6초마다 잘 동작한다.

 


 ① 유니티에선 하나하나가 컴포넌트이다.

 

 ② GameObject를 컴포넌트화 함으로써 상속의 복잡성을 피할 수 있고, 캡슐화가 촉진되는 장점이 있다.

 

 ③ 컴포넌트 패턴을 이용하여 만들고 조합하는 방식으로 기능을 추가한다.

 

 ④ 객체지향 프로그래밍에서 상속이 아니여도 기능 추가가 가능하다.

728x90
반응형

'프로그래밍 > 디자인 패턴' 카테고리의 다른 글

추상 팩토리 패턴 (Abstract Factory Pattern)  (0) 2020.05.31
팩토리 메서드 패턴 (Factory Method Pattern)  (0) 2020.05.26
심플 팩토리 패턴 (Simple Factory Pattern)  (0) 2020.05.24
스트레티지 패턴 (Strategy Pattern)  (0) 2020.05.20
싱글턴 패턴 (Singleton Pattern)  (0) 2020.05.19
    '프로그래밍/디자인 패턴' 카테고리의 다른 글
    • 팩토리 메서드 패턴 (Factory Method Pattern)
    • 심플 팩토리 패턴 (Simple Factory Pattern)
    • 스트레티지 패턴 (Strategy Pattern)
    • 싱글턴 패턴 (Singleton Pattern)
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바