주녘공부일지

[해피스케치] 스테이지 관리 및 제어 본문

GameDevelopment/[Unity] Project

[해피스케치] 스테이지 관리 및 제어

주녘 2024. 12. 10. 16:44

플레이 영상

해피스케치의 요청에 따라 모션 감지를 이용한 AR게임 프로토타입 모델

- 여러 가지 미니게임 스테이지를 구현하여 2명의 사용자가 대전을 하는 AR 멀티 게임

- PC버전으로 선 구현 후 채택 시 AR 멀티 게임으로 확장

 

 

스테이지 관련

스테이지 관련 클래스다이어그램

 

StageController는 Stage를 제어 및 관리

- Stage는 콘텐츠에 따라 SingleStage와 MultiStage를 상속받아서 구체화하며 스테이지를 구현

- 구체화된 스테이지 클래스는 OnReceiveStageParam 메서드로 스테이지의 정보가 변경됨을 알림

 

Stage는 스테이지 진행 상황에 대한 정보와 플레이어를 관리

- 싱글 스테이지 : 하나의 스테이지에 2명의 플레이어가 소환되어 플레이하는 환경

- 멀티 스테이지 : 동일한 스테이지 2개의 각각의 플레이어가 소환되어 플레이하는 환경

public enum EStageType
{
    SharkAvoidance,
    CollectingCandy,
    CrossingBridge,
    Max
}

public abstract class BaseStage : MonoBehaviour
{
    [field: SerializeField, ReadOnly] protected Transform playerStartPoint;
    [field: SerializeField, ReadOnly] public EStageType StageType { get; protected set; }
#if UNITY_EDITOR
    protected virtual void Reset()
    {
        playerStartPoint = Util.FindChild<Transform>(this.gameObject, "PlayerStartPoint", true);
        playerStartPoint ??= Util.Editor_InstantiateObject(this.transform).transform;
        playerStartPoint.gameObject.name = "PlayerStartPoint";
    }
#endif
    public abstract void StartStage();
    public abstract void EndStage(ETeamType winnerTeam);
}
public abstract class SingleStage : BaseStage
{
    [SerializeField, ReadOnly] protected Player leftPlayer;
    [SerializeField, ReadOnly] protected Player rightPlayer;
    public event Action<StageParam> OnLeftReceiveStageParam;
    public event Action<StageParam> OnRightReceiveStageParam;

    protected void OnLeftReceiveStageParamCallBack(StageParam stageParam)
    {
        if (Managers.Game.IsGamePlay == false)
            return;
            
        OnLeftReceiveStageParam?.Invoke(stageParam);
    }

    protected void OnRightReceiveStageParamCallBack(StageParam stageParam)
    {
        if (Managers.Game.IsGamePlay == false)
            return;

        OnRightReceiveStageParam?.Invoke(stageParam);
    }

    public virtual void SetInfo(Player leftPlayer, Player rightPlayer)
    {
        StageType = Managers.Game.GetCurrStageType();

        this.leftPlayer = leftPlayer;
        this.rightPlayer = rightPlayer;
    }

    public override void StartStage()
    {
        leftPlayer.SetInfo((int)StageType);
        rightPlayer.SetInfo((int)StageType);
    }

    public override void EndStage(ETeamType winnerTeam)
    {
        leftPlayer.OnEndStage(leftPlayer.TeamType == winnerTeam);
        rightPlayer.OnEndStage(rightPlayer.TeamType == winnerTeam);
    }

    public abstract void ConnectEvents(Action<ETeamType> onEndGameCallBack);

    public abstract Vector3 GetStartPoint(ETeamType teamType);
}
public abstract class MultiStage : BaseStage
{
    [field: SerializeField, ReadOnly] public ETeamType TeamType { get; protected set; }
    [SerializeField, ReadOnly] protected Player player;

    public event Action<StageParam> OnReceiveStageParam;

    protected void OnReceiveStageParamCallBack(StageParam stageParam)
    {
        if (Managers.Game.IsGamePlay == false)
            return;

        OnReceiveStageParam?.Invoke(stageParam);
    }

    public virtual void SetInfo(Player player)
    {
        StageType = Managers.Game.GetCurrStageType();
        this.player = player;

        TeamType = player.TeamType;
    }

    public override void StartStage()
    {
        player.SetInfo((int)StageType);
    }

    public override void EndStage(ETeamType winnerTeam)
    {
        player.OnEndStage(player.TeamType == winnerTeam);
    }

    public abstract void ConnectEvents(Action<ETeamType> onEndGameCallBack);
    public Vector3 GetStartPoint() => playerStartPoint.position;
}