Page 1 of 1

独自拡張したステートの参照を持つ方法

Posted: 2018/05/23 06:12
by esw09bisco
独自拡張したステートの参照を持つ方法

Code: Select all

public class CustomArborState : Arbor.StateBehaviour
{
}

Code: Select all

public class AnyClass : MonoBehaviour
{
    [SerializeField]
    private CustomArborState _customArborState;
}
上記の様なクラスを作成した場合に
GameObjectに適応させた AnyClass の変数 _customArborState に
Arborエディタのステートに挙動追加されている CustomArborState を
ドラッグ&ドロップ等で参照させる、という処理はできますでしょうか?

試した感じ別エディタウィンドウなので無理なのかもしれませんが
Inspector ウィンドウのアセット選択(であってますでしょうか?右端の丸いアイコンです)
で、参照を持たせることが可能でしたので、質問させていただきました。
( UnityEditor拡張上、D&Dの操作が無理なのかもしれないですが・・)

単一の参照であればこの手法で問題ないな、と思ったのですが
ステートの挙動をフレキシブルに作成し、いろいろなステートに
CustomArborStateクラスを挙動追加させた場合
2つめ以降の参照が

Code: Select all

var targetObjects = FindObjectsOfType<CustomArborState>();
等を行い何かしらの方法で対象を特定する必要がありそうだな、と感じております。

FindObjectsOfTypeでの取得方法をなるべく採用したくないので
他に手法がありましたらご教授願えますでしょうか?

よろしくお願いいたします。

Re: 独自拡張したステートの参照を持つ方法

Posted: 2018/05/23 09:38
by caitsithware
ご質問ありがとうございます。

StateBehaviourを外部から参照する方法はおっしゃる通り、現状Inspectorから参照する場合はご指摘の方法以外にありません。
このような使用方法がそもそも特殊となっていますので、
どのような策がベストかを判断するためにも、どういったことをしたいか詳細を聞いてみたいです。

補足:「ステートの参照」方法

今回の例とは若干意味がことなるかと思いますが、
Arborではステートが複数のStateBehaviourを持つため、StateBehaviourを参照するのではなくStateの参照方法についても一応補足しておきます。
  • ArborFSMの参照とステート名を持たせる。
    コード例 :

    Code: Select all

    public ArborFSM fsm;
    public string stateName;
    
  • ArborFSM.FindState(string stateName)を使用してステート名から取得。
    スクリプトリファレンス : FindState
    コード例 :

    Code: Select all

    State state = fsm.FindState(stateName);
    
  • StateからGetBehaviourなどで各StateBehaviourにアクセスできる
    スクリプトリファレンス : State
    コード例 :

    Code: Select all

    CustomArborState customState = state.GetBehaviour<CustomArborState>();
    

Re: 独自拡張したステートの参照を持つ方法

Posted: 2018/05/24 07:59
by esw09bisco
ご回答頂き有難うございます。
また補足も頂き有難うございます。大変参考になります。


> このような使用方法がそもそも特殊となっていますので、
> どのような策がベストかを判断するためにも、どういったことをしたいか詳細を聞いてみたいです。

こちらについてですが、現状は
・Arbor3のFsmでゲームの内部状態遷移を全て作成する
・Fsmへ外部の状態を通知することでステート遷移させるためにカスタマイズしたい
という制作方針で
仰る通り特殊なケースへの対応として取れる手法を模索しているという感じです。

Photon を利用する想定で
通信の状態変化をArbor内にも伝えられる様に考えておきたく
・Global Parameter Container を採用した場合、管理させる情報量が多くなりそう
・SendMessage 等の手法はあまり採用したくない
という考えから、回避策があれば、と思い質問させていただきました。

またアプリ起動時前にFsmのステートは確定しているので
・できれば静的に参照を保持してアプリを開始させたい
という考えも持っておりました。

Code: Select all

public class CustomArborState : Arbor.StateBehaviour
{
    public void OnRecieveNotification()
    {
    }
}

public class AnyClass : MonoBehaviour
{
    [SerializeField]
    private CustomArborState[] _customArborStates;

    public void SendNotification()
    {
        _customArborStates.ForEach( x => x.OnRecieveNotification() );
    }
}
参照をD&Dできると上記の様なデリゲーター的な通知を外部から与えることもできて
開発工数が抑えられそうなケースもでてくるかな、と妄想しておりました。

まだArborの持つ機能の全貌を把握できておりませんので
ご期待の返答内容となっていないかもしれませんが
1意見として実装機能候補としてご考慮頂けますと幸いです。

Re: 独自拡張したステートの参照を持つ方法

Posted: 2018/05/24 11:35
by caitsithware
なるほど。大体のやりたいことが見えてきました。

要望の一つとして、インスペクタへのD&Dを検討してみます。

現バージョンでの回避策としてですが、
StateBehaviourを直接参照するのは編集の都合上面倒なことになってしまうので、
逆の視点で、通知される側が通知する側にイベントを登録して必要なタイミングで送ってもらう、という形式が良いかと思います。

コード例:

Code: Select all

public class CustomArborState : StateBehaviour
{
	public AnyClass anyClass;

	public override void OnStateBegin()
	{
		anyClass.notificationCallback += OnRecieveNotification;
	}

	public override void OnStateEnd()
	{
		anyClass.notificationCallback -= OnRecieveNotification;
	}

	void OnRecieveNotification()
	{
	}
}

public class AnyClass : MonoBehaviour
{
	public event System.Action notificationCallback;

	public void SendNotification()
	{
		if (notificationCallback != null)
		{
			notificationCallback();
		}
	}
}
また、もしこの対処でも、OnStateBeginでは登録のタイミングが遅いなどで対応できない場合は、ステートの分け方も見直したほうが良いかもしれません。

Re: 独自拡張したステートの参照を持つ方法

Posted: 2018/06/05 22:34
by esw09bisco
> 要望の一つとして、インスペクタへのD&Dを検討してみます。
ありがとうございます。

コード例もありがとうございます。
確かに Graphics 等のコンポーネントを
StateBehaviour 側へ参照を持たせられるのを失念しておりました。

ご教授いただいた方法での実装を第一候補として実装&検証していきたいと思います。
ありがとうございました。