Page 1 of 1

現在のステートを復元する方法はありますか?

Posted: 2018/02/09 19:57
by hildsoft
グラフにいくつかのステートがある状態で、一旦ゲームを中断するときに任意のステート(中断前のステート)にしたいのですが、標準でシリアライズする方法はありますか?

開始ステート -> A <-> B
の3つのステート
・開始ステート:初期処理(終了後すぐにAに移動)
・A:通常状態
・B:特定の処理を実行している状態
があるとします。

ゲーム中にAからBに遷移したときに中断して保存した場合、
シリアライズで復元するときは、開始ステートを実行後にBの状態でゲームを再開したいのです。

Transitionを利用して開始ステートで直接Bに遷移することはできるのですが、数が増えてくるとノードを接続するのも大変なので何か方法があったら教えていただけると嬉しいです。

Re: 現在のステートを復元する方法はありますか?

Posted: 2018/02/10 00:44
by caitsithware
ご質問ありがとうございます。

ゲームを再開する時は、開始ステート→ステートBと遷移させたい、ということですね。

その場合は、次の手順で実現できるかと思います。
  • 中断時にstateMachine.currentState.nodeIDと中断しているフラグ等を保存。
  • 再開時に開始ステートで中断フラグをチェックし、
    中断ならstateMachine.Transition(保存していたnodeID)で遷移。
    中断でなければStateLinkを用いて通常遷移(ステートAに遷移)
コードにすると以下のような感じです。
(コード例についてはあくまで例であり細かな動作保証までは致しかねるため、参考程度とお考え下さい。)

Code: Select all

// どこからか中断するときに呼ばれる保存メソッド(仮にAbortStoreクラス。シングルトン的な存在)
public void Save()
{
    abortSaveFlag = true;
    currentStateID = arborFSM.currentState.nodeID;
}

// 開始ステートにアタッチする再開StateBehaviour(RestoreTransition.cs)
public class RestoreTransition : StateBehaviour
{
    // 通常遷移先
    public StateLInk normalLink;
    
    // 仮にOnStateBeginで書いていますが、適宜遷移させたいタイミングにしてください。
    public override void OnStateBegin()
    {
        if( AbortStore.instance.abortSaveFlag )
        {
            Transition(AbortStore.instance.currentStateID);
            AbortStore.instance.abortSaveFlag = false;
        }
        else
        {
            Transition(normalLink);
        }
    }
}
CalculatorSlotを使用している場合はCalculatorBranchも復元する必要があるかもしれません。
CalculatorBranchは以下のようなコードで保存/復元できます。

Code: Select all

// CalculatorBranchを保存するクラス
public class StoreCalculatorBranch
{
    public int branchID;
    public object value;

    public StoreCalculatorBranch(int id,object v)
    {
        branchID = id;
        value = v;
    }
}

// どこからか中断するときに呼ばれる保存メソッド。CalculatorBranch用
public void SaveBranch()
{
    for(int i = 0; i < arborFSM.calculatorBranchCount; ++i)
    {
        CalculatorBranch branch = arborFSM.GetCalculatorBranchFromIndex(i);
        if(branch.isUsed)
        {
            AddStoreCalculatorBranch( new StoreCalculatorBranch(branch.branchID,branch.value) );
        }
    }
}

// CalculatorBranchの復元メソッド
public void RestoreBranch()
{
    for(int i = 0; i < abortCalculatorBranchCount; ++i )
    {
        StoreCalculatorBranch storeBranch = GetStoreCalculatorBranch(i);
        CalculatorBranch branch = arborFSM.GetCalculatorBranchFromID(storeBranch.branchID);
        branch.value = storeBranch.value;
     }
}
ファイル等への保存方法につきましてはサポート外となりますので省いてあります。
valueにGameObjectやComponentが入っている場合もありますので、通常の方法では保存/復元できない点はご注意ください。

同様にParameterContainerを使用している場合も、必要に応じて保存してください。
コード例についてはあまり長くなりすぎるのもどうかと思いますので、今回は省きます。
必要であればお申し付けください。

以上となります。

Re: 現在のステートを復元する方法はありますか?

Posted: 2018/02/23 01:52
by hildsoft
ご丁寧にサンプルコードまで記載いしていただきありがとうございます。

問題解決のために十分なコードです。
サンプルコードの意図は理解できたので、環境に合うように調整して使用させていただきます。