mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
[+] 接入ET8服务端
[+] 接入ET8服务端
This commit is contained in:
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/AI.meta
Normal file
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/AI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2809a97c6cbc7b42b7df4abc77cb1f7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(AIComponent))]
|
||||
[FriendOf(typeof(AIComponent))]
|
||||
[FriendOf(typeof(AIDispatcherComponent))]
|
||||
public static partial class AIComponentSystem
|
||||
{
|
||||
[Invoke(TimerInvokeType.AITimer)]
|
||||
public class AITimer: ATimer<AIComponent>
|
||||
{
|
||||
protected override void Run(AIComponent self)
|
||||
{
|
||||
try
|
||||
{
|
||||
self.Check();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"move timer error: {self.Id}\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Awake(this AIComponent self, int aiConfigId)
|
||||
{
|
||||
self.AIConfigId = aiConfigId;
|
||||
self.Timer = self.Fiber().TimerComponent.NewRepeatedTimer(1000, TimerInvokeType.AITimer, self);
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Destroy(this AIComponent self)
|
||||
{
|
||||
self.Fiber().TimerComponent?.Remove(ref self.Timer);
|
||||
self.CancellationToken?.Cancel();
|
||||
self.CancellationToken = null;
|
||||
self.Current = 0;
|
||||
}
|
||||
|
||||
private static void Check(this AIComponent self)
|
||||
{
|
||||
if (self.Parent == null)
|
||||
{
|
||||
self.Fiber().TimerComponent.Remove(ref self.Timer);
|
||||
return;
|
||||
}
|
||||
|
||||
var oneAI = AIConfigCategory.Instance.AIConfigs[self.AIConfigId];
|
||||
|
||||
foreach (AIConfig aiConfig in oneAI.Values)
|
||||
{
|
||||
|
||||
AAIHandler aaiHandler = AIDispatcherComponent.Instance.Get(aiConfig.Name);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc49c73c647c3cb47974ecfc4bd8121f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
Assets/GameScripts/DotNet/Hotfix/Share/Module/Actor.meta
Normal file
3
Assets/GameScripts/DotNet/Hotfix/Share/Module/Actor.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee3a9e6a195849ee8792a8793fb0bdd6
|
||||
timeCreated: 1687789835
|
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public static partial class ActorHandleHelper
|
||||
{
|
||||
[EnableAccessEntiyChild]
|
||||
public static async ETTask HandleMessage(Fiber fiber, ActorId actorId, MessageObject message)
|
||||
{
|
||||
await ETTask.CompletedTask;
|
||||
/*
|
||||
// 收到actor消息,放入actor队列
|
||||
switch (message)
|
||||
{
|
||||
case IActorRequest iActorRequest:
|
||||
{
|
||||
|
||||
|
||||
switch (mailBoxComponent.MailboxType)
|
||||
{
|
||||
case MailboxType.OrderedMessage:
|
||||
{
|
||||
using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Mailbox, actorId.InstanceId))
|
||||
{
|
||||
if (entity.InstanceId != actorId.InstanceId)
|
||||
{
|
||||
IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
|
||||
ActorMessageSenderComponent.Instance.Reply(actorId, response);
|
||||
break;
|
||||
}
|
||||
|
||||
await ActorMessageDispatcherComponent.Instance.Handle(entity, actorId, iActorRequest);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MailboxType.UnOrderMessageDispatcher:
|
||||
{
|
||||
await ActorMessageDispatcherComponent.Instance.Handle(entity, actorId, iActorRequest);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Exception($"no mailboxtype: {mailBoxComponent.MailboxType} {iActorRequest}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IActorMessage iActorMessage:
|
||||
{
|
||||
mailBoxComponent = Fiber.Instance.Mailboxes.Get(actorId.InstanceId);
|
||||
if (mailBoxComponent == null)
|
||||
{
|
||||
Log.Error($"actor not found mailbox: {actorId} {iActorMessage}");
|
||||
return;
|
||||
}
|
||||
mailBoxComponent.Add(iActorMessage as MessageObject);
|
||||
|
||||
switch (mailBoxComponent.MailboxType)
|
||||
{
|
||||
case MailboxType.OrderedMessage:
|
||||
{
|
||||
using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Mailbox, actorId.InstanceId))
|
||||
{
|
||||
if (entity.InstanceId != actorId.InstanceId)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
await ActorMessageDispatcherComponent.Instance.Handle(entity, actorId, iActorMessage);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MailboxType.UnOrderMessageDispatcher:
|
||||
{
|
||||
await ActorMessageDispatcherComponent.Instance.Handle(entity, actorId, iActorMessage);
|
||||
break;
|
||||
}
|
||||
case MailboxType.GateSession:
|
||||
{
|
||||
if (entity is PlayerSessionComponent playerSessionComponent)
|
||||
{
|
||||
playerSessionComponent.Session?.Send(iActorMessage);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Exception($"no mailboxtype: {mailBoxComponent.MailboxType} {iActorMessage}");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db010549ca0dacb4aad130643706b6f8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EnableClass]
|
||||
public abstract class ActorMessageHandler<E, Message>: IMActorHandler where E : Entity where Message : class, IActorMessage
|
||||
{
|
||||
protected abstract ETTask Run(E entity, Message message);
|
||||
|
||||
public async ETTask Handle(Entity entity, Address fromAddress, MessageObject actorMessage)
|
||||
{
|
||||
if (actorMessage is not Message msg)
|
||||
{
|
||||
Log.Error($"消息类型转换错误: {actorMessage.GetType().FullName} to {typeof (Message).Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity is not E e)
|
||||
{
|
||||
Log.Error($"Actor类型转换错误: {entity.GetType().FullName} to {typeof (E).Name} --{typeof (Message).FullName}");
|
||||
return;
|
||||
}
|
||||
|
||||
await this.Run(e, msg);
|
||||
}
|
||||
|
||||
public Type GetRequestType()
|
||||
{
|
||||
if (typeof (IActorLocationMessage).IsAssignableFrom(typeof (Message)))
|
||||
{
|
||||
Log.Error($"message is IActorLocationMessage but handler is AMActorHandler: {typeof (Message)}");
|
||||
}
|
||||
|
||||
return typeof (Message);
|
||||
}
|
||||
|
||||
public Type GetResponseType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[EnableClass]
|
||||
public abstract class ActorMessageHandler<E, Request, Response>: IMActorHandler where E : Entity where Request : MessageObject, IActorRequest where Response : MessageObject, IActorResponse
|
||||
{
|
||||
protected abstract ETTask Run(E unit, Request request, Response response);
|
||||
|
||||
public async ETTask Handle(Entity entity, Address fromAddress, MessageObject actorMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (actorMessage is not Request request)
|
||||
{
|
||||
Log.Error($"消息类型转换错误: {actorMessage.GetType().FullName} to {typeof (Request).Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity is not E ee)
|
||||
{
|
||||
Log.Error($"Actor类型转换错误: {entity.GetType().FullName} to {typeof (E).FullName} --{typeof (Request).FullName}");
|
||||
return;
|
||||
}
|
||||
|
||||
int rpcId = request.RpcId;
|
||||
Response response = ObjectPool.Instance.Fetch<Response>();
|
||||
|
||||
try
|
||||
{
|
||||
await this.Run(ee, request, response);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception);
|
||||
response.Error = ErrorCore.ERR_RpcFail;
|
||||
response.Message = exception.ToString();
|
||||
}
|
||||
|
||||
response.RpcId = rpcId;
|
||||
entity.Root().GetComponent<ActorInnerComponent>().Reply(fromAddress, response);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception($"解释消息失败: {actorMessage.GetType().FullName}", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Type GetRequestType()
|
||||
{
|
||||
if (typeof (IActorLocationRequest).IsAssignableFrom(typeof (Request)))
|
||||
{
|
||||
Log.Error($"message is IActorLocationMessage but handler is AMActorRpcHandler: {typeof (Request)}");
|
||||
}
|
||||
|
||||
return typeof (Request);
|
||||
}
|
||||
|
||||
public Type GetResponseType()
|
||||
{
|
||||
return typeof (Response);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04b4a2b11a349624bb67b2fe9a0ff8da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
namespace ET
|
||||
{
|
||||
[Invoke((long)MailBoxType.OrderedMessage)]
|
||||
public class MailBoxType_OrderedMessageHandler: AInvokeHandler<MailBoxInvoker>
|
||||
{
|
||||
public override void Handle(MailBoxInvoker args)
|
||||
{
|
||||
HandleInner(args).Coroutine();
|
||||
}
|
||||
|
||||
private static async ETTask HandleInner(MailBoxInvoker args)
|
||||
{
|
||||
MailBoxComponent mailBoxComponent = args.MailBoxComponent;
|
||||
|
||||
// 对象池回收
|
||||
using MessageObject messageObject = args.MessageObject;
|
||||
|
||||
CoroutineLockComponent coroutineLockComponent = mailBoxComponent.CoroutineLockComponent;
|
||||
if (coroutineLockComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long instanceId = mailBoxComponent.InstanceId;
|
||||
using (await coroutineLockComponent.Wait(CoroutineLockType.Mailbox, mailBoxComponent.ParentInstanceId))
|
||||
{
|
||||
if (mailBoxComponent.InstanceId != instanceId)
|
||||
{
|
||||
if (messageObject is IActorRequest request)
|
||||
{
|
||||
IActorResponse resp = ActorHelper.CreateResponse(request, ErrorCore.ERR_NotFoundActor);
|
||||
mailBoxComponent.Root().GetComponent<ActorInnerComponent>().Reply(args.FromAddress, resp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
await ActorMessageDispatcherComponent.Instance.Handle(mailBoxComponent.Parent, args.FromAddress, messageObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b1a21d2bb4831842b09143fd143efe7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,20 @@
|
||||
namespace ET
|
||||
{
|
||||
[Invoke((long)MailBoxType.UnOrderedMessage)]
|
||||
public class MailBoxType_UnOrderedMessageHandler: AInvokeHandler<MailBoxInvoker>
|
||||
{
|
||||
public override void Handle(MailBoxInvoker args)
|
||||
{
|
||||
HandleAsync(args).Coroutine();
|
||||
}
|
||||
|
||||
private static async ETTask HandleAsync(MailBoxInvoker args)
|
||||
{
|
||||
MailBoxComponent mailBoxComponent = args.MailBoxComponent;
|
||||
|
||||
using MessageObject messageObject = args.MessageObject;
|
||||
|
||||
await ActorMessageDispatcherComponent.Instance.Handle(mailBoxComponent.Parent, args.FromAddress, messageObject);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7552d478fb2b3534e967630e8c63e8b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe0c2296b8e188a4cae9c6f010fd0d77
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(ConsoleComponent))]
|
||||
[FriendOf(typeof(ConsoleComponent))]
|
||||
[FriendOf(typeof(ModeContex))]
|
||||
public static partial class ConsoleComponentSystem
|
||||
{
|
||||
[EntitySystem]
|
||||
private static void Awake(this ConsoleComponent self)
|
||||
{
|
||||
self.Start().Coroutine();
|
||||
}
|
||||
|
||||
|
||||
private static async ETTask Start(this ConsoleComponent self)
|
||||
{
|
||||
self.CancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
ModeContex modeContex = self.GetComponent<ModeContex>();
|
||||
string line = await Task.Factory.StartNew(() =>
|
||||
{
|
||||
Console.Write($"{modeContex?.Mode ?? ""}> ");
|
||||
return Console.In.ReadLine();
|
||||
}, self.CancellationTokenSource.Token);
|
||||
|
||||
line = line.Trim();
|
||||
|
||||
switch (line)
|
||||
{
|
||||
case "":
|
||||
break;
|
||||
case "exit":
|
||||
self.RemoveComponent<ModeContex>();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
string[] lines = line.Split(" ");
|
||||
string mode = modeContex == null? lines[0] : modeContex.Mode;
|
||||
|
||||
IConsoleHandler iConsoleHandler = ConsoleDispatcher.Instance.Get(mode);
|
||||
if (modeContex == null)
|
||||
{
|
||||
modeContex = self.AddComponent<ModeContex>();
|
||||
modeContex.Mode = mode;
|
||||
}
|
||||
await iConsoleHandler.Run(self.Fiber(), modeContex, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Console(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3bdd9b39878d7e04685a85d38bc88950
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[ConsoleHandler(ConsoleMode.ReloadConfig)]
|
||||
public class ReloadConfigConsoleHandler: IConsoleHandler
|
||||
{
|
||||
public async ETTask Run(Fiber fiber, ModeContex contex, string content)
|
||||
{
|
||||
switch (content)
|
||||
{
|
||||
case ConsoleMode.ReloadConfig:
|
||||
contex.Parent.RemoveComponent<ModeContex>();
|
||||
Log.Console("C must have config name, like: C UnitConfig");
|
||||
break;
|
||||
default:
|
||||
string[] ss = content.Split(" ");
|
||||
string configName = ss[1];
|
||||
string category = $"{configName}Category";
|
||||
Type type = EventSystem.Instance.GetType($"ET.{category}");
|
||||
if (type == null)
|
||||
{
|
||||
Log.Console($"reload config but not find {category}");
|
||||
return;
|
||||
}
|
||||
ConfigComponent.Instance.Reload(type);
|
||||
Log.Console($"reload config {configName} finish!");
|
||||
break;
|
||||
}
|
||||
|
||||
await ETTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bf64d72d2f1cc445ad8fb13eeef331b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,12 @@
|
||||
namespace ET
|
||||
{
|
||||
[ConsoleHandler(ConsoleMode.ReloadDll)]
|
||||
public class ReloadDllConsoleHandler: IConsoleHandler
|
||||
{
|
||||
public async ETTask Run(Fiber fiber, ModeContex contex, string content)
|
||||
{
|
||||
await ETTask.CompletedTask;
|
||||
CodeLoader.Instance.LoadHotfix();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffe8f82cde98483438673415feab109a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d247feb1f882fa24094546d5699183d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(SessionAcceptTimeoutComponent))]
|
||||
[FriendOf(typeof(SessionAcceptTimeoutComponent))]
|
||||
public static partial class SessionAcceptTimeoutComponentHelper
|
||||
{
|
||||
[Invoke(TimerInvokeType.SessionAcceptTimeout)]
|
||||
public class SessionAcceptTimeout: ATimer<SessionAcceptTimeoutComponent>
|
||||
{
|
||||
protected override void Run(SessionAcceptTimeoutComponent self)
|
||||
{
|
||||
try
|
||||
{
|
||||
self.Parent.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"move timer error: {self.Id}\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Awake(this SessionAcceptTimeoutComponent self)
|
||||
{
|
||||
self.Timer = self.Fiber().TimerComponent.NewOnceTimer(self.Fiber().TimeInfo.ServerNow() + 5000, TimerInvokeType.SessionAcceptTimeout, self);
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Destroy(this SessionAcceptTimeoutComponent self)
|
||||
{
|
||||
self.Fiber().TimerComponent?.Remove(ref self.Timer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 389d0d5a5107d864782d45a819b8fcd5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(SessionIdleCheckerComponent))]
|
||||
[FriendOf(typeof(SessionIdleCheckerComponent))]
|
||||
public static partial class SessionIdleCheckerComponentSystem
|
||||
{
|
||||
[Invoke(TimerInvokeType.SessionIdleChecker)]
|
||||
public class SessionIdleChecker: ATimer<SessionIdleCheckerComponent>
|
||||
{
|
||||
protected override void Run(SessionIdleCheckerComponent self)
|
||||
{
|
||||
try
|
||||
{
|
||||
self.Check();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"session idle checker timer error: {self.Id}\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Awake(this SessionIdleCheckerComponent self)
|
||||
{
|
||||
self.RepeatedTimer = self.Fiber().TimerComponent.NewRepeatedTimer(CheckInteral, TimerInvokeType.SessionIdleChecker, self);
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Destroy(this SessionIdleCheckerComponent self)
|
||||
{
|
||||
self.Fiber().TimerComponent?.Remove(ref self.RepeatedTimer);
|
||||
}
|
||||
|
||||
public const int CheckInteral = 2000;
|
||||
|
||||
private static void Check(this SessionIdleCheckerComponent self)
|
||||
{
|
||||
Session session = self.GetParent<Session>();
|
||||
long timeNow = self.Fiber().TimeInfo.ClientNow();
|
||||
|
||||
if (timeNow - session.LastRecvTime < ConstValue.SessionTimeoutTime && timeNow - session.LastSendTime < ConstValue.SessionTimeoutTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Info($"session timeout: {session.Id} {timeNow} {session.LastRecvTime} {session.LastSendTime} {timeNow - session.LastRecvTime} {timeNow - session.LastSendTime}");
|
||||
session.Error = ErrorCore.ERR_SessionSendOrRecvTimeout;
|
||||
|
||||
session.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a68abadd37d72f14393cf250c23e1164
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/Move.meta
Normal file
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/Move.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 069fa286008182847950a814f31931e3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,294 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(MoveComponent))]
|
||||
[FriendOf(typeof(MoveComponent))]
|
||||
public static partial class MoveComponentSystem
|
||||
{
|
||||
[Invoke(TimerInvokeType.MoveTimer)]
|
||||
public class MoveTimer: ATimer<MoveComponent>
|
||||
{
|
||||
protected override void Run(MoveComponent self)
|
||||
{
|
||||
try
|
||||
{
|
||||
self.MoveForward(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"move timer error: {self.Id}\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[EntitySystem]
|
||||
private static void Destroy(this MoveComponent self)
|
||||
{
|
||||
self.MoveFinish(false);
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Awake(this MoveComponent self)
|
||||
{
|
||||
self.StartTime = 0;
|
||||
self.StartPos = float3.zero;
|
||||
self.NeedTime = 0;
|
||||
self.MoveTimer = 0;
|
||||
self.tcs = null;
|
||||
self.Targets.Clear();
|
||||
self.Speed = 0;
|
||||
self.N = 0;
|
||||
self.TurnTime = 0;
|
||||
}
|
||||
|
||||
public static bool IsArrived(this MoveComponent self)
|
||||
{
|
||||
return self.Targets.Count == 0;
|
||||
}
|
||||
|
||||
public static bool ChangeSpeed(this MoveComponent self, float speed)
|
||||
{
|
||||
if (self.IsArrived())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (speed < 0.0001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Unit unit = self.GetParent<Unit>();
|
||||
|
||||
using ListComponent<float3> path = ListComponent<float3>.Create();
|
||||
|
||||
self.MoveForward(false);
|
||||
|
||||
path.Add(unit.Position); // 第一个是Unit的pos
|
||||
for (int i = self.N; i < self.Targets.Count; ++i)
|
||||
{
|
||||
path.Add(self.Targets[i]);
|
||||
}
|
||||
self.MoveToAsync(path, speed).Coroutine();
|
||||
return true;
|
||||
}
|
||||
|
||||
// 该方法不需要用cancelToken的方式取消,因为即使不传入cancelToken,多次调用该方法也要取消之前的移动协程,上层可以stop取消
|
||||
public static async ETTask<bool> MoveToAsync(this MoveComponent self, List<float3> target, float speed, int turnTime = 100)
|
||||
{
|
||||
self.Stop(false);
|
||||
|
||||
foreach (float3 v in target)
|
||||
{
|
||||
self.Targets.Add(v);
|
||||
}
|
||||
|
||||
self.IsTurnHorizontal = true;
|
||||
self.TurnTime = turnTime;
|
||||
self.Speed = speed;
|
||||
self.tcs = ETTask<bool>.Create(true);
|
||||
|
||||
EventSystem.Instance.Publish(self.Scene(), new EventType.MoveStart() {Unit = self.GetParent<Unit>()});
|
||||
|
||||
self.StartMove();
|
||||
|
||||
bool moveRet = await self.tcs;
|
||||
|
||||
if (moveRet)
|
||||
{
|
||||
EventSystem.Instance.Publish(self.Scene(), new EventType.MoveStop() {Unit = self.GetParent<Unit>()});
|
||||
}
|
||||
return moveRet;
|
||||
}
|
||||
|
||||
// ret: 停止的时候,移动协程的返回值
|
||||
private static void MoveForward(this MoveComponent self, bool ret)
|
||||
{
|
||||
Unit unit = self.GetParent<Unit>();
|
||||
|
||||
long timeNow = self.Fiber().TimeInfo.ClientNow();
|
||||
long moveTime = timeNow - self.StartTime;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (moveTime <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算位置插值
|
||||
if (moveTime >= self.NeedTime)
|
||||
{
|
||||
unit.Position = self.NextTarget;
|
||||
if (self.TurnTime > 0)
|
||||
{
|
||||
unit.Rotation = self.To;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 计算位置插值
|
||||
float amount = moveTime * 1f / self.NeedTime;
|
||||
if (amount > 0)
|
||||
{
|
||||
float3 newPos = math.lerp(self.StartPos, self.NextTarget, amount);
|
||||
unit.Position = newPos;
|
||||
}
|
||||
|
||||
// 计算方向插值
|
||||
if (self.TurnTime > 0)
|
||||
{
|
||||
amount = moveTime * 1f / self.TurnTime;
|
||||
if (amount > 1)
|
||||
{
|
||||
amount = 1f;
|
||||
}
|
||||
quaternion q = math.slerp(self.From, self.To, amount);
|
||||
unit.Rotation = q;
|
||||
}
|
||||
}
|
||||
|
||||
moveTime -= self.NeedTime;
|
||||
|
||||
// 表示这个点还没走完,等下一帧再来
|
||||
if (moveTime < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 到这里说明这个点已经走完
|
||||
|
||||
// 如果是最后一个点
|
||||
if (self.N >= self.Targets.Count - 1)
|
||||
{
|
||||
unit.Position = self.NextTarget;
|
||||
unit.Rotation = self.To;
|
||||
|
||||
self.MoveFinish(ret);
|
||||
return;
|
||||
}
|
||||
|
||||
self.SetNextTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private static void StartMove(this MoveComponent self)
|
||||
{
|
||||
self.BeginTime = self.Fiber().TimeInfo.ClientNow();
|
||||
self.StartTime = self.BeginTime;
|
||||
self.SetNextTarget();
|
||||
|
||||
self.MoveTimer = self.Fiber().TimerComponent.NewFrameTimer(TimerInvokeType.MoveTimer, self);
|
||||
}
|
||||
|
||||
private static void SetNextTarget(this MoveComponent self)
|
||||
{
|
||||
|
||||
Unit unit = self.GetParent<Unit>();
|
||||
|
||||
++self.N;
|
||||
|
||||
// 时间计算用服务端的位置, 但是移动要用客户端的位置来插值
|
||||
float3 v = self.GetFaceV();
|
||||
float distance = math.length(v);
|
||||
|
||||
// 插值的起始点要以unit的真实位置来算
|
||||
self.StartPos = unit.Position;
|
||||
|
||||
self.StartTime += self.NeedTime;
|
||||
|
||||
self.NeedTime = (long) (distance / self.Speed * 1000);
|
||||
|
||||
if (self.TurnTime > 0)
|
||||
{
|
||||
// 要用unit的位置
|
||||
float3 faceV = self.GetFaceV();
|
||||
if (math.lengthsq(faceV) < 0.0001f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.From = unit.Rotation;
|
||||
|
||||
if (self.IsTurnHorizontal)
|
||||
{
|
||||
faceV.y = 0;
|
||||
}
|
||||
|
||||
if (Math.Abs(faceV.x) > 0.01 || Math.Abs(faceV.z) > 0.01)
|
||||
{
|
||||
self.To = quaternion.LookRotation(faceV, math.up());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.TurnTime == 0) // turn time == 0 立即转向
|
||||
{
|
||||
float3 faceV = self.GetFaceV();
|
||||
if (self.IsTurnHorizontal)
|
||||
{
|
||||
faceV.y = 0;
|
||||
}
|
||||
|
||||
if (Math.Abs(faceV.x) > 0.01 || Math.Abs(faceV.z) > 0.01)
|
||||
{
|
||||
self.To = quaternion.LookRotation(faceV, math.up());
|
||||
unit.Rotation = self.To;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static float3 GetFaceV(this MoveComponent self)
|
||||
{
|
||||
return self.NextTarget - self.PreTarget;
|
||||
}
|
||||
|
||||
public static bool FlashTo(this MoveComponent self, float3 target)
|
||||
{
|
||||
Unit unit = self.GetParent<Unit>();
|
||||
unit.Position = target;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ret: 停止的时候,移动协程的返回值
|
||||
public static void Stop(this MoveComponent self, bool ret)
|
||||
{
|
||||
if (self.Targets.Count > 0)
|
||||
{
|
||||
self.MoveForward(ret);
|
||||
}
|
||||
|
||||
self.MoveFinish(ret);
|
||||
}
|
||||
|
||||
private static void MoveFinish(this MoveComponent self, bool ret)
|
||||
{
|
||||
if (self.StartTime == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.StartTime = 0;
|
||||
self.StartPos = float3.zero;
|
||||
self.BeginTime = 0;
|
||||
self.NeedTime = 0;
|
||||
self.Targets.Clear();
|
||||
self.Speed = 0;
|
||||
self.N = 0;
|
||||
self.TurnTime = 0;
|
||||
self.IsTurnHorizontal = false;
|
||||
self.Fiber().TimerComponent?.Remove(ref self.MoveTimer);
|
||||
|
||||
if (self.tcs != null)
|
||||
{
|
||||
var tcs = self.tcs;
|
||||
self.tcs = null;
|
||||
tcs.SetResult(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c9d0c7894766af4290b1cf3bac03841
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad2461a885cf71940812b6f3ca8cb6a5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
namespace ET
|
||||
{
|
||||
// 分发数值监听
|
||||
[Event(SceneType.All)] // 服务端Map需要分发, 客户端CurrentScene也要分发
|
||||
public class NumericChangeEvent_NotifyWatcher: AEvent<Scene, EventType.NumbericChange>
|
||||
{
|
||||
protected override async ETTask Run(Scene scene, EventType.NumbericChange args)
|
||||
{
|
||||
NumericWatcherComponent.Instance.Run(args.Unit, args);
|
||||
await ETTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4ee1a86c772c6d42a5d25c36004720e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
namespace ET
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户端监视hp数值变化,改变血条值
|
||||
/// </summary>
|
||||
[NumericWatcher(SceneType.Current, NumericType.Hp)]
|
||||
public class NumericWatcher_Hp_ShowUI : INumericWatcher
|
||||
{
|
||||
public void Run(Unit unit, EventType.NumbericChange args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1215d410dbbdb144be73a6410148c59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce6c6236ff156ac47a06c57952ca1abb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(PathfindingComponent))]
|
||||
[FriendOf(typeof(PathfindingComponent))]
|
||||
public static partial class PathfindingComponentSystem
|
||||
{
|
||||
[EntitySystem]
|
||||
private static void Awake(this PathfindingComponent self, string name)
|
||||
{
|
||||
self.Name = name;
|
||||
byte[] buffer = NavmeshComponent.Instance.Get(name);
|
||||
self.navMesh = Recast.RecastLoad(buffer, buffer.Length);
|
||||
if (self.navMesh == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception($"nav load fail: {name}");
|
||||
}
|
||||
}
|
||||
|
||||
[EntitySystem]
|
||||
private static void Destroy(this PathfindingComponent self)
|
||||
{
|
||||
self.Name = string.Empty;
|
||||
|
||||
Recast.RecastClear(self.navMesh);
|
||||
|
||||
self.navMesh = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public static void Find(this PathfindingComponent self, float3 start, float3 target, List<float3> result)
|
||||
{
|
||||
if (self.navMesh == IntPtr.Zero)
|
||||
{
|
||||
Log.Debug("寻路| Find 失败 pathfinding ptr is zero");
|
||||
throw new Exception($"pathfinding ptr is zero: {self.Scene().Name}");
|
||||
}
|
||||
|
||||
self.StartPos[0] = -start.x;
|
||||
self.StartPos[1] = start.y;
|
||||
self.StartPos[2] = start.z;
|
||||
|
||||
self.EndPos[0] = -target.x;
|
||||
self.EndPos[1] = target.y;
|
||||
self.EndPos[2] = target.z;
|
||||
//Log.Debug($"start find path: {self.GetParent<Unit>().Id}");
|
||||
int n = Recast.RecastFind(self.navMesh, self.extents, self.StartPos, self.EndPos, self.Result);
|
||||
if (n < 0)
|
||||
{
|
||||
throw new Exception($"find path error: {n}");
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
int index = i * 3;
|
||||
result.Add(new float3(-self.Result[index], self.Result[index + 1], self.Result[index + 2]));
|
||||
}
|
||||
//Log.Debug($"finish find path: {self.GetParent<Unit>().Id} {result.ListToString()}");
|
||||
}
|
||||
|
||||
public static void FindWithAdjust(this PathfindingComponent self, float3 start, float3 target, List<float3> result,float adjustRaduis)
|
||||
{
|
||||
self.Find(start, target, result);
|
||||
for (int i = 0; i < result.Count; i++)
|
||||
{
|
||||
float3 adjust = self.FindRandomPointWithRaduis(result[i], adjustRaduis);
|
||||
result[i] = adjust;
|
||||
}
|
||||
}
|
||||
|
||||
public static float3 FindRandomPointWithRaduis(this PathfindingComponent self, float3 pos, float raduis)
|
||||
{
|
||||
if (self.navMesh == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception($"pathfinding ptr is zero: {self.Scene().Name}");
|
||||
}
|
||||
|
||||
if (raduis > PathfindingComponent.FindRandomNavPosMaxRadius * 0.001f)
|
||||
{
|
||||
throw new Exception($"pathfinding raduis is too large,cur: {raduis}, max: {PathfindingComponent.FindRandomNavPosMaxRadius}");
|
||||
}
|
||||
|
||||
int degrees = RandomGenerator.RandomNumber(0, 360);
|
||||
float r = RandomGenerator.RandomNumber(0, (int) (raduis * 1000)) / 1000f;
|
||||
|
||||
float x = r * math.cos(math.radians(degrees));
|
||||
float z = r * math.sin(math.radians(degrees));
|
||||
|
||||
float3 findpos = new float3(pos.x + x, pos.y, pos.z + z);
|
||||
|
||||
return self.RecastFindNearestPoint(findpos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以pos为中心各自在宽和高的左右 前后两个方向延伸
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static float3 FindRandomPointWithRectangle(this PathfindingComponent self, float3 pos, int width, int height)
|
||||
{
|
||||
if (self.navMesh == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception($"pathfinding ptr is zero: {self.Scene().Name}");
|
||||
}
|
||||
|
||||
if (width > PathfindingComponent.FindRandomNavPosMaxRadius * 0.001f || height > PathfindingComponent.FindRandomNavPosMaxRadius * 0.001f)
|
||||
{
|
||||
throw new Exception($"pathfinding rectangle is too large,width: {width} height: {height}, max: {PathfindingComponent.FindRandomNavPosMaxRadius}");
|
||||
}
|
||||
|
||||
float x = RandomGenerator.RandomNumber(-width, width);
|
||||
float z = RandomGenerator.RandomNumber(-height, height);
|
||||
|
||||
float3 findpos = new float3(pos.x + x, pos.y, pos.z + z);
|
||||
|
||||
return self.RecastFindNearestPoint(findpos);
|
||||
}
|
||||
|
||||
public static float3 FindRandomPointWithRaduis(this PathfindingComponent self, float3 pos, float minRadius, float maxRadius)
|
||||
{
|
||||
if (self.navMesh == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception($"pathfinding ptr is zero: {self.Scene().Name}");
|
||||
}
|
||||
|
||||
if (maxRadius > PathfindingComponent.FindRandomNavPosMaxRadius * 0.001f)
|
||||
{
|
||||
throw new Exception($"pathfinding raduis is too large,cur: {maxRadius}, max: {PathfindingComponent.FindRandomNavPosMaxRadius}");
|
||||
}
|
||||
|
||||
int degrees = RandomGenerator.RandomNumber(0, 360);
|
||||
float r = RandomGenerator.RandomNumber((int) (minRadius * 1000), (int) (maxRadius * 1000)) / 1000f;
|
||||
|
||||
float x = r * math.cos(math.radians(degrees));
|
||||
float z = r * math.sin(math.radians(degrees));
|
||||
|
||||
float3 findpos = new float3(pos.x + x, pos.y, pos.z + z);
|
||||
|
||||
return self.RecastFindNearestPoint(findpos);
|
||||
}
|
||||
|
||||
public static float3 RecastFindNearestPoint(this PathfindingComponent self, float3 pos)
|
||||
{
|
||||
if (self.navMesh == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception($"pathfinding ptr is zero: {self.Scene().Name}");
|
||||
}
|
||||
|
||||
self.StartPos[0] = -pos.x;
|
||||
self.StartPos[1] = pos.y;
|
||||
self.StartPos[2] = pos.z;
|
||||
|
||||
int ret = Recast.RecastFindNearestPoint(self.navMesh, self.extents, self.StartPos, self.EndPos);
|
||||
if (ret == 0)
|
||||
{
|
||||
throw new Exception($"RecastFindNearestPoint fail, 可能是位置配置有问题: sceneName:{self.Scene().Name} {pos} {self.Name} {self.GetParent<Unit>().Id} {self.GetParent<Unit>().Config.Id} {self.EndPos.ArrayToString()}");
|
||||
}
|
||||
|
||||
return new float3(-self.EndPos[0], self.EndPos[1], self.EndPos[2]);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bdc5a9258f99554b92e5fb56e8eb1c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/Scene.meta
Normal file
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/Scene.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b58e79ff7cee3ce458b0d0aa593faf69
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace ET
|
||||
{
|
||||
public static partial class CurrentScenesComponentSystem
|
||||
{
|
||||
public static Scene CurrentScene(this Scene root)
|
||||
{
|
||||
return root.GetComponent<CurrentScenesComponent>()?.Scene;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcdaee383c510da42bff4aa0620ed28b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/Unit.meta
Normal file
8
Assets/GameScripts/DotNet/Hotfix/Share/Module/Unit.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 151803197aee1fd4c9eed75afb1b6b12
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,21 @@
|
||||
namespace ET
|
||||
{
|
||||
public static partial class UnitComponentSystem
|
||||
{
|
||||
public static void Add(this UnitComponent self, Unit unit)
|
||||
{
|
||||
}
|
||||
|
||||
public static Unit Get(this UnitComponent self, long id)
|
||||
{
|
||||
Unit unit = self.GetChild<Unit>(id);
|
||||
return unit;
|
||||
}
|
||||
|
||||
public static void Remove(this UnitComponent self, long id)
|
||||
{
|
||||
Unit unit = self.GetChild<Unit>(id);
|
||||
unit?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7fbe1de137b21e4e88024c1411f792d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,12 @@
|
||||
namespace ET
|
||||
{
|
||||
[EntitySystemOf(typeof(Unit))]
|
||||
public static partial class UnitSystem
|
||||
{
|
||||
[EntitySystem]
|
||||
private static void Awake(this Unit self, int configId)
|
||||
{
|
||||
self.ConfigId = configId;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9af1ba2890c2e524ca5fc31a4c2ee406
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user