unity:XNode插件的使用
XNode是一個(gè)在GitHub上的節(jié)點(diǎn)編程開源項(xiàng)目。
如果你需要讓你的功能使用數(shù)據(jù)驅(qū)動,那么節(jié)點(diǎn)編程是一個(gè)非常不錯(cuò)的選擇。
而我的這個(gè)簡紹是簡單粗暴的使用XNode輔助你快速搭建出一個(gè)能用的節(jié)點(diǎn)編輯器。
XNode具體細(xì)節(jié),還請查看https://github.com/Siccity/xNode/wiki
案列可以看XNode的案列分支https://github.com/Siccity/xNode/tree/examples
但是這個(gè)案列分支并不是特別完美,使用的是XNode自帶的GetValue接口。我并不推薦使用這個(gè)接口。因?yàn)橥ǔm?xiàng)目的復(fù)雜程序這個(gè)接口并不能很好的使用。直接硬擼就行。
一、可視化編輯的本質(zhì):實(shí)例工廠
可視化編程利用編輯器擴(kuò)展功能,將配置的信息轉(zhuǎn)換成數(shù)據(jù)文件,在unity中使用scriptObject會方便很多。使用unity編輯器擴(kuò)展功能產(chǎn)生的數(shù)據(jù),個(gè)人都比較推薦使用scriptObject。而使用外部工具產(chǎn)生的數(shù)據(jù),則推薦使用byte文件。
配置好數(shù)據(jù)后,我們?yōu)閟criptObject編寫對應(yīng)的方法,使其生成我們所需要的實(shí)例類,因此可視化編程的本質(zhì)就是實(shí)例工廠,當(dāng)然你也可以讓這個(gè)實(shí)例工廠能夠勝任更多的產(chǎn)品生產(chǎn)。
二、Xnode的使用
XNode的核心類有三個(gè):Graph、Node、Port。
其組合關(guān)系是:一個(gè)Graph擁有多個(gè)Node,而Node與Node之間通過Port相連。
1、定義Graph
? ??????我們使用XNode只能使用其最外層,Graph于是成為我們和Graph內(nèi)部節(jié)點(diǎn)溝通的渠道,為了不必要的耦合,并不建議Graph開放太多信息,只需要提供我們所需要的實(shí)例即可。
因?yàn)镚raph應(yīng)該至少具備兩個(gè)方法。1、private RootNode?GetRootNode()。該方法用于獲得其下我們所需要的指定節(jié)點(diǎn)。2、public T GetInstance()通過指定的Node獲得我們需要的實(shí)例
2、定義Node
Node節(jié)點(diǎn)提供有GetInputPort,GetPort,GetOutputPort等方法,幫助我們獲得對應(yīng)的Port。
而Port提供了Connection,GetConnections,GetConnection等方法幫助我們獲得對應(yīng)Connection。即對應(yīng)Port所連接的Port(Port為一對多的關(guān)系相連)。而每個(gè)Port.node屬性又可以幫助我們獲得其Node,因此GetPort可以幫助我們獲得產(chǎn)生鏈接的所有節(jié)點(diǎn)。獲得這些節(jié)點(diǎn)就能補(bǔ)全我們實(shí)例所缺少的信息。
比如這樣
[CreateNodeMenu("Ability/Action/CauseDamage")]
public class CauseDamageNode : SubActionNode
{
? ?[Input()] public DamagePort info;
? ?public override IAction GetAction()
? ?{
? ? ? ?
? ? ? ?var node = GetInputPort("info").Connection.node as DamageInfoNode;
? ? ? ?if (node != null)
? ? ? ?{
? ? ? ? ? ?var action = new CauseDamageAction();
? ? ? ? ? ?action.info = node.GetDamageInfo();
? ? ? ? ? ?return action;
? ? ? ?}
? ? ? ?return null;
? ?}
}
3、定義Port
Port只是用于鏈接不同Node。因?yàn)槲覀兺褂靡粋€(gè)可實(shí)例化空類(添加[Serializable],但不具備任何內(nèi)容的類)來展示即可。
比如這樣
[Serializable]
public class DamagePort
{
? ?
}