Sfoglia il codice sorgente

加入行为树组件

tanghai 8 anni fa
parent
commit
48857e7e62

+ 133 - 0
Unity/Assets/Scripts/Component/BehaviorTreeComponent.cs

@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using UnityEngine;
+
+namespace Model
+{
+	[EntityEvent(EntityEventId.BehaviorTreeComponent)]
+	public class BehaviorTreeComponent : Component
+	{
+		private Dictionary<string, Func<NodeProto, Node>> dictionary;
+		private Dictionary<GameObject, BehaviorTree> treeCache;
+
+		public void Awake()
+		{
+			this.Load();
+		}
+
+		public void Load()
+		{
+			this.dictionary = new Dictionary<string, Func<NodeProto, Node>>();
+			this.treeCache = new Dictionary<GameObject, BehaviorTree>();
+
+		
+			Type[] types = DllHelper.GetMonoTypes();
+			foreach (Type type in types)
+			{
+				object[] attrs = type.GetCustomAttributes(typeof(NodeAttribute), false);
+				if (attrs.Length == 0)
+				{
+					continue;
+				}
+
+				Type classType = type;
+				if (this.dictionary.ContainsKey(type.Name))
+				{
+					throw new Exception($"已经存在同类节点: {classType.Name}");
+				}
+				this.dictionary.Add(type.Name, config =>
+				{
+					Node node = (Node)Activator.CreateInstance(classType, config);
+					try
+					{
+						InitFieldValue(ref node, config);
+					}
+					catch (Exception e)
+					{
+						throw new Exception($"InitFieldValue error, node: {node.Id} {node.Type}", e);
+					}
+					return node;
+				});
+			}
+			
+		}
+
+		private static void InitFieldValue(ref Node node, NodeProto nodeProto)
+		{
+			Type type = typeof(Game).Assembly.GetType("Model." + nodeProto.Name);
+
+			foreach (var args_item in nodeProto.Args.Dict())
+			{
+				FieldInfo fieldInfo = type.GetField(args_item.Key, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+				if (fieldInfo == null)
+				{
+					continue;
+				}
+				NewSetValue(ref node, fieldInfo, args_item.Value);
+			}
+		}
+
+		private static void NewSetValue(ref Node node, FieldInfo field, object value)
+		{
+			// unity enum无法序列化,保存的string形式
+			if (field.FieldType.IsEnum)
+			{
+				value = Enum.Parse(field.FieldType, (string) value);
+			}
+			field.SetValue(node, value);
+		}
+
+		private Node CreateOneNode(NodeProto proto)
+		{
+			if (!this.dictionary.ContainsKey(proto.Name))
+			{
+				throw new KeyNotFoundException($"NodeType没有定义该节点: {proto.Name}");
+			}
+			return this.dictionary[proto.Name](proto);
+		}
+
+		private Node CreateTreeNode(NodeProto proto)
+		{
+			Node node = this.CreateOneNode(proto);
+			node.EndInit(this.GetOwner<Scene>());
+
+			if (proto.Children == null)
+			{
+				return node;
+			}
+
+			foreach (NodeProto nodeProto in proto.Children)
+			{
+				Node childNode = this.CreateTreeNode(nodeProto);
+				node.AddChild(childNode);
+			}
+			return node;
+		}
+
+		public BehaviorTree CreateTree(Scene scene, GameObject treeGo)
+		{
+			try
+			{
+				BehaviorTree tree;
+				if (this.treeCache.TryGetValue(treeGo, out tree))
+				{
+					return tree;
+				}
+
+				BehaviorTreeConfig behaviorTreeConfig = treeGo.GetComponent<BehaviorTreeConfig>();
+				Node node = this.CreateTreeNode(behaviorTreeConfig.RootNodeProto);
+				tree = new BehaviorTree(scene, node);
+				if (Define.LoadResourceType == LoadResourceType.Async)
+				{
+					this.treeCache.Add(treeGo, tree);
+				}
+				return tree;
+			}
+			catch (Exception e)
+			{
+				throw new Exception($"行为树配置错误: {treeGo.name}", e);
+			}
+		}
+	}
+}

+ 12 - 0
Unity/Assets/Scripts/Component/BehaviorTreeComponent.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 71b098e198f87ba47ba6649596ee01bc
+timeCreated: 1498443309
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 20 - 24
Unity/Assets/Scripts/Component/ResourcesComponent.cs

@@ -64,34 +64,30 @@ namespace Model
 			TimerComponent timerComponent = Game.Scene.GetComponent<TimerComponent>();
 			while (true)
 			{
-				WWWAsync wwwAsync = null;
-				try
+				using (WWWAsync wwwAsync = new WWWAsync())
 				{
-					++count;
-					if (count > 1)
-					{
-						await timerComponent.WaitAsync(2000);
+					try
+					{ 
+						++count;
+						if (count > 1)
+						{
+							await timerComponent.WaitAsync(1000);
+						}
+
+						if (this.Id == 0)
+						{
+							return;
+						}
+
+						await wwwAsync.LoadFromCacheOrDownload(url, ResourcesComponent.AssetBundleManifestObject.GetAssetBundleHash(assetBundleName));
+						assetBundle = wwwAsync.www.assetBundle;
+
+						break;
 					}
-
-					if (this.Id == 0)
+					catch (Exception e)
 					{
-						return;
+						Log.Error(e.ToString());
 					}
-
-					wwwAsync = new WWWAsync();
-					
-					await wwwAsync.LoadFromCacheOrDownload(url, ResourcesComponent.AssetBundleManifestObject.GetAssetBundleHash(assetBundleName));
-					assetBundle = wwwAsync.www.assetBundle;
-					
-					break;
-				}
-				catch (Exception e)
-				{
-					Log.Error(e.ToString());
-				}
-				finally
-				{
-					wwwAsync?.Dispose();
 				}
 			}
 

+ 1 - 0
Unity/Hotfix/Init.cs

@@ -11,6 +11,7 @@ namespace Hotfix
 			{
 				Hotfix.Scene.ModelScene.AddComponent<NetOuterComponent>();
 				Hotfix.Scene.ModelScene.AddComponent<ResourcesComponent>();
+				Hotfix.Scene.ModelScene.AddComponent<BehaviorTreeComponent>();  
 				Hotfix.Scene.AddComponent<UIComponent>();
 				Hotfix.Scene.AddComponent<UnitComponent>();
 				Hotfix.Scene.GetComponent<EventComponent>().Run(EventIdType.InitSceneStart);

+ 2 - 2
Unity/Hotfix/UI/UILobby/Component/UILobbyComponent.cs

@@ -22,9 +22,9 @@ namespace Hotfix
 			Session session = null;
 			try
 			{
-				session = Game.Scene.GetComponent<NetOuterComponent>().Create("127.0.0.1:10001");
+				session = Hotfix.Scene.ModelScene.GetComponent<NetOuterComponent>().Create("127.0.0.1:10001");
 				R2C_Login r2CLogin = await session.Call<C2R_Login, R2C_Login>(new C2R_Login() { Account = "abcdef", Password = "111111" });
-				Session gateSession = Game.Scene.GetComponent<NetOuterComponent>().Create(r2CLogin.Address);
+				Session gateSession = Hotfix.Scene.ModelScene.GetComponent<NetOuterComponent>().Create(r2CLogin.Address);
 				G2C_LoginGate g2CLoginGate = await gateSession.Call<C2G_LoginGate, G2C_LoginGate>(new C2G_LoginGate(r2CLogin.Key));
 
 				Log.Info("登陆gate成功!");

+ 1 - 0
Unity/Unity.csproj

@@ -424,6 +424,7 @@
     <Compile Include="Assets\Scripts\BehaviorTree\NodePropAttribute.cs" />
     <Compile Include="Assets\Scripts\BehaviorTree\NodeProto.cs" />
     <Compile Include="Assets\Scripts\BehaviorTree\TypeHelper.cs" />
+    <Compile Include="Assets\Scripts\Component\BehaviorTreeComponent.cs" />
     <Compile Include="Assets\Scripts\Component\Config\ClientConfig.cs" />
     <Compile Include="Assets\Scripts\Component\Config\InnerConfig.cs" />
     <Compile Include="Assets\Scripts\Component\Config\OuterConfig.cs" />