전략패턴 이란?
1. 전략 패턴(Strategy Pattern)은 객체 지향 디자인 패턴 중 하나이다.
2. 실행 중에 알고리즘을 선택할 수 있도록 해주는 패턴입니다.
3. 이 패턴은 알고리즘을 캡슐화하여 동적으로 변경할 수 있도록 해주며, 이를 통해 알고리즘의 동작을 변경하고 다른 알고리즘으로 교체할 수있게 만들어준다.
4. 전략 패턴은 대개 추상 클래스나 인터페이스를 정의하고, 이를 구현한 여러 가지 구체적인 전략 클래스를 만들어 사용한다.
5. 이렇게 구현된 전략 클래스는 클라이언트에서 실행 중에 선택하거나 교체할 수 있다.
전략 패턴의 활용
전략 패턴은 다양한 분야에서 활용될 수 있는데. 예를 들어, 게임 프로그래밍에서 적의 AI를 구현할 때, 전략 패턴을 사용하여 다양한 전투 전략을 캡슐화하고 실행 중에 선택할 수 있도록 할 수 있다. 또한, GUI 프로그래밍에서는 다양한 동작을 수행하는 버튼 등에 대해 전략 패턴을 적용하여 버튼을 클릭할 때마다 실행할 동작을 변경할 수 있도록 할 수 있다.
====전략 패턴의 사용예시====
먼저 구조체 클래스를 보면

총 이라는 카테고리에서 공통적으로 쓰이는 변수들을 담아주는 구조체 클래스를 만들었다.
이러면 가독성도 좋아지고 아래 건 웨폰 추상 클래스를 상속받은 클래스 들은 data변수에 접근자를 붙여 해당 필드에 접근할수 있다.
*여기서 구조체란?
정의
1. C#에서 구조체(Struct)는 값 타입(Value Type)을 정의하는 데 사용되는 데이터 형식이다.
2. 구조체는 클래스와 유사한 멤버 변수, 메서드 및 속성을 가지지만, 일반적으로 클래스보다 더 가볍고 빠르며 값 형식으로 처리된다 (스택 메모리에 저장 된다)
특징
1. 값 타입: 구조체는 값 형식이므로, 인스턴스가 생성될 때 메모리의 스택 영역에 저장됩니다. 이러한 이유로 클래스보다 더 가볍고 빠르다.
2. 상속 불가: 구조체는 상속이 불가능합니다.
3. 인터페이스 구현 가능: 구조체는 인터페이스를 구현할 수 있다.
4. 생성자: 구조체는 매개변수가 없는 생성자와 매개변수가 있는 생성자를 가질 수 있다.
5. 복사: 구조체는 값 형식이므로, 인스턴스를 복사할 때 새로운 메모리 공간을 할당한다.
이럴때 사용하면 좋다!
1. 작은 객체: 구조체는 작은 객체를 표현하는 데 유용하다.
2. 성능: 구조체는 값 형식이므로, 메모리 할당 및 삭제가 더 빠르다.
3. 상속 불가: 상속이 필요하지 않은 경우 구조체를 사용할 수 있다.
4. 인터페이스 구현: 인터페이스를 구현해야하는 경우 구조체를 사용할 수 있다.
아래는 모노 추상 클래스

스크립트를 분석해보면
우선 추상 멤버를 선언해주고 다른 클래스에서 해당 추상 클래스를 상속 받을 시 추상 멤버를 강제로 구현하게 만들어 준다. (혹은 일반 멤버를 선언해주어 구현 내용을 넣어주는 것 또한 가능하다)
위 스크립트 에서는 InitSetting 추상 멤버를 선언하고 아래에는 Using 메서드를 선언했다
여기서 Using 메서드의 경우 상속받은 다른 클래스에서 함수 사용시 재정의 할수 있도록 virtual 키워드를 사용하여 상속받은 클래스에서 오버라이드 될수 있도록 하였다. (총마다 상세한 사용 방법이 다르기 때문이다.)
*여기서 추상 클래스란?
정의
C#에서 추상 클래스(Abstract Class)는 인스턴스화할 수 없는 클래스로, 일반적으로 하나 이상의 추상 멤버를 포함한다. 추상 멤버는 구현이 없는 멤버로, 파생 클래스에서 반드시 구현해야 한다.
특징
1. 인스턴스화 불가: 추상 클래스는 인스턴스화할 수 없다.
2. 추상 멤버: 추상 클래스는 하나 이상의 추상 멤버를 가질 수 있다. 추상 멤버는 구현이 없으므로, 파생 클래스에서 반드시 구현해야 한다.
3. 일반 멤버: 추상 클래스는 일반 멤버를 가질 수 있다. 이러한 멤버는 구현이 있으며, 파생 클래스에서 재정의할 수 있다.
4. 상속: 추상 클래스는 상속을 통해 사용된다. 즉 추상 클래스를 상속받은 파생 클래스는 추상 멤버를 구현하고, 인스턴스화하여 사용할 수 있다.
이럴때 추상 클래스를 사용하자!
1. 추상적인 개념 표현: 추상 클래스는 구체적인 구현이 아닌, 추상적인 개념을 표현하기 위해 사용될 수 있다.
2. 공통 인터페이스: 추상 클래스는 공통 인터페이스를 제공하기 위해 사용될 수 있다. 예를 들어, 데이터베이스에서 다양한 종류의 데이터베이스에 대한 접근을 표현하는 인터페이스를 추상 클래스로 구현할 수 있다.
아래는 위에서 만든 추상클래스를 상속받은 DefaultGun 클래스 스크립트

여기서 InitSetting의 경우 virtual 키워드를 사용하지 않아 정의를 해주었고
아래 Using 메서드의 경우 base키워드의 접근자를 사용(부모클래스 접근) 하여 using 메서드에 인자를 넣어 사용하는 식으로 구현하였다.
아래는 위에서 만들어준 스크립트를 사용할 WeaponController 모노 스크립트

이제 위에서 만들어준 스크립트를 플레이어 오브젝트에 넣어주고 DefaultGun 클래스는 바로 넣어주는 것이 아니라 플레이어 오브젝트에 먼저 부착을 해준뒤 인스펙터 창에서 끌어다가 할당 해주면 된다.

그럼 하나의 스크립트에 절차 지향형으로 몰아 넣는게 아닌 객체 지향으로 힘들게 구현하면 장점이 무엇인가?
그건 아래를 보면 알수있다.
우선 GunWeapon 클래스를 상속받은 RifleGun 클래스 스크립트를 하나 생성한다.

이후 해당 스크립트를 같은 방식으로 인스펙터 창에서 플레이어에게 추가해주면 된다.

이런식으로 새로운 총을 만들어도 쉽게 재사용이 가능하다.
그럼 여기서 남은 문제는 플레이 도중에 총을 어떻게 바꿔줄것인가 인데
그건 아래 스크립트를 참고해보면 된다.

여러 내용이 많이 추가되긴 했는데 일단 중요한 부분은 아래 GetComponet 메서드 부분이다.
GetComponet 메서드를 사용하여 현재 플레이어에 붙어있는 스크립트를 넣어주면 된다
위 스크립트에서는 조건을 총알을 모두 소비했을떄 로 되어있는데 그렇게 하지 않고 그냥 특정 이벤트가 발생했을때 넣어주는 식으로 변경하면 된다.
아직 실제로 사용해 보진 않은 디자인 패턴인지라 직접 사용해 보면 좀더 와닿을수 있을텐데 어떤 부분에서 해당 패턴을 넣어 구현시킬지 아직 고민이다..
'프로젝트 > 건즈앤 레이첼스' 카테고리의 다른 글
| [유니티 프로젝트] 랜덤맵 + 플레이어 조작 합치기 (0) | 2023.03.28 |
|---|---|
| [유니티 프로젝트] 맵 텔레포트 카메라 이동 및 맵 외곽의 void 만들기 (0) | 2023.03.26 |
| [유니티 프로젝트] 맵 제너레이터 추가 사항 컴포넌트 꺼짐 문제 해결 (1) | 2023.03.21 |
| [유니티 프로젝트] 랜덤 생성맵 포탈 구현 (맵간의 이동) 및 미니맵 포지션 구현 (0) | 2023.03.19 |
| [유니티 프로젝트] 랜덤맵 미니맵 제작 (0) | 2023.03.18 |