鍓嶈█
鍦╱nity寮鍙戞父鎴忕紪杈戝櫒鎵╁睍涓紝鎴戜滑甯稿父浼氱敤鍒拌妭鐐圭紪杈戝櫒銆傝妭鐐圭紪杈戝櫒灏辨槸鐢ㄨ妭鐐瑰拰鑺傜偣杩炴帴鐨勫浘褰㈣瘽缂栬緫鍣紝姣斿unity鑷甫鐨剆hadergraph灏辨槸涓涓妭鐐圭紪杈戝櫒銆傜敤鎴烽氳繃鑺傜偣涔嬮棿鐨勬嫋鎷栨媺鎷夛紝杩炵嚎灏辫兘寰楀埌鎯宠鐨勭粨鏋溿
鍦ㄤ竴娈垫椂闂撮噷锛屾墦绠楀仛涓涓糠瀹殑鍦板浘缂栬緫鍣紝姣忎釜鍦板浘鏈変笂涓嬪乏鍙4涓棬锛屽彲浠ュ拰鍏朵粬鍦板浘杩炴帴銆備簬鏄墦绠楀紑鍙戜竴涓紪杈戝櫒锛岄氳繃鍙鍖栫殑鏂瑰紡鍘荤敓鎴愭暣涓糠瀹殑鏁版嵁銆傛煡浜嗗緢澶氱殑鑺傜偣鎻掍欢锛寈node浣滀负杞婚噺绾х殑鑺傜偣缂栬緫鍣ㄥ氨闈炲父閫傚悎鐢ㄦ潵鍋氫簩娆″紑鍙
Xnode锛https://github.com/Siccity/xNode锛夋槸寮婧愮殑杞婚噺绾х殑鑺傜偣缂栬緫鍣ㄦ彃浠躲傛墍浠ョ悊瑙e拰寮鍙戣捣鏉ラ潪甯告柟渚
鏈缁堝紑鍙戞晥鏋滃涓嬨傚彲浠ュ湪绐楀彛鍐呭垱寤鸿妭鐐癸紝璁剧疆鍥涗釜闂ㄧ殑璺宠浆鍏崇郴锛屾渶缁堢偣鍑诲鍑轰繚瀛樹负涓涓寚瀹氱殑鏁版嵁鏂囦欢
瀹夎Xnode
浠巊ithub涓嬭浇杩欎釜鎻掍欢锛岃В鍘嬪嚭鏉ユ斁鍦ˋssets鐩綍涓嬪嵆鍙
涓嶈繃杩欓噷鎴戝仛浜嗕竴鐐圭偣鏀瑰姩銆傝冭檻鍒板彧鎯宠xnode鐨勭紪杈戝櫒鍔熻兘锛屼笉鎵撶畻鎵撳寘鐨勬椂鍊欐妸xnode鐨勪唬鐮佸甫鍒版渶缁堢殑鍖呴噷闈紝鎵浠ユ妸runtime鐨勪唬鐮佸叏閮ㄦ斁鍒颁簡Editor鐩綍閲岄潰銆傝繖鏍峰氨鍙互淇濊瘉鎵撳寘鏃跺欙紝鎴戜滑娓告垙鐨勫伐绋嬫槸鍜寈node鐩镐簰鐙珛鐨勩
濡傚浘鎵绀猴紝鐜板湪宸ョ▼閲岄潰浠g爜鍏ㄩ儴鍦‥ditor涓嬮潰
瀹氫箟鍥惧拰鑺傜偣
xnode鏄潪甯歌交閲忕骇鐨勯潪甯告槗寮鍙戠殑銆傚畠鐨勬蹇靛氨鏄浘Graph锛岃妭鐐筃ode锛岀鍙ort銆傜鍙f垜浠彲浠ュ厛涓嶅叧蹇冦傚厛鏉ュ畾涔変竴涓嬪浘
[CreateAssetMenu(fileName = "mazelayer", menuName = "UmGame/鍦烘櫙/杩峰缂栬緫鍣ㄦ暟鎹")] public class MazeLayerGraph : NodeGraph
{
}
灏辨槸杩欎箞绠鍗曪紝缁ф壙涓涓婲odeGraph鍗冲彲銆
杩欓噷缁橫azeLayerGraph鍔犱簡涓涓狢reateAssetMenu鏍囩銆傝繖鏍峰氨鍙互鍦≒roject闈㈡澘涓紝閫氳繃鍙抽敭鑿滃崟鐨勬柟寮忓垱寤哄嚭杩欎釜鍥炬枃浠躲
鍒涘缓涔嬪悗锛屽氨鍙互閫氳繃鍙屽嚮杩欎釜鏂囦欢鎴栬呭湪Inspector闈㈡澘涓偣鍑籓pen鎴栬呯偣鍑籈ditGraph閮藉彲浠ユ墦寮
鎵撳紑鐨勭晫闈粈涔堥兘娌℃湁锛屽彸閿彍鍗曢噷闈篃娌′粈涔堜笢瑗
杩欐槸鍥犱负杩樻病鏈夊畾涔夎妭鐐筃ode锛屾墍浠ュ紑濮嬪畾涔変竴涓婲ode
閫夋嫨杩欎釜鑿滃崟灏卞彲浠ュ垱寤哄嚭涓涓妭鐐逛簡
浣嗘槸杩欎簺鏁版嵁涓嶆槸鎴戞兂鍦ㄥ浘涓睍绀虹殑锛屾墍浠ユ墦绠楅噸鍐欒妭鐐圭殑缁樺埗銆
Node閲嶇粯
xnode涓疄鐜癗ode閲嶇粯闈炲父绠鍗曪紝鍙绫讳技unity鍐欎竴涓狢ustomEditor灏卞彲浠ャ傚浜屾寮鍙戦潪甯稿弸濂姐
namespace Game {
[CustomNodeEditor(typeof(MazeLayerRoomNode))]
public class MazeLayerRoomNodeEditor : NodeEditor
{
public override void OnHeaderGUI()
{
var tar = (MazeLayerRoomNode)target;
var head = tar.RoomID.ToString();
if (!string.IsNullOrEmpty(tar.RoomName))
head += ":" + tar.RoomName;
EditorGUILayout.LabelField(head, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
}
public override int GetWidth()
{
return 115;
}
public Rect[] Points = new Rect[4];
public override void OnBodyGUI()
{
var tar = (MazeLayerRoomNode)target;
var width = GetWidth();
if (tar.Tex == null)
tar.Tex = AssetDatabase.LoadAssetAtPath<Texture2D>(
$"Assets/Game/Art/Map/levelmap/{tar.TerrianID}.png");
GUILayout.Label("", GUILayout.Width(width - 20), GUILayout.Height(210 / 2f));
var r = new Rect(20, 35, 150 / 2f, 210 / 2f);
if (tar.Tex != null)
EditorGUI.DrawPreviewTexture(r, tar.Tex);
else
EditorGUI.DrawRect(r, Color.white);
var height = GUILayoutUtility.GetLastRect().yMax;
EditorGUILayout.LabelField("", GUILayout.Height(height));
var rect = new Rect(0, 0, 16, 16);
foreach (var port in target.DynamicPorts)
{
var rport = port;
var strs = rport.fieldName.Split('_');
if (strs.Length != 2)
continue;
var doorid = (EmDoorID)int.Parse(strs[0]);
switch (doorid)
{
case EmDoorID.Bottom:
rect.y = height;
if (rport.IsInput)
rect.x = width / 2f + 8;
else
rect.x = width / 2f - 8 - 16;
break;
case EmDoorID.Left:
rect.x = 0;
if (rport.IsInput)
rect.y = height / 2f - 8 - 16;
else
rect.y = height / 2f + 8;
rect.y += 15;
break;
case EmDoorID.Right:
rect.x = width - 16;
if (rport.IsInput)
rect.y = height / 2f + 8;
else
rect.y = height / 2f - 8 - 16;
rect.y += 15;
break;
case EmDoorID.Top:
rect.y = 0;
if (rport.IsInput)
rect.x = width / 2f - 8 - 16;
else
rect.x = width / 2f + 8;
break;
default:
throw new ArgumentOutOfRangeException();
}
var color = rport.IsInput ? Color.red : Color.green;
NodeEditorGUILayout.DrawPortHandle(rect, Color.black, color);
portPositions[rport] = rect.center;
}
}
public override void AddContextMenuItems(GenericMenu menu)
{
base.AddContextMenuItems(menu);
var tar = (MazeLayerRoomNode)target;
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node)
{
menu.AddItem(new GUIContent("澧炲姞闂/鈫戜笂"), false, () => tar.AddDoor(EmDoorID.Top));
menu.AddItem(new GUIContent("澧炲姞闂/鈫撲笅"), false, () => tar.AddDoor(EmDoorID.Bottom));
menu.AddItem(new GUIContent("澧炲姞闂/涓婁笅"), false, () =>
{
tar.AddDoor(EmDoorID.Bottom);
tar.AddDoor(EmDoorID.Top);
});
menu.AddItem(new GUIContent("澧炲姞闂/鈫愬乏"), false, () => tar.AddDoor(EmDoorID.Left));
menu.AddItem(new GUIContent("澧炲姞闂/鈫掑彸"), false, () => tar.AddDoor(EmDoorID.Right));
menu.AddItem(new GUIContent("澧炲姞闂/宸﹀彸"), false, () =>
{
tar.AddDoor(EmDoorID.Right);
tar.AddDoor(EmDoorID.Left);
});
menu.AddItem(new GUIContent("澧炲姞闂/涓婁笅宸﹀彸"), false, () =>
{
tar.AddDoor(EmDoorID.Bottom);
tar.AddDoor(EmDoorID.Top);
tar.AddDoor(EmDoorID.Right);
tar.AddDoor(EmDoorID.Left);
});
}
}
}
}
1銆佺户鎵縉odeEditor锛屾瘮鐢–ustomNodeEditor鍜屾垜浠嚜瀹氫箟鐨凬ode鐩稿叧鑱
2銆佸鍐欎簡OnHeaderGUI锛岃鑺傜偣澶撮儴鏄剧ず鎴块棿鐨処D鍜屽悕绉帮紝杩欐牱鏌ョ湅姣旇緝鏂逛究
3銆佸鍐橤etWidth銆傚洜涓烘垜鐭ラ亾鐢荤殑鍥剧殑澶у皬锛屽叾浠栦笉鎯虫樉绀猴紝鎵浠ュ浐瀹氫负115
4銆佸鍐橭nBodyGUI銆傝繖涓槸閲嶇偣銆傚洜涓哄湪鑺傜偣鐢诲嚭鍥撅紝鎵浠ュ湪杩欎釜鍑芥暟閲岄潰锛屽厛鍘籄ssetDataBase閲岄潰鎵惧埌鍥撅紝鐒跺悗浣跨敤DrawPreviewTexture鐢诲嚭鏉ャ傛渶鍚庢垜瑕佺敾鍑洪棬鐨勫嚭鍏ュ彛锛屾墍浠ヤ娇鐢∟ode鐨凞ynamicPorts瀛樺偍闂ㄧ殑鏁版嵁銆傛渶鍚庢妸杩欎簺port鐨勪綅缃褰曞埌portPositions鏁扮粍涓紝杩欐牱鍒版椂鍊欏幓灏卞彲浠ュ幓鍋氳繛绾夸簡銆
5銆佸鍐橝ddContextMenuItems锛屽湪鑺傜偣鐨勫彸閿彍鍗曠殑鏃跺欏姞涓婁竴浜涘姩鎬佸姞闂ㄧ殑鏂规硶
濡傚浘锛屾坊鍔4涓棬涔嬪悗锛屽氨鍦ㄨ妭鐐瑰懆鍥寸敾鍑轰簡4涓叆鍙e拰4涓嚭鍙
澶氬姞鍑犱釜鑺傜偣锛岀劧鍚庤繛鎺ヨ捣鏉
杩欎釜鏇茬嚎涓嶆庝箞婊℃剰锛屾庝箞鍔炪
Graph閲嶇粯
鍦▁node涓紝涓嶄粎Node鍙互閲嶇粯锛孏raph涔熷彲浠
[CustomNodeGraphEditor(typeof(MazeLayerGraph))] public class MazeLayerGraphEditor : NodeGraphEditor {
public override NoodlePath GetNoodlePath(NodePort output, NodePort input)
{
return NoodlePath.Straight;
}
}
绫讳技鐨勶紝鎴戜滑鍙缁ф壙NodeGraphEditor锛屽苟鐢–ustomNodeGraphEditor鍜屾垜浠嚜瀹氫箟鐨凣raph鍏宠仈灏卞彲浠ヤ簡銆
涓轰簡瀹炵幇鏇茬嚎鍙樼洿绾匡紝鎴戜滑鍙澶嶅啓GetNoodlePath鍗冲彲锛孨oodlePath.Straight琛ㄧず鐩寸嚎
OK銆傞偅澶ч儴鍒嗗氨瀹屾垚浜嗐傛渶鍚庡氨鏄繚瀛樹簡銆傛垜浠湪MazeLayerGraphEditor涓殑OnGUI鍙互鍐欎竴涓猙uttom锛岀劧鍚庢妸鐩稿叧鏁版嵁鍐欏埌鑷畾涔夌殑鏁版嵁灏卞彲浠ヤ簡銆