플레이 영상

 

현재 개발중인 게임 특성상 Player가 여러 종류의 무기를 사용하고 무기마다 공격 방식이 다르기 때문에 전략 패턴을 활용해 구현했습니다.

 

전략 패턴을 활용하여 추후 Player의 새로운 무기가 추가되더라도 기존 로직을 크게 수정하지 않고, Class를 추가하는 방식으로 확장할 수 있어 유지보수성과 확장성 측면에서 좋을 것이라고 판단합니다.

 

Flow Chart

 

Player 관련 코드

// 각 무기 공격 전략이 따라야 하는 공통 인터페이스
public interface IPlayerAttackStrategy
{
    void Attack(PlayerWeaponController _weaponController, NewWeaponData _weaponData);
}

// PlayerWeaponController 내 전략 패턴 적용 예시
public class PlayerWeaponController : MonoBehaviour
{
    public NewWeaponData currentWeaponData;
    private IPlayerAttackStrategy currentAttackStrategy;

    private SingleShotAttackStrategy singleShotStrategy;
    private ShotgunAttackStrategy shotgunStrategy;
    private SniperAttackStrategy sniperStrategy;
    private AxeAttackStrategy axeStrategy;
    
    private float timer;
	
    // 시작 시 각 무기별 공격 전략 객체 생성
    private void Start()
    {
        ObjectPool objectPool = ObjectPool.Instance;

        singleShotStrategy = new SingleShotAttackStrategy(objectPool);
        shotgunStrategy = new ShotgunAttackStrategy(objectPool);
        sniperStrategy = new SniperAttackStrategy();
        axeStrategy = new AxeAttackStrategy();
		
        // 게임 시작 시 현재 무기에 맞는 전략 설정
        SetWeapon(currentWeaponData);
    }

    private void Update()
    {
        if (currentWeaponData == null || currentAttackStrategy == null) return;

        timer += Time.deltaTime;
		
        // 무기별 공격 주기 확인
        if (timer >= currentWeaponData.AttackInterval)
        {
            PlayerAttack();
            timer = 0f;
        }
    }

    public void PlayerAttack()
    {
        if (currentWeaponData == null || currentAttackStrategy == null) return;
		
        // 현재 착용중인 공격 전략 실행
        currentAttackStrategy.Attack(this, currentWeaponData);
    }

    public void SetWeapon(NewWeaponData _weaponData)
    {
        currentWeaponData = _weaponData;
        currentAttackStrategy = CreateStrategyByWeapon(_weaponData);
        timer = 0f;
    }

    private IPlayerAttackStrategy CreateStrategyByWeapon(NewWeaponData _weaponData)
    {
        if (_weaponData is SingleShotWeaponData) return singleShotStrategy;
        if (_weaponData is ShotgunWeaponData) return shotgunStrategy;
        if (_weaponData is SniperWeaponData) return sniperStrategy;
        if (_weaponData is AxeWeaponData) return axeStrategy;
        return null;
    }
}

 

무기 관련 코드

public class AxeAttackStrategy : IPlayerAttackStrategy
{
    public void Attack(PlayerWeaponController _weaponController, NewWeaponData _weaponData)
    {
    	// 공격 로직 구현
    }
}

public class ShotgunAttackStrategy : IPlayerAttackStrategy
{
    public void Attack(PlayerWeaponController _weaponController, NewWeaponData _weaponData)
    {
    	// 공격 로직 구현
    }
}

public class SingleShotAttackStrategy : IPlayerAttackStrategy
{
    public void Attack(PlayerWeaponController _weaponController, NewWeaponData _weaponData)
    {
    	// 공격 로직 구현
    }
}

public class SniperAttackStrategy : IPlayerAttackStrategy
{
    public void Attack(PlayerWeaponController _weaponController, NewWeaponData _weaponData)
    {
       // 공격 로직 구현
    }
}