提交 30b147ab 编写于 作者: T tanghai

ai框架提交,附带一个小例子,登录进游戏,角色会自动巡逻10秒,停下来攻击5秒,然后再巡逻10秒,一直循环下去

注意AIConfig表中,每个ai是一个sheet,表中可以配置多个ai
上级 172ab0c3
......@@ -404,6 +404,7 @@ II.2.12 <HandlesEvent />
<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/AutoExpandResults/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/MergeOccurences/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/OpenPreviewTabForSelectedItemInFindResults/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EdotCover_002EInteractive_002ECore_002EFilterManagement_002EMigration_002EGlobalFilterSettingsManagerMigrateSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002EDaemon_002EInlayHints_002EParameterHints_002ECppParameterNameHintsOptionsOptionsMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECSharp_002EParameterNameHints_002ECSharpParameterNameHintsOptionsMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EInlayHints_002EInlayHintsOptionsMigration/@EntryIndexedValue">True</s:Boolean>
......
e" AI_Attack
f" AI_XunLuo
" AI_XunLuo
\ No newline at end of file
文件已添加
......@@ -64,20 +64,25 @@ message M2C_CreateUnits // IActorMessage
{
int32 RpcId = 90;
int64 ActorId = 93;
repeated UnitInfo Units = 1;
repeated UnitInfo Units = 2;
}
message C2M_PathfindingResult // IActorLocationMessage
{
int32 RpcId = 90;
int64 ActorId = 93;
int64 Id = 94;
float X = 1;
float Y = 2;
float Z = 3;
}
message C2M_Stop // IActorLocationMessage
{
int32 RpcId = 90;
int64 ActorId = 93;
}
message M2C_PathfindingResult // IActorMessage
{
int64 ActorId = 93;
......
......@@ -10,7 +10,7 @@ namespace ET
{
Vector3 target = new Vector3(message.X, message.Y, message.Z);
MoveHelper.FindPathMoveToAsync(unit, target).Coroutine();
unit.FindPathMoveToAsync(target).Coroutine();
await ETTask.CompletedTask;
}
......
using System.Collections.Generic;
using UnityEngine;
namespace ET
{
[ActorMessageHandler]
public class C2M_StopHandler : AMActorLocationHandler<Unit, C2M_Stop>
{
protected override async ETTask Run(Unit unit, C2M_Stop message)
{
unit.Stop(0);
await ETTask.CompletedTask;
}
}
}
\ No newline at end of file
......@@ -9,43 +9,48 @@ namespace ET
public static async ETTask FindPathMoveToAsync(this Unit unit, Vector3 target, ETCancellationToken cancellationToken = null)
{
float speed = unit.GetComponent<NumericComponent>().GetAsFloat(NumericType.Speed);
if (speed < 0.001)
if (speed < 0.01)
{
unit.SendStop(-1);
return;
}
using var list = ListComponent<Vector3>.Create();
using (var list = ListComponent<Vector3>.Create())
{
unit.Domain.GetComponent<RecastPathComponent>().SearchPath(10001, unit.Position, target, list.List);
unit.Domain.GetComponent<RecastPathComponent>().SearchPath(10001, unit.Position, target, list.List);
List<Vector3> path = list.List;
if (path.Count < 2)
{
unit.SendStop(-2);
return;
}
List<Vector3> path = list.List;
if (path.Count < 2)
{
unit.SendStop(0);
return;
}
// 广播寻路路径
M2C_PathfindingResult m2CPathfindingResult = new M2C_PathfindingResult();
m2CPathfindingResult.Id = unit.Id;
for (int i = 0; i < list.List.Count; ++i)
{
Vector3 vector3 = list.List[i];
m2CPathfindingResult.Xs.Add(vector3.x);
m2CPathfindingResult.Ys.Add(vector3.y);
m2CPathfindingResult.Zs.Add(vector3.z);
}
MessageHelper.Broadcast(unit, m2CPathfindingResult);
// 广播寻路路径
M2C_PathfindingResult m2CPathfindingResult = new M2C_PathfindingResult();
m2CPathfindingResult.Id = unit.Id;
for (int i = 0; i < list.List.Count; ++i)
{
Vector3 vector3 = list.List[i];
m2CPathfindingResult.Xs.Add(vector3.x);
m2CPathfindingResult.Ys.Add(vector3.y);
m2CPathfindingResult.Zs.Add(vector3.z);
}
MessageHelper.Broadcast(unit, m2CPathfindingResult);
bool ret = await unit.GetComponent<MoveComponent>().MoveToAsync(path, speed);
if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop
{
unit.SendStop(0);
}
bool ret = await unit.GetComponent<MoveComponent>().MoveToAsync(path, speed);
if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop
{
unit.SendStop(0);
}
}
public static void Stop(this Unit unit, int error)
{
unit.GetComponent<MoveComponent>().Stop();
unit.SendStop(error);
}
public static void SendStop(this Unit unit, int error)
{
MessageHelper.Broadcast(unit, new M2C_Stop()
......
......@@ -47,8 +47,10 @@
<Compile Include="..\..\Unity\Assets\Hotfix\Module\Numeric\NumericWatcher_Hp_ShowUI.cs">
<Link>Module\Numeric\NumericWatcher_Hp_ShowUI.cs</Link>
</Compile>
<EmbeddedResource Remove="Other\**" />
<None Remove="Other\**" />
<Compile Include="..\..\Unity\Assets\Hotfix\Module\AI\**\*.cs">
<Link>Module\AI\%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Server.Model.csproj" />
......
using System;
using System.Collections.Generic;
using MongoDB.Bson.Serialization.Attributes;
using ProtoBuf;
namespace ET
{
[ProtoContract]
[Config]
public partial class AIConfigCategory : ProtoObject
{
public static AIConfigCategory Instance;
[ProtoIgnore]
[BsonIgnore]
private Dictionary<int, AIConfig> dict = new Dictionary<int, AIConfig>();
[BsonElement]
[ProtoMember(1)]
private List<AIConfig> list = new List<AIConfig>();
public AIConfigCategory()
{
Instance = this;
}
[ProtoAfterDeserialization]
public void AfterDeserialization()
{
foreach (AIConfig config in list)
{
this.dict.Add(config.Id, config);
}
list.Clear();
this.EndInit();
}
public AIConfig Get(int id)
{
this.dict.TryGetValue(id, out AIConfig item);
if (item == null)
{
throw new Exception($"配置找不到,配置表名: {nameof (AIConfig)},配置id: {id}");
}
return item;
}
public bool Contain(int id)
{
return this.dict.ContainsKey(id);
}
public Dictionary<int, AIConfig> GetAll()
{
return this.dict;
}
public AIConfig GetOne()
{
if (this.dict == null || this.dict.Count <= 0)
{
return null;
}
return this.dict.Values.GetEnumerator().Current;
}
}
[ProtoContract]
public partial class AIConfig: ProtoObject, IConfig
{
[ProtoMember(1, IsRequired = true)]
public int Id { get; set; }
[ProtoMember(2, IsRequired = true)]
public int AIConfigId { get; set; }
[ProtoMember(3, IsRequired = true)]
public int Order { get; set; }
[ProtoMember(4, IsRequired = true)]
public string Name { get; set; }
[ProtoMember(5, IsRequired = true)]
public int[] NodeParams { get; set; }
[ProtoAfterDeserialization]
public void AfterDeserialization()
{
this.EndInit();
}
}
}
......@@ -140,7 +140,7 @@ namespace ET
[ProtoMember(93)]
public long ActorId { get; set; }
[ProtoMember(1)]
[ProtoMember(2)]
public List<UnitInfo> Units = new List<UnitInfo>();
}
......@@ -155,9 +155,6 @@ namespace ET
[ProtoMember(93)]
public long ActorId { get; set; }
[ProtoMember(94)]
public long Id { get; set; }
[ProtoMember(1)]
public float X { get; set; }
......@@ -169,6 +166,18 @@ namespace ET
}
[Message(OuterOpcode.C2M_Stop)]
[ProtoContract]
public partial class C2M_Stop: Object, IActorLocationMessage
{
[ProtoMember(90)]
public int RpcId { get; set; }
[ProtoMember(93)]
public long ActorId { get; set; }
}
[Message(OuterOpcode.M2C_PathfindingResult)]
[ProtoContract]
public partial class M2C_PathfindingResult: Object, IActorMessage
......
......@@ -11,22 +11,23 @@ namespace ET
public const ushort UnitInfo = 20007;
public const ushort M2C_CreateUnits = 20008;
public const ushort C2M_PathfindingResult = 20009;
public const ushort M2C_PathfindingResult = 20010;
public const ushort M2C_Stop = 20011;
public const ushort C2G_Ping = 20012;
public const ushort G2C_Ping = 20013;
public const ushort G2C_Test = 20014;
public const ushort C2M_Reload = 20015;
public const ushort M2C_Reload = 20016;
public const ushort C2R_Login = 20017;
public const ushort R2C_Login = 20018;
public const ushort C2G_LoginGate = 20019;
public const ushort G2C_LoginGate = 20020;
public const ushort G2C_TestHotfixMessage = 20021;
public const ushort C2M_TestActorRequest = 20022;
public const ushort M2C_TestActorResponse = 20023;
public const ushort PlayerInfo = 20024;
public const ushort C2G_PlayerInfo = 20025;
public const ushort G2C_PlayerInfo = 20026;
public const ushort C2M_Stop = 20010;
public const ushort M2C_PathfindingResult = 20011;
public const ushort M2C_Stop = 20012;
public const ushort C2G_Ping = 20013;
public const ushort G2C_Ping = 20014;
public const ushort G2C_Test = 20015;
public const ushort C2M_Reload = 20016;
public const ushort M2C_Reload = 20017;
public const ushort C2R_Login = 20018;
public const ushort R2C_Login = 20019;
public const ushort C2G_LoginGate = 20020;
public const ushort G2C_LoginGate = 20021;
public const ushort G2C_TestHotfixMessage = 20022;
public const ushort C2M_TestActorRequest = 20023;
public const ushort M2C_TestActorResponse = 20024;
public const ushort PlayerInfo = 20025;
public const ushort C2G_PlayerInfo = 20026;
public const ushort G2C_PlayerInfo = 20027;
}
}
......@@ -37,6 +37,10 @@
<Compile Include="..\..\Unity\Assets\Model\Module\Config\**\*.cs">
<Link>Module\Config\%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Module\AI\**\*.cs">
<Link>Module\AI\%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Remove="Libs\**" />
......
......@@ -14,12 +14,6 @@ namespace ET
{
}
[ProtoAfterDeserialization]
public virtual void AfterDeserialization()
{
this.EndInit();
}
public virtual void EndInit()
{
}
......
e" AI_Attack
f" AI_XunLuo
" AI_XunLuo
\ No newline at end of file
fileFormatVersion: 2
guid: 277d58db3067742a7b32f9994984b3bc
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 0c430df865ee84f2f9348d817d6596a9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace ET
{
public class AI_Attack: AAIHandler
{
public override int Check(AIComponent aiComponent, AIConfig aiConfig)
{
long sec = TimeHelper.ClientNow() / 1000 % 15;
if (sec >= 10)
{
return 0;
}
return 1;
}
public override async ETVoid Execute(AIComponent aiComponent, AIConfig aiConfig, ETCancellationToken cancellationToken)
{
Scene zoneScene = aiComponent.DomainScene();
Unit myUnit = zoneScene.GetComponent<UnitComponent>().MyUnit;
if (myUnit == null)
{
return;
}
// 停在当前位置
zoneScene.GetComponent<SessionComponent>().Session.Send(new C2M_Stop());
Log.Debug("开始攻击");
for (int i = 0; i < 100000; ++i)
{
Log.Debug($"攻击: {i}次");
// 因为协程可能被中断,任何协程都要传入cancellationToken,判断如果是中断则要返回
bool timeRet = await TimerComponent.Instance.WaitAsync(1000, cancellationToken);
if (!timeRet)
{
return;
}
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 0b11fc1dea7c44643a27b53e790e9a1c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace ET
{
public class AI_XunLuo: AAIHandler
{
public override int Check(AIComponent aiComponent, AIConfig aiConfig)
{
long sec = TimeHelper.ClientNow() / 1000 % 15;
if (sec < 10)
{
return 0;
}
return 1;
}
public override async ETVoid Execute(AIComponent aiComponent, AIConfig aiConfig, ETCancellationToken cancellationToken)
{
Scene zoneScene = aiComponent.DomainScene();
Unit myUnit = zoneScene.GetComponent<UnitComponent>().MyUnit;
if (myUnit == null)
{
return;
}
Log.Debug("开始巡逻");
while (true)
{
XunLuoPathComponent xunLuoPathComponent = myUnit.GetComponent<XunLuoPathComponent>();
Vector3 nextTarget = xunLuoPathComponent.GetCurrent();
int ret = await myUnit.MoveToAsync(nextTarget, cancellationToken);
if (ret != 0)
{
return;
}
xunLuoPathComponent.MoveNext();
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: dd174eb9071c649bfba0b572fa58f130
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace ET
{
public static class XunLuoPathComponentSystem
{
public static Vector3 GetCurrent(this XunLuoPathComponent self)
{
return self.path[self.Index];
}
public static void MoveNext(this XunLuoPathComponent self)
{
self.Index = ++self.Index % self.path.Length;
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: cbebec6c70d61475b889cc1a0fe80d6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -10,6 +10,10 @@ namespace ET
try
{
G2C_EnterMap g2CEnterMap = await zoneScene.GetComponent<SessionComponent>().Session.Call(new C2G_EnterMap()) as G2C_EnterMap;
UnitComponent unitComponent = zoneScene.GetComponent<UnitComponent>();
unitComponent.MyUnit = unitComponent.Get(g2CEnterMap.UnitId);
Game.EventSystem.Publish(new EventType.EnterMapFinish() {ZoneScene = zoneScene}).Coroutine();
}
catch (Exception e)
......
......@@ -8,7 +8,7 @@ namespace ET
// 可以多次调用,多次调用的话会取消上一次的协程
public static async ETTask<int> MoveToAsync(this Unit unit, Vector3 targetPos, ETCancellationToken cancellationToken = null)
{
C2M_PathfindingResult msg = new C2M_PathfindingResult();
C2M_PathfindingResult msg = new C2M_PathfindingResult() {X = targetPos.x, Y = targetPos.y, Z = targetPos.z};
unit.Domain.GetComponent<SessionComponent>().Session.Send(msg);
ObjectWait objectWait = unit.GetComponent<ObjectWait>();
......@@ -17,7 +17,7 @@ namespace ET
objectWait.Notify(new WaitType.Wait_UnitStop() { Error = WaitTypeError.Cancel });
// 一直等到unit发送stop
WaitType.Wait_UnitStop waitUnitStop = await objectWait.Wait<WaitType.Wait_UnitStop>();
WaitType.Wait_UnitStop waitUnitStop = await objectWait.Wait<WaitType.Wait_UnitStop>(cancellationToken);
return waitUnitStop.Error;
}
}
......
......@@ -16,6 +16,10 @@ namespace ET
numericComponent.Set((NumericType)unitInfo.Ks[i], unitInfo.Vs[i]);
}
unit.AddComponent<ObjectWait>();
unit.AddComponent<XunLuoPathComponent>();
UnitComponent unitComponent = domain.GetComponent<UnitComponent>();
unitComponent.Add(unit);
......
fileFormatVersion: 2
guid: 490f7b30b1f804e9882ec3deb25b6013
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using UnityEngine;
namespace ET
{
[ObjectSystem]
public class AIComponentAwakeSystem: AwakeSystem<AIComponent, int>
{
public override void Awake(AIComponent self, int aiConfigId)
{
self.AIConfigId = aiConfigId;
self.Timer = TimerComponent.Instance.NewRepeatedTimer(1000, self.Check);
}
}
[ObjectSystem]
public class AIComponentDestroySystem: DestroySystem<AIComponent>
{
public override void Destroy(AIComponent self)
{
TimerComponent.Instance.Remove(ref self.Timer);
self.CancellationToken?.Cancel();
self.CancellationToken = null;
self.Current = 0;
}
}
public static class AIComponentSystem
{
public static void Check(this AIComponent self)
{
if (self.Parent == null)
{
TimerComponent.Instance.Remove(ref self.Timer);
return;
}
var oneAI = AIConfigCategory.Instance.AIConfigs[self.AIConfigId];
foreach (AIConfig aiConfig in oneAI.Values)
{
AIDispatcherComponent.Instance.AIHandlers.TryGetValue(aiConfig.Name, out AAIHandler aaiHandler);
if (aaiHandler == null)
{
Log.Error($"not found aihandler: {aiConfig.Name}");
continue;
}
int ret = aaiHandler.Check(self, aiConfig);
if (ret != 0)
{
continue;
}
if (self.Current == aiConfig.Id)
{
break;
}
self.Cancel(); // 取消之前的行为
ETCancellationToken cancellationToken = new ETCancellationToken();
self.CancellationToken = cancellationToken;
self.Current = aiConfig.Id;
aaiHandler.Execute(self, aiConfig, cancellationToken).Coroutine();
return;
}
}
private static void Cancel(this AIComponent self)
{
self.CancellationToken?.Cancel();
self.Current = 0;
self.CancellationToken = null;
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: e782e22b472a243e99f82c93f1b191da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ET
{
[ObjectSystem]
public class AIDispatcherComponentAwakeSystem: AwakeSystem<AIDispatcherComponent>
{
public override void Awake(AIDispatcherComponent self)
{
AIDispatcherComponent.Instance = self;
self.Load();
}
}
[ObjectSystem]
public class AIDispatcherComponentLoadSystem: LoadSystem<AIDispatcherComponent>
{
public override void Load(AIDispatcherComponent self)
{
self.Load();
}
}
[ObjectSystem]
public class AIDispatcherComponentDestroySystem: DestroySystem<AIDispatcherComponent>
{
public override void Destroy(AIDispatcherComponent self)
{
self.AIHandlers.Clear();
AIDispatcherComponent.Instance = null;
}
}
public static class AIDispatcherComponentSystem
{
public static void Load(this AIDispatcherComponent self)
{
self.AIHandlers.Clear();
var types = Game.EventSystem.GetTypes(typeof (AIHandlerAttribute));
foreach (Type type in types)
{
AAIHandler aaiHandler = Activator.CreateInstance(type) as AAIHandler;
if (aaiHandler == null)
{
Log.Error($"robot ai is not AAIHandler: {type.Name}");
continue;
}
self.AIHandlers.Add(type.Name, aaiHandler);
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 4e4f1a7d7c4df49d88b56711a37c25d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -24,6 +24,8 @@ namespace ET
Game.Scene.AddComponent<GlobalComponent>();
Game.Scene.AddComponent<AIDispatcherComponent>();
ResourcesComponent.Instance.LoadBundle("unit.unity3d");
Scene zoneScene = await SceneFactory.CreateZoneScene(1, "Process");
......
......@@ -34,25 +34,8 @@ namespace ET
self.frameClickMap.Y = self.ClickPoint.y;
self.frameClickMap.Z = self.ClickPoint.z;
self.DomainScene().GetComponent<SessionComponent>().Session.Send(self.frameClickMap);
// 测试actor rpc消息
self.TestActor().Coroutine();
}
}
}
public static async ETVoid TestActor(this OperaComponent self)
{
try
{
M2C_TestActorResponse response = (M2C_TestActorResponse)await self.Domain.GetComponent<SessionComponent>().Session.Call(
new C2M_TestActorRequest() { Info = "actor rpc request" });
Log.Info(response.Info);
}
catch (Exception e)
{
Log.Error(e);
}
}
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ namespace ET
zoneScene.AddComponent<ZoneSceneFlagComponent>();
zoneScene.AddComponent<NetKcpComponent>();
zoneScene.AddComponent<UnitComponent>();
zoneScene.AddComponent<AIComponent, int>(1);
// UI层的初始化
await Game.EventSystem.Publish(new EventType.AfterCreateZoneScene() {ZoneScene = zoneScene});
......
......@@ -53,7 +53,7 @@ namespace ET
}
#endif
}
public override string ToString()
{
return JsonHelper.ToJson(this);
......
fileFormatVersion: 2
guid: bc7b2c776a049435694c2242436e6183
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace ET
{
public class XunLuoPathComponent: Entity
{
public Vector3[] path = new Vector3[] { new Vector3(0, 0, 0), new Vector3(20, 0, 0), new Vector3(20, 0, 20), new Vector3(0, 0, 20), };
public int Index;
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 8bde98272f7b14c46bfc11f5072d4e9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using MongoDB.Bson.Serialization.Attributes;
using ProtoBuf;
namespace ET
{
[ProtoContract]
[Config]
public partial class AIConfigCategory : ProtoObject
{
public static AIConfigCategory Instance;
[ProtoIgnore]
[BsonIgnore]
private Dictionary<int, AIConfig> dict = new Dictionary<int, AIConfig>();
[BsonElement]
[ProtoMember(1)]
private List<AIConfig> list = new List<AIConfig>();
public AIConfigCategory()
{
Instance = this;
}
[ProtoAfterDeserialization]
public void AfterDeserialization()
{
foreach (AIConfig config in list)
{
this.dict.Add(config.Id, config);
}
list.Clear();
this.EndInit();
}
public AIConfig Get(int id)
{
this.dict.TryGetValue(id, out AIConfig item);
if (item == null)
{
throw new Exception($"配置找不到,配置表名: {nameof (AIConfig)},配置id: {id}");
}
return item;
}
public bool Contain(int id)
{
return this.dict.ContainsKey(id);
}
public Dictionary<int, AIConfig> GetAll()
{
return this.dict;
}
public AIConfig GetOne()
{
if (this.dict == null || this.dict.Count <= 0)
{
return null;
}
return this.dict.Values.GetEnumerator().Current;
}
}
[ProtoContract]
public partial class AIConfig: ProtoObject, IConfig
{
[ProtoMember(1, IsRequired = true)]
public int Id { get; set; }
[ProtoMember(2, IsRequired = true)]
public int AIConfigId { get; set; }
[ProtoMember(3, IsRequired = true)]
public int Order { get; set; }
[ProtoMember(4, IsRequired = true)]
public string Name { get; set; }
[ProtoMember(5, IsRequired = true)]
public int[] NodeParams { get; set; }
[ProtoAfterDeserialization]
public void AfterDeserialization()
{
this.EndInit();
}
}
}
fileFormatVersion: 2
guid: 43cfda55a06294993bc33c15d1062d6f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -140,7 +140,7 @@ namespace ET
[ProtoMember(93)]
public long ActorId { get; set; }
[ProtoMember(1)]
[ProtoMember(2)]
public List<UnitInfo> Units = new List<UnitInfo>();
}
......@@ -155,9 +155,6 @@ namespace ET
[ProtoMember(93)]
public long ActorId { get; set; }
[ProtoMember(94)]
public long Id { get; set; }
[ProtoMember(1)]
public float X { get; set; }
......@@ -169,6 +166,18 @@ namespace ET
}
[Message(OuterOpcode.C2M_Stop)]
[ProtoContract]
public partial class C2M_Stop: Object, IActorLocationMessage
{
[ProtoMember(90)]
public int RpcId { get; set; }
[ProtoMember(93)]
public long ActorId { get; set; }
}
[Message(OuterOpcode.M2C_PathfindingResult)]
[ProtoContract]
public partial class M2C_PathfindingResult: Object, IActorMessage
......
......@@ -11,22 +11,23 @@ namespace ET
public const ushort UnitInfo = 20007;
public const ushort M2C_CreateUnits = 20008;
public const ushort C2M_PathfindingResult = 20009;
public const ushort M2C_PathfindingResult = 20010;
public const ushort M2C_Stop = 20011;
public const ushort C2G_Ping = 20012;
public const ushort G2C_Ping = 20013;
public const ushort G2C_Test = 20014;
public const ushort C2M_Reload = 20015;
public const ushort M2C_Reload = 20016;
public const ushort C2R_Login = 20017;
public const ushort R2C_Login = 20018;
public const ushort C2G_LoginGate = 20019;
public const ushort G2C_LoginGate = 20020;
public const ushort G2C_TestHotfixMessage = 20021;
public const ushort C2M_TestActorRequest = 20022;
public const ushort M2C_TestActorResponse = 20023;
public const ushort PlayerInfo = 20024;
public const ushort C2G_PlayerInfo = 20025;
public const ushort G2C_PlayerInfo = 20026;
public const ushort C2M_Stop = 20010;
public const ushort M2C_PathfindingResult = 20011;
public const ushort M2C_Stop = 20012;
public const ushort C2G_Ping = 20013;
public const ushort G2C_Ping = 20014;
public const ushort G2C_Test = 20015;
public const ushort C2M_Reload = 20016;
public const ushort M2C_Reload = 20017;
public const ushort C2R_Login = 20018;
public const ushort R2C_Login = 20019;
public const ushort C2G_LoginGate = 20020;
public const ushort G2C_LoginGate = 20021;
public const ushort G2C_TestHotfixMessage = 20022;
public const ushort C2M_TestActorRequest = 20023;
public const ushort M2C_TestActorResponse = 20024;
public const ushort PlayerInfo = 20025;
public const ushort C2G_PlayerInfo = 20026;
public const ushort G2C_PlayerInfo = 20027;
}
}
fileFormatVersion: 2
guid: 167c92d772b01476c983b16abfa46562
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
namespace ET
{
public class AIHandlerAttribute: BaseAttribute
{
}
[AIHandler]
public abstract class AAIHandler
{
// 检查是否满足条件
public abstract int Check(AIComponent aiComponent, AIConfig aiConfig);
// 协程编写必须可以取消
public abstract ETVoid Execute(AIComponent aiComponent, AIConfig aiConfig, ETCancellationToken cancellationToken);
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 4fe4e242d994c449483c3160866a57d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
namespace ET
{
// 客户端挂在ZoneScene上,服务端挂在Unit上
public class AIComponent: Entity
{
public int AIConfigId;
public ETCancellationToken CancellationToken;
public long Timer;
public int Current;
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: c754f37c484d34e4fa0a9160de407f8f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using System.ComponentModel;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using ProtoBuf;
namespace ET
{
public partial class AIConfigCategory
{
public Dictionary<int, SortedDictionary<int, AIConfig>> AIConfigs = new Dictionary<int, SortedDictionary<int, AIConfig>>();
public SortedDictionary<int, AIConfig> GetAI(int aiConfigId)
{
return this.AIConfigs[aiConfigId];
}
public override void EndInit()
{
base.EndInit();
foreach (var kv in this.GetAll())
{
SortedDictionary<int, AIConfig> aiNodeConfig;
if (!this.AIConfigs.TryGetValue(kv.Value.AIConfigId, out aiNodeConfig))
{
aiNodeConfig = new SortedDictionary<int, AIConfig>();
this.AIConfigs.Add(kv.Value.AIConfigId, aiNodeConfig);
}
aiNodeConfig.Add(kv.Key, kv.Value);
}
}
}
}
fileFormatVersion: 2
guid: 9093f3843f3ee4466a5fc71c53a394b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
namespace ET
{
public class AIDispatcherComponent: Entity
{
public static AIDispatcherComponent Instance;
public Dictionary<string, AAIHandler> AIHandlers = new Dictionary<string, AAIHandler>();
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: b3ad59713447042a18ef6ff24c957d02
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -6,7 +6,8 @@ namespace ET
{
private static readonly HashSet<ushort> ignoreDebugLogMessageSet = new HashSet<ushort>
{
OuterOpcode.C2G_Ping,
OuterOpcode.G2C_Ping,
};
private static bool IsNeedLogMessage(ushort opcode)
......
......@@ -52,7 +52,7 @@
"url": "https://packages.unity.cn"
},
"com.unity.test-framework": {
"version": "1.1.22",
"version": "1.1.24",
"depth": 1,
"source": "registry",
"dependencies": {
......
m_EditorVersion: 2020.3.0f1c1
m_EditorVersionWithRevision: 2020.3.0f1c1 (1e553bf703d9)
m_EditorVersion: 2020.3.3f1c1
m_EditorVersionWithRevision: 2020.3.3f1c1 (a34b99c2c582)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册