Arbor2: 自分用メモ
Arbor2のメモ。
Arbor2はunityでステートマシンを使うことができるアセットです。
ステートマシンはunityのMechanimにもついている。下記参照。
<使い分け>
アニメ素材で遷移を管理したい=>Mechanim
コード+ステートマシンで管理したい。=>Arbor
使うと便利な事。
・ステート毎に分けてコードを書けるのでシンプルでわかりやすいし、バグも見つけやすい。monodevelopを継承しているのですぐ使える。
ステートの小さな歯車をクリックしてスクリプト編集を使うと、コードが見れるので参考になる。
開始ステートから接続されたステートに移る。
常駐ステートはいつでも条件が満たされたら実行する。
ーーーーーーーーーーーーー
挙動
ステートの遷移はTransitionに用意されている。
時間や距離などで遷移する事ができる。
即遷移はgotoTransition
-----------------------------------
実行順序
http://arbor.caitsithware.com/tutorial/coding/
Awake <= これが最初
OnStateAwake (一回だけ実行)
OnStateBegin
Start <= 順番注意:(一回だけ実行)
Update-----
OnStateEnd
2回めのステート実行
OnStateBegin
Update-------
OnStateEnd
----------------------------------------------------
statebehavior のコードを書くには
Project =>Create => Arbor =>StateBehavior =>C#を選択しファイルを作る。
作ったスクリプトはArborEditorで挙動追加=>scriptの中に入っている。
スクリプトでArborを使うにはusing Arbor;を宣言する。
------------------------------------------------
変数
プロパティで設定するならseriarizeかpublicしたものを使う。
他のステートでも同じ変数を使いたい場合はParameterContainerを使う。
シーンを遷移する場合も同じ変数を使いたいならglobalParameterContainer。
外部から利用例:基本の変数コマンドは用意されている。
--- set
gameObject.GetComponent<ParameterContainer>().SetFloat("damagex",9f);
---- get
int seeRange;
gameObject.GetComponent<ParameterContainer>().GetFloat("seeRange",out seeRange);
------------------------------------
ステートの移動はTransition 。stateLinkに接続先を指定。
public StateLink NextState;で指定したステートをエディタで繋ぐ。
Transition(NextState);
-------------------------------
イベントにメッセージを送るにはsendTrigger系。
受けるにはTriggerTransitionを常駐させる。
外部からステートを遷移させたいとき
gameObject.GetComponent<ArborFSM>().SendTrigger("ChangeState");
----------------------------------------
一定時間ごとに条件判定させて遷移する方法は、coroutine等があるようだ。
coroutineの参考にしたサイト:
public override void OnStateBegin() {
StartCoroutine(Loop(interval));
}
private IEnumerator Loop(float interval){
while(true){
yield return new WaitForSeconds(interval);
// if (-----) Transition(NextState);
}
public override void OnStateEnd() {
StopAllCoroutines();// ("Loop")
}
-----------------------------------------
statebehaviourから現在のステート名を見るにはstate.name;
外部から現在のステートは何か取得する場合
gameObject.GetComponent<ArborFSMInternal>().currentState.name
注意:
上記をmonoのStartから実行するとエラーが出る。
monobehaviourのStartとarborFSMのステートの実行順を理解する必要がある。
--------------------------------------------
参考ツイート
呼び出し順の話。
— caitsithware(Unity使い (@caitsithware) 2016年11月14日
Startが呼ばれるのが最初のUpdate直前ていうのが罠なんだよなぁ・・・
だから個人的にはGetComponentしなきゃいけない場合は、必要になったタイミングでGetComponentしてキャッシュを推したい
じゃあStartは何に使うかというと、Updateで使う時間経過の判定用にTime.time取っといたりカウンターの初期化とかに使う。
— caitsithware(Unity使い (@caitsithware) 2016年11月14日
あるいはStartをコルーチンにして「5秒後に死ぬ」みたいなのをサラッと書いたり。
参考にしたサイト
フォーラム:掲示板
Arbor: State Diagram Editor - Index page
-------------------------------------------------------
Linq 自分メモ
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;//これが必要
public class createItemObect_Manager : MonoBehaviour {
public ItemDatabase itemdb;
public GameObject originalItemObject;
private List<Item> AllItemList = new List<Item>();
// Use this for initialization
void Start () {
foreach (Item i in itemdb.itemDB){//
AllItemList.Add(i);
//GameObject copyObj = Instantiate(originalItemObject) as GameObject;
//copyObj.GetComponent<ItemObject>().item = i;
}
var itemList = AllItemList.Where(n => n.itemType ==Item.ItemType.Potion).ToList();
var weaponlist = AllItemList.Where(n => n.itemType ==Item.ItemType.Weapon).Select(n => n.itemAttack*2).ToList();
foreach(var n in weaponlist){
Debug.Log("attack:"+n);
}
}
}
unity fungus シーンの移動
サブルーチンのような使い方
1:呼び出し元にFlow-->Callを追加
2:呼び出すブロックを指定する。(必要に応じてflowchartやlabelを設定する)
3:Callmodeに wait until finishedを指定する。
呼び出しブロックにStopBlockを設定しとくと、そこでそのブロック処理が止まり呼び出し元に戻る。
同様にcallmodeでcontinueを使うと変数計算等のマクロのような使い方ができそう?(要検証)
callmodeにstopだとそのまま終了するようだ。(Jumpとの違いがわからん)
//--fungusにload等のcommandがあったので不要。
using UnityEngine;
using System.Collections;
using Fungus;
using UnityEngine.SceneManagement;
using UnityEditor;
[CommandInfo("Command","reload scene","reload scene")]
public class LoadScene_funguscommand : Command {
// Use this for initialization
public override void OnEnter(){
// do
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex, LoadSceneMode.Single);
// Continue();
}
}
[CommandInfo("Command","load nextScene","next scene")]
public class nextScene_funguscommand : Command {
// Use this for initialization
public override void OnEnter(){
// do
SceneManager.LoadScene((SceneManager.GetActiveScene().buildIndex+1), LoadSceneMode.Single);
Continue();
}
}
[CommandInfo("Command","goto scenename","goto scene")]
public class gotoScene_funguscommand : Command {
public string sceneName;
// Use this for initialization
public override void OnEnter(){
// do
SceneManager.LoadScene(sceneName, LoadSceneMode.Single);
//SceneManager.LoadScene(sceneName);
// Continue();
}
}
//--------
unity C# 継承とgetcomponentを調べた
unity を勉強中な素人なので記事に保証はありません。
unityでC#を勉強した覚書きを書こうかと思います。
monobehaviourを継承したオブジェクトはnewではなくgetcomponentを使用するようにメッセージがでたのでgetcomponentをテストした。
-------------------------using 省略
testA.C# monobehaviourを継承している
public class testA : MonoBehaviour {
public void attack()
{
Debug.Log("attack A");
}
}
Aを継承したBを作る
testB.C#
public class testB : testA {
public void attack()
{
Debug.Log("attackB");
}
}
●空のgameObjectのTestBを作成しtestBスクリプトをくっつける
testC.C#
public GameObject objB;
void Start () {
testB testb = objB.GetComponent<testB>();
testb.attack();
testA testab = objB.GetComponent<testB>();
testab.attack();
testA testaa = objB.GetComponent<testA>();
testaa.attack();
}
}
●空のgameObjectのTestCを作成してtestCスクリプトをくっつける。
objBにTestBおぶじぇくとを指定する。
実行結果
attackB
attackA
attackA
ちなみにtestB testba = objB.GetComponent<testA>();
testba.attack(); 型の問題でエラーになる
testB testb = objB.GetComponent<testA>() as testB;とすると通るが意味がない
------------------------
全ての結果をattackBと表示させるには?overrideとvartualを使う
testAを書き直す
public virtual void attack()
{
Debug.Log("attack A");
}
testBを書き直す
public override void attack()
{
Debug.Log("attackB");
}
結果は全てattackBと表示する。