반응형
인터페이스
구현은 없고 선언만 있다
클래스가 반드시 구현해야 할 메서드와 프로퍼티를 정의한 일종의 설계도(청사진) 이다
인터페이스 정의
public interface IMoveable
{
// 프로퍼티 선언
float Speed { get; set; }
// 메서드 선언
void Move(Vector3 direction);
void Stop();
}
인터페이스 주요 특징
1. 인터페이스 이름은 보통 'I'로 시작한다
2. 메서드와 프로퍼티만 선언 가능하며, 구현부는 작성할 수 없다
3. 다중 상속이 가능하다
4. 모든 멤버는 기본적으로 public 이다
장점
1. 다중상속 가능
C#은 클래스 다중 상속이 불가능하지만, 인터페이스는 여러 개 구현이 가능하다
2. 느슨한 결합도
구체적인 구현체가 아닌 인터페이스에 의존하므로 코드 유연성이 증가한다
3. 표준화된 규약 제공
개발자 간 일관된 코드 작성이 가능하며 팀 협업이 수월해진다
4. 확장성
기존 코드 수정 없이 클래스 추가가 가능하며, 다형성을 통한 유연한 설계가 가능하다
단점
1. 추가 코드 작성 필요
정의와 구현을 위한 추가 코드가 작성이 필요하므로 작은 프로젝트에선 오버헤드가 될 수 있다
2. 복잡성 증가
과도한 인터페이스 사용은 코드 이해도를 떨어뜨리고 계층구조가 복잡해질 수 있다
3. 버전 관리의 어려움
인터페이스 수정 시 모든 구현체도 수정이 필요하다
4. 런타임 오버헤드
대부분의 경우 무시할 만한 수준이지만 메서드 직접 호출보다 약간의 성능 저하 발생
인터페이스 사용법
// 인터페이스 정의
public interface IMoveable
{
// 프로퍼티 선언
float Speed { get; set; }
// 메서드 선언
void Move(Vector3 direction);
void Stop();
}
// 인터페이스 구현 예시
public class Player : MonoBehaviour, IMoveable
{
public float Speed { get; set; }
public void Move(Vector3 direction)
{
transform.Translate(direction * Speed * Time.deltaTime);
}
public void Stop()
{
// 이동 멈추기 구현
}
}
인터페이스 사용 상황
공통 동작이 필요한 경우
데미지를 받는 모든 객체
상호작용 가능한 모든 객체
저장/로드가 필요한 모든 객체
시스템간 통신이 필요한 경우
// 체력 변경, 점수 획득 등의 이벤트를 UI, 사운드, 이펙트 등 여러 시스템에 알릴 때
public interface IObserver
{
void OnNotify(string eventType, object data);
}
교체 가능한 컴포넌트가 필요한 경우
// 무기 시스템에서 검, 총, 마법 등 다양한 무기를 쉽게 교체하고 싶을 때
public interface IWeapon
{
void Attack();
}
플러그인이나 확장 기능을 만들 때
// 일반 모드, 하드코어 모드, 연습 모드 등 게임 모드를 쉽게 추가하고 싶을 때
public interface IGameMode
{
void InitializeGame();
void EndGame();
}
활용 예시
데미지 시스템
인터페이스
// 데미지를 받을 수 있는 객체들의 인터페이스
public interface IDamageable
{
float Health { get; set; }
void TakeDamage(float damage);
bool IsAlive { get; }
}
플레이어 구현
public class Player : MonoBehaviour, IDamageable
{
public float Health { get; set; } = 100f;
public bool IsAlive => Health > 0;
public void TakeDamage(float damage)
{
Health -= damage;
if (!IsAlive) {
Die();
}
}
private void Die()
{
// 사망 처리 로직
}
}
적 구현
public class Enemy : MonoBehaviour, IDamageable
{
public float Health { get; set; } = 50f;
public bool IsAlive => Health > 0;
public void TakeDamage(float damage)
{
Health -= damage;
if (!IsAlive) {
DropItem();
Destroy(gameObject);
}
}
private void DropItem()
{
// 아이템 드롭 로직
}
}
시스템간 통신 (Observer 패턴)
인터페이스 및 Enum
// 이벤트를 구독할 수 있는 인터페이스
public interface IGameEventObserver
{
void OnNotify(GameEvent gameEvent);
}
public enum GameEvent
{
PlayerDamaged,
ScoreChanged,
GameOver
}
UI매니저
public class UIManager : MonoBehaviour, IGameEventObserver
{
public void OnNotify(GameEvent gameEvent)
{
switch (gameEvent)
{
case GameEvent.PlayerDamaged:
UpdateHealthBar();
break;
case GameEvent.ScoreChanged:
UpdateScoreDisplay();
break;
case GameEvent.GameOver:
ShowGameOverScreen();
break;
}
}
}
오디오매니저
public class AudioManager : MonoBehaviour, IGameEventObserver
{
public void OnNotify(GameEvent gameEvent)
{
switch (gameEvent)
{
case GameEvent.PlayerDamaged:
PlayDamageSound();
break;
case GameEvent.GameOver:
PlayGameOverMusic();
break;
}
}
}
무기 교체 시스템
인터페이스 및 Enum
public interface IWeapon
{
void Attack();
void Reload();
WeaponType GetWeaponType();
}
public enum WeaponType
{
Sword,
Bow,
Staff
}
검
public class Sword : MonoBehaviour, IWeapon
{
public void Attack()
{
// 근접 공격 구현
StartCoroutine(SwingAnimation());
CheckMeleeHit();
}
public void Reload()
{
// 검은 재장전이 없음
}
public WeaponType GetWeaponType() => WeaponType.Sword;
}
활
public class Bow : MonoBehaviour, IWeapon
{
[SerializeField] private int maxArrows = 10;
private int currentArrows;
public void Attack()
{
if (currentArrows > 0)
{
ShootArrow();
currentArrows--;
}
}
public void Reload()
{
currentArrows = maxArrows;
}
public WeaponType GetWeaponType() => WeaponType.Bow;
}
무기교체매니저
// 무기 교체 시스템
public class WeaponController : MonoBehaviour
{
private IWeapon currentWeapon;
public void EquipWeapon(IWeapon newWeapon)
{
currentWeapon = newWeapon;
}
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
currentWeapon?.Attack();
}
if (Input.GetButtonDown("Reload"))
{
currentWeapon?.Reload();
}
}
}
게임 모드 플러그인 시스템
인터페이스
public interface IGameMode
{
void InitializeGame();
void UpdateGameState();
void EndGame();
string GetModeName();
}
일반모드
public class NormalMode : IGameMode
{
private float playerHealth = 100f;
private int score = 0;
public void InitializeGame()
{
playerHealth = 100f;
score = 0;
// 일반 난이도 적 생성
SpawnEnemies(5);
}
public void UpdateGameState()
{
// 일반 모드 게임 로직
CheckWinCondition();
}
public void EndGame()
{
SaveScore(score);
}
public string GetModeName() => "Normal Mode";
}
하드코어 모드
public class HardcoreMode : IGameMode
{
private float playerHealth = 50f;
private int score = 0;
private float timeLimit = 300f; // 5분
public void InitializeGame()
{
playerHealth = 50f;
score = 0;
// 더 많은 적 생성
SpawnEnemies(10);
StartTimer();
}
public void UpdateGameState()
{
UpdateTimer();
CheckTimeLimit();
// 하드코어 모드 특별 규칙
ApplyHardcoreRules();
}
public void EndGame()
{
SaveHighScore(score);
UnlockAchievements();
}
public string GetModeName() => "Hardcore Mode";
}
게임모드 매니저
public class GameModeManager : MonoBehaviour
{
private IGameMode currentGameMode;
private Dictionary<string, IGameMode> availableGameModes;
private void Start()
{
availableGameModes = new Dictionary<string, IGameMode>
{
{ "normal", new NormalMode() },
{ "hardcore", new HardcoreMode() }
};
}
public void ChangeGameMode(string modeName)
{
if (availableGameModes.TryGetValue(modeName, out IGameMode newMode))
{
currentGameMode?.EndGame();
currentGameMode = newMode;
currentGameMode.InitializeGame();
}
}
private void Update()
{
currentGameMode?.UpdateGameState();
}
}반응형
'유니티 > 문법' 카테고리의 다른 글
| [Unity] 유니티 C#) 생성자 (0) | 2024.11.26 |
|---|---|
| [Unity] 유니티 C#) ref 와 out 키워드 (0) | 2024.11.25 |
| [Unity] 유니티 C#) 자료구조 스택(Stack), 큐(Queue) (5) | 2024.11.02 |
| [Unity] 유니티 C#) 자료구조 딕셔너리(Dictionary) (0) | 2024.10.28 |
| [Unity] 유니티 C#) 자료구조 배열(Array),리스트(List) (0) | 2024.10.28 |