This commit is contained in:
PC-20230316NUNE\Administrator 2024-08-31 21:05:29 +08:00
parent d67032e1de
commit 77b305be7a
53 changed files with 316 additions and 118 deletions

View File

@ -125,7 +125,7 @@
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.TileCache\DtTileCacheLayerBuilder.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.TileCache\DtTileCacheLayerBuilder.cs" />
<Compile Include="Assets\Scripts\Game\Logic\System\Logic\DWorldSystem.cs" /> <Compile Include="Assets\Scripts\Game\Logic\System\Logic\DWorldSystem.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.Extras\Jumplink\EdgeSamplerFactory.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.Extras\Jumplink\EdgeSamplerFactory.cs" />
<Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\EDNodeLookup.cs" /> <Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\Lookup\EDNodeLookup.cs" />
<Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\Controller\EDPlayerController.cs" /> <Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\Controller\EDPlayerController.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Recast.Toolset\Geom\DemoDtTileCacheMeshProcess.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Recast.Toolset\Geom\DemoDtTileCacheMeshProcess.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Recast.Toolset\Tools\RcJumpLinkBuilderTool.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Recast.Toolset\Tools\RcJumpLinkBuilderTool.cs" />
@ -208,7 +208,7 @@
<Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Shared\Scripts\ThirdPersonFollowDistanceModifier.cs" /> <Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Shared\Scripts\ThirdPersonFollowDistanceModifier.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.Dynamic\Colliders\DtTrimeshCollider.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.Dynamic\Colliders\DtTrimeshCollider.cs" />
<Compile Include="Assets\JNGame\Sync\App\Tile\JNSSTileTool.cs" /> <Compile Include="Assets\JNGame\Sync\App\Tile\JNSSTileTool.cs" />
<Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\EDBossLookup.cs" /> <Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\Lookup\EDBossLookup.cs" />
<Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Scenes\3rdPersonWithAimMode\ActivateOnKeypress.cs" /> <Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Scenes\3rdPersonWithAimMode\ActivateOnKeypress.cs" />
<Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Scenes\DualTarget\MoveAimTarget.cs" /> <Compile Include="Assets\Samples\Cinemachine\2.10.1\Cinemachine Example Scenes\Scenes\DualTarget\MoveAimTarget.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.TileCache\IDtTileCacheMeshProcess.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.TileCache\IDtTileCacheMeshProcess.cs" />
@ -412,7 +412,7 @@
<Compile Include="Assets\Scripts\Service\JNGResService.cs" /> <Compile Include="Assets\Scripts\Service\JNGResService.cs" />
<Compile Include="Assets\JNGame\Plugins\Entitas\Entitas.CodeGeneration.Attributes\src\CleanupAttribute.cs" /> <Compile Include="Assets\JNGame\Plugins\Entitas\Entitas.CodeGeneration.Attributes\src\CleanupAttribute.cs" />
<Compile Include="Assets\JNGame\Plugins\Entitas\Entitas.VisualDebugging.Unity\src\ContextObserver\ContextObserverExtension.cs" /> <Compile Include="Assets\JNGame\Plugins\Entitas\Entitas.VisualDebugging.Unity\src\ContextObserver\ContextObserverExtension.cs" />
<Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\EDPlayerLookup.cs" /> <Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\Lookup\EDPlayerLookup.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.Dynamic\Colliders\DtCylinderCollider.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Detour.Dynamic\Colliders\DtCylinderCollider.cs" />
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Core\Collections\RcImmutableArray.Enumerable.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Core\Collections\RcImmutableArray.Enumerable.cs" />
<Compile Include="Assets\JNGame\Plugins\Entitas\Entitas.CodeGeneration.Attributes\src\EntityIndex\EntityIndexAttribute.cs" /> <Compile Include="Assets\JNGame\Plugins\Entitas\Entitas.CodeGeneration.Attributes\src\EntityIndex\EntityIndexAttribute.cs" />
@ -701,6 +701,8 @@
<Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Core\IRcRand.cs" /> <Compile Include="Assets\JNGame\Map\DotRecast\Src\DotRecast.Core\IRcRand.cs" />
<Compile Include="Assets\JNGame\Math\BaseType\LVector2.cs" /> <Compile Include="Assets\JNGame\Math\BaseType\LVector2.cs" />
<Compile Include="Assets\JNGame\Plugins\Entitas\Entitas\src\Context\Context.cs" /> <Compile Include="Assets\JNGame\Plugins\Entitas\Entitas\src\Context\Context.cs" />
<Compile Include="Assets\Scripts\Game\Logic\Entity\EDEntityBasis.cs" />
<Compile Include="Assets\Scripts\Game\Logic\Entity\Nodes\Component\EDEntityComponent.cs" />
<None Include="Assets\TextMesh Pro\Shaders\TMPro.cginc" /> <None Include="Assets\TextMesh Pro\Shaders\TMPro.cginc" />
<None Include="Assets\TextMesh Pro\Shaders\TMP_SDF-Mobile Overlay.shader" /> <None Include="Assets\TextMesh Pro\Shaders\TMP_SDF-Mobile Overlay.shader" />
<None Include="Assets\Packages\Google.Protobuf.3.18.3\lib\netstandard2.0\Google.Protobuf.xml" /> <None Include="Assets\Packages\Google.Protobuf.3.18.3\lib\netstandard2.0\Google.Protobuf.xml" />

View File

@ -10,7 +10,7 @@ namespace JNGame.EntitasExtend
private int _index = 0; private int _index = 0;
public int Count => _index + 1; public int Count => _index;
public int Next() public int Next()
{ {

View File

@ -144,7 +144,8 @@ namespace JNGame.Map.DotRecast
//获取避障 //获取避障
public DtCrowdAgent GetAgent(ulong id) public DtCrowdAgent GetAgent(ulong id)
{ {
return agents[id]; agents.TryGetValue(id, out var value);
return value;
} }

View File

@ -52,11 +52,16 @@ namespace DotRecast.Detour.Crowd
/// The desired speed. /// The desired speed.
public LFloat desiredSpeed; public LFloat desiredSpeed;
public RcVec3f npos = new RcVec3f(); // < The current agent position. [(x, y, z)] // 当前代理的位置。这是一个三维向量包含x、y、z坐标。
public RcVec3f disp = new RcVec3f(); // < A temporary value used to accumulate agent displacement during iterative collision resolution. [(x, y, z)] public RcVec3f npos = new RcVec3f();
public RcVec3f dvel = new RcVec3f(); // < The desired velocity of the agent. Based on the current path, calculated from scratch each frame. [(x, y, z)] // 一个临时值用于在迭代碰撞解决过程中累积代理的位移。这也是一个三维向量包含x、y、z方向的位移。
public RcVec3f nvel = new RcVec3f(); // < The desired velocity adjusted by obstacle avoidance, calculated from scratch each frame. [(x, y, z)] public RcVec3f disp = new RcVec3f();
public RcVec3f vel = new RcVec3f(); // < The actual velocity of the agent. The change from nvel -> vel is constrained by max acceleration. [(x, y, z)] // 代理的期望速度。这个速度基于当前路径并且每帧都会重新计算。这是一个三维向量表示x、y、z方向上的期望速度。
public RcVec3f dvel = new RcVec3f();
// 经过障碍物避让调整后的期望速度。这个速度也是每帧重新计算并且考虑到了障碍物避免的逻辑。这是一个三维向量表示调整后的x、y、z方向上的速度。
public RcVec3f nvel = new RcVec3f();
// 代理的实际速度。从nvel到vel的变化受到最大加速度的限制。这也是一个三维向量表示x、y、z方向上的实际速度。
public RcVec3f vel = new RcVec3f();
/// The agent's configuration parameters. /// The agent's configuration parameters.
public DtCrowdAgentParams option; public DtCrowdAgentParams option;

View File

@ -4,8 +4,8 @@
/// @ingroup crowd /// @ingroup crowd
public enum DtCrowdAgentState public enum DtCrowdAgentState
{ {
DT_CROWDAGENT_STATE_INVALID, // < The agent is not in a valid state. DT_CROWDAGENT_STATE_INVALID, // < Agent 未处于有效状态。
DT_CROWDAGENT_STATE_WALKING, // < The agent is traversing a normal navigation mesh polygon. DT_CROWDAGENT_STATE_WALKING, // < 代理正在遍历普通导航网格多边形。
DT_CROWDAGENT_STATE_OFFMESH, // < The agent is traversing an off-mesh connection. DT_CROWDAGENT_STATE_OFFMESH, // < 代理正在遍历网格外连接。
}; };
} }

View File

@ -2,12 +2,19 @@
{ {
public enum DtMoveRequestState public enum DtMoveRequestState
{ {
// 无目标状态
DT_CROWDAGENT_TARGET_NONE, DT_CROWDAGENT_TARGET_NONE,
// 目标设置失败
DT_CROWDAGENT_TARGET_FAILED, DT_CROWDAGENT_TARGET_FAILED,
// 目标有效
DT_CROWDAGENT_TARGET_VALID, DT_CROWDAGENT_TARGET_VALID,
// 正在请求目标
DT_CROWDAGENT_TARGET_REQUESTING, DT_CROWDAGENT_TARGET_REQUESTING,
// 正在等待队列处理
DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE, DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE,
// 正在等待路径规划
DT_CROWDAGENT_TARGET_WAITING_FOR_PATH, DT_CROWDAGENT_TARGET_WAITING_FOR_PATH,
// 正在以特定速度移动(可能指向目标或进行其他移动)
DT_CROWDAGENT_TARGET_VELOCITY, DT_CROWDAGENT_TARGET_VELOCITY,
}; };
} }

View File

@ -111,6 +111,15 @@ namespace JNGame.Math
#endregion #endregion
public static LFloat Build1000(int val)
{
return new LFloat("", val);
}
public static LFloat Build(int val)
{
return new LFloat(val);
}
public LFloat SetInfinite(bool isInfinite) public LFloat SetInfinite(bool isInfinite)
{ {
this.isInfinite = 0; this.isInfinite = 0;
@ -614,6 +623,11 @@ namespace JNGame.Math
public static readonly LFloat EPS_1MS = new LFloat(null, 1L); public static readonly LFloat EPS_1MS = new LFloat(null, 1L);
/// <summary>
/// 10
/// </summary>
public static readonly LFloat L1 = 1.ToLFloat();
/// <summary> /// <summary>
/// 10 /// 10
/// </summary> /// </summary>

View File

@ -170,10 +170,10 @@ namespace Entitas.VisualDebugging.Unity.Editor
var debugSystemsBehaviour = gameObject.GetComponent<DebugSystemsBehaviour>(); var debugSystemsBehaviour = gameObject.GetComponent<DebugSystemsBehaviour>();
if (debugSystemsBehaviour != null) if (debugSystemsBehaviour != null)
{ {
if (debugSystemsBehaviour.systems.executeDuration < _systemWarningThreshold) // if (debugSystemsBehaviour.systems.executeDuration < _systemWarningThreshold)
GUI.DrawTexture(rect, systemsHierarchyIcon); // GUI.DrawTexture(rect, systemsHierarchyIcon);
else // else
GUI.DrawTexture(rect, systemsWarnHierarchyIcon); // GUI.DrawTexture(rect, systemsWarnHierarchyIcon);
} }
} }
} }

View File

@ -11,9 +11,9 @@ namespace JNGame.Sync.State.Tile.Entity
public class JNTileContext<T> : JNContext<T> where T : JNTileEntity, new() public class JNTileContext<T> : JNContext<T> where T : JNTileEntity, new()
{ {
private JNSSTileServerService SyncTile => base.Sync as JNSSTileServerService; private JNSSTileServerService SyncTile => Sync as JNSSTileServerService;
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
foreach (var entity in base.GetEntities()) foreach (var entity in base.GetEntities())
{ {
@ -21,6 +21,10 @@ namespace JNGame.Sync.State.Tile.Entity
//生命周期 //生命周期
bool isContains = SyncTile.IsContains(entity.Position); bool isContains = SyncTile.IsContains(entity.Position);
bool isHost = entity.IsHost; bool isHost = entity.IsHost;
//从服务器 如果数据不是自己创建的则自己永远没有权限
if (SyncTile.IsSlave && !(entity.IsSelfCreate)) isContains = false;
entity.IsHost = isContains; entity.IsHost = isContains;
//区块进入生命周期 //区块进入生命周期
@ -37,28 +41,36 @@ namespace JNGame.Sync.State.Tile.Entity
//判断实体是否在所属区块 在则 更新 //判断实体是否在所属区块 在则 更新
if (entity.IsHost) if (entity.IsHost)
{ {
entity.OnSyncUpdate(); entity.OnSyncUpdate(dt);
} }
} }
} }
public override T CreateEntity()
{
var entity = NewEntity();
BindInitialize(entity);
entity.IsHost = true;
entity.IsSelfCreate = true;
BindComponent(entity);
BindLifeCycle(entity);
return entity;
}
public T TileSyncCreate(ulong id) public T TileSyncCreate(ulong id)
{ {
//判断是否有这个Id实体 //判断是否有这个Id实体
foreach (var data in GetEntities()) if (Entities.ContainsKey(id))
{
if (data.Id == id)
{ {
Debug.Log("重复Id实体创建"); Debug.Log("重复Id实体创建");
return null; return null;
} }
}
var entity = NewEntity(); var entity = NewEntity();
entity.OnInit(this,id); entity.OnInit(this,id);
entity.IsHost = false; entity.IsHost = false;
entity.IsSelfCreate = false;
BindComponent(entity); BindComponent(entity);
BindLifeCycle(entity); BindLifeCycle(entity);
return entity; return entity;

View File

@ -43,13 +43,42 @@ namespace JNGame.Sync.State.Tile.Entity
/// </summary> /// </summary>
public bool IsHost { get; set; } = false; public bool IsHost { get; set; } = false;
/// <summary>
/// 是否自己服务器创建
/// </summary>
public bool IsSelfCreate { get; set; } = false;
/// <summary> /// <summary>
/// 是否将数据同步到从服务器 /// 是否将数据同步到从服务器
/// </summary> /// </summary>
public bool IsSyncSlave { get; set; } = false; public bool IsSyncSlave { get; set; } = false;
/// <summary> /// <summary>
/// 是否将数据同步到主服务器 /// 是否将数据同步到主服务器 (目前没有这个场景 压根想不到这个场景使用所以遗弃)
/// 其中一个场景就是 主服务器的玩家要攻击从服务器的实体
/// 这个场景是不可能遇到的 因为 违背的设计
/// 1. 从服务器是用来解决主服务器实体多 导致同步流量高 而出现的解决方案
/// 如果将从服务器的实体同步到主服务器那么就违背了设计思路 导致主服务器流量增加
/// 2. 这种场景直接主服务器创建这个实体就可以了 没必要 从 从服务器里创建在同步给主服务器 多此一举
///
/// 衍生问题 : 多人大乱斗的场景怎么办
/// 1. 主从服务器的模式并不能解决这个场景 主从服务器解决的场景有两种:
/// 1.主从服务器适用的场景是所有人攻击主服务器的某个实体 比如世界 Boss
/// 2.可以作为独立服务器存在 比如一个区块人满了 就创建一个独立的服务器
/// 让后面的人加入到新的服务器中 比如逆水寒右上角选择分场景 这时候的
/// 从服务器是不会和主服务器有任何交集的
/// 2. 如果要解决多人大乱斗的场景 怎么解决 ?
/// 1.解决这个问题的首先 要知道问题所在 问题的所在也是玩家多了之后同步
/// 的实体就会很多 怎么解决?
/// 2.这时候要引出另一种架构 主服务器 - [list]数据层服务器 - [list]玩家
/// 通过中间的数据层服务器去给玩家发送状态从而解决主服务器流量压力
/// 3.主服务器每次更新状态时候 将状态分别发送给 所有数据层服务器 有玩家
/// 加入就给玩家分配其中一个数据层服务器 通过这个数据层服务器 去同步
/// 数据
/// 4.当然 上面的是解决主服务压力 如果场景很多实体 会出现同步实体过多
/// 导致客户端接受到的状态数据非常多 从而客户端也有流量压力 所以这时候
/// 数据层服务器要增加一个功能 通过玩家位置 发送附近的状态数据 和 过滤
/// 指定实体来解决客户端流量压力 (这种优化点适用任何的状态同步)
/// </summary> /// </summary>
public bool IsSyncMaster { get; set; } = false; public bool IsSyncMaster { get; set; } = false;

View File

@ -7,6 +7,13 @@ namespace JNGame.Sync.Frame.Entity.Component.Components
{ {
public class JNTransformComponent : JNComponent public class JNTransformComponent : JNComponent
{ {
public LVector3 Position = new(); public LVector3 Position = new();
public bool IsRange(LVector3 target,LFloat len)
{
return LVector3.Distance(Position, target) <= len;
}
} }
} }

View File

@ -24,7 +24,7 @@ namespace JNGame.Sync.Entity.Component
//生命周期 //生命周期
public virtual void OnSyncStart(){} public virtual void OnSyncStart(){}
public virtual void OnSyncUpdate(){} public virtual void OnSyncUpdate(int dt){}
public virtual void OnSyncDestroy(){} public virtual void OnSyncDestroy(){}
} }
} }

View File

@ -88,7 +88,7 @@ namespace JNGame.Sync.Frame.Entity
return entity; return entity;
} }
public sealed override T CreateEntity() public override T CreateEntity()
{ {
var entity = NewEntity(); var entity = NewEntity();
BindInitialize(entity); BindInitialize(entity);
@ -100,14 +100,14 @@ namespace JNGame.Sync.Frame.Entity
//帧同步 生命周期 //帧同步 生命周期
public virtual void OnSyncStart(){} public virtual void OnSyncStart(){}
public virtual void OnSyncUpdate() public virtual void OnSyncUpdate(int dt)
{ {
//给实体推帧 //给实体推帧
foreach (var entity in GetEntities()) foreach (var entity in GetEntities())
{ {
if (entity.isEnabled) if (entity.isEnabled)
{ {
entity.OnSyncUpdate(); entity.OnSyncUpdate(dt);
} }
} }
} }

View File

@ -23,7 +23,7 @@ namespace JNGame.Sync.Entity
{ {
for (var i = 0; i < allContexts.Length; i++) for (var i = 0; i < allContexts.Length; i++)
{ {
(allContexts[i] as IJNContext)?.OnSyncUpdate(); (allContexts[i] as IJNContext)?.OnSyncUpdate(Sync.DeltaTime);
} }
} }

View File

@ -136,12 +136,12 @@ namespace JNGame.Sync.Entity
//生命周期 //生命周期
public virtual void OnSyncStart(){} public virtual void OnSyncStart(){}
public virtual void OnSyncUpdate() public virtual void OnSyncUpdate(int dt)
{ {
//给组件推帧 //给组件推帧
foreach (var component in GetComponents()) foreach (var component in GetComponents())
{ {
(component as JNComponent)?.OnSyncUpdate(); (component as JNComponent)?.OnSyncUpdate(dt);
} }
} }

View File

@ -14,7 +14,7 @@
/// <summary> /// <summary>
/// 实体每帧刷新 /// 实体每帧刷新
/// </summary> /// </summary>
public void OnSyncUpdate(); public void OnSyncUpdate(int dt);
/// <summary> /// <summary>
/// 实体销毁 /// 实体销毁

View File

@ -116,13 +116,13 @@ namespace JNGame.Sync.Frame
if (syncSystemInfos[i].isActive){ if (syncSystemInfos[i].isActive){
var time = DateTime.Now.Ticks; var time = DateTime.Now.Ticks;
_syncSystems[i].OnSyncUpdate(); _syncSystems[i].OnSyncUpdate(DeltaTime);
double time1 = (DateTime.Now.Ticks - time) / 10000f; double time1 = (DateTime.Now.Ticks - time) / 10000f;
syncSystemInfos[i].AddSyncUpdateDuration(time1); syncSystemInfos[i].AddSyncUpdateDuration(time1);
} }
#else #else
_syncSystems[i].OnSyncUpdate(); _syncSystems[i].OnSyncUpdate(DeltaTime);
#endif #endif
} }

View File

@ -7,7 +7,7 @@
public abstract class SFrameDataSystem<T> : SDataSystem<T> where T : ISData,new() public abstract class SFrameDataSystem<T> : SDataSystem<T> where T : ISData,new()
{ {
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
Data = GetLatest(); Data = GetLatest();
} }

View File

@ -71,14 +71,21 @@ namespace JNGame.Sync.System.Data
public bool isServer => Type is SStateDataEnum.ServerClient or SStateDataEnum.Server; public bool isServer => Type is SStateDataEnum.ServerClient or SStateDataEnum.Server;
public bool isClient => Type is SStateDataEnum.ServerClient or SStateDataEnum.Client; public bool isClient => Type is SStateDataEnum.ServerClient or SStateDataEnum.Client;
//待插入的数据
private Queue<Dictionary<ulong, byte[]>> WaitUBytes = new ();
protected SStateDataSystem(SStateDataEnum type) protected SStateDataSystem(SStateDataEnum type)
{ {
Type = type; Type = type;
} }
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
while (WaitUBytes.Count > 0)
{
OnUByteUpdate(WaitUBytes.Dequeue());
}
//服务器: 发送最近数据 //服务器: 发送最近数据
if (isServer) if (isServer)
@ -125,8 +132,7 @@ namespace JNGame.Sync.System.Data
/// <returns></returns> /// <returns></returns>
public void OnInsertUBytes(Dictionary<ulong, byte[]> bytes) public void OnInsertUBytes(Dictionary<ulong, byte[]> bytes)
{ {
//提交数据更新 WaitUBytes.Enqueue(bytes);
OnUByteUpdate(bytes);
} }
/// <summary> /// <summary>

View File

@ -78,6 +78,26 @@ namespace JNGame.Sync.System.Data
{ {
} }
public override Dictionary<ulong, T> GetLatest()
{
var nodes = new Dictionary<ulong, T>();
E[] entities = null;
if (IsMaster)
{
entities = NodeContext.GetHostEntities();
}else if (IsSlave)
{
entities = NodeContext.GetEntities();
}
entities.ForEach(child =>
{
var entity = new T();
entity.BindEntity(child);
nodes.Add(child.Id,entity);
});
return nodes;
}
public override void OnUByteUpdate(Dictionary<ulong, byte[]> bytes) public override void OnUByteUpdate(Dictionary<ulong, byte[]> bytes)
{ {
base.OnUByteUpdate(bytes); base.OnUByteUpdate(bytes);
@ -153,6 +173,9 @@ namespace JNGame.Sync.System.Data
foreach (var keyValue in lIsTileData) foreach (var keyValue in lIsTileData)
{ {
var entity = NodeContext.TileSyncCreate(keyValue.Key); var entity = NodeContext.TileSyncCreate(keyValue.Key);
//如果当前是从服务器则同步的实体都是 从 主服务器 同步给 从服务器
if (IsSlave) entity.IsSyncSlave = true;
entity?.TileSyncData(keyValue.Value); entity?.TileSyncData(keyValue.Value);
//将实体绑定到数据中 //将实体绑定到数据中
keyValue.Value.BindEntity(entity); keyValue.Value.BindEntity(entity);
@ -164,13 +187,19 @@ namespace JNGame.Sync.System.Data
public override void Update(T data) public override void Update(T data)
{ {
var entity = NodeContext.Query(data.Id); var entity = NodeContext.Query(data.Id);
if (IsMaster)
{
if (entity is null || !entity.IsHost) return; if (entity is null || !entity.IsHost) return;
}
base.Update(data); base.Update(data);
} }
public override void Add(T data) public override void Add(T data)
{ {
var entity = NodeContext.Query(data.Id); var entity = NodeContext.Query(data.Id);
if (IsMaster)
{
if (entity is null || !entity.IsHost) return; if (entity is null || !entity.IsHost) return;
}
base.Add(data); base.Add(data);
} }

View File

@ -79,9 +79,9 @@ namespace JNGame.Sync.System.View
} }
} }
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
UpdateSInputs(); UpdateSInputs();
} }

View File

@ -41,7 +41,7 @@ namespace JNGame.Sync.System
{ {
public abstract void OnSyncStart(); public abstract void OnSyncStart();
public abstract void OnSyncUpdate(); public abstract void OnSyncUpdate(int dt);
public virtual void OnSyncDestroy() public virtual void OnSyncDestroy()
{ } { }

View File

@ -23,7 +23,7 @@ namespace JNGame.Sync.System
} }
public virtual void OnSyncUpdate() public virtual void OnSyncUpdate(int dt)
{ {
} }

View File

@ -12,7 +12,7 @@ namespace JNGame.Sync.System
public virtual void OnSyncStart() public virtual void OnSyncStart()
{ {
} }
public virtual void OnSyncUpdate() public virtual void OnSyncUpdate(int dt)
{ {
} }
public virtual void OnSyncDestroy() public virtual void OnSyncDestroy()

View File

@ -2,6 +2,7 @@
using DotRecast.Core.Collections; using DotRecast.Core.Collections;
using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Contexts; using Game.JNGFrame.Logic.Entity.Contexts;
using Game.Logic.Entity.Nodes;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;
using JNGame.Sync.System.Data; using JNGame.Sync.System.Data;
using UnityEngine; using UnityEngine;

View File

@ -6,6 +6,7 @@ using DotRecast.Core.Collections;
using Entitas; using Entitas;
using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Contexts; using Game.JNGFrame.Logic.Entity.Contexts;
using Game.Logic.Entity.Nodes;
using JNGame.Math; using JNGame.Math;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;
using JNGame.Sync.System; using JNGame.Sync.System;

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using DotRecast.Core.Collections; using DotRecast.Core.Collections;
using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Contexts; using Game.JNGFrame.Logic.Entity.Contexts;
using Game.Logic.Entity.Nodes;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;
using JNGame.Sync.System; using JNGame.Sync.System;
using JNGame.Sync.System.Data; using JNGame.Sync.System.Data;

View File

@ -115,18 +115,6 @@ namespace Game.JNGState.Logic.Data
{ {
} }
public override Dictionary<ulong, T> GetLatest()
{
var nodes = new Dictionary<ulong, T>();
NodeContext.GetHostEntities().ForEach(child =>
{
var entity = new T();
entity.BindEntity(child);
nodes.Add(child.Id,entity);
});
return nodes;
}
public override void OnSendAllData(Dictionary<ulong, byte[]> bytes) public override void OnSendAllData(Dictionary<ulong, byte[]> bytes)
{ {
JNStateItemData player = new JNStateItemData(); //玩家状态数据 JNStateItemData player = new JNStateItemData(); //玩家状态数据

View File

@ -0,0 +1,30 @@
using JNGame.Math;
using JNGame.Sync.Frame.Service;
using JNGame.Sync.State.Tile;
using JNGame.Sync.State.Tile.Entity;
namespace Game.Logic.Entity
{
public abstract class EDEntityBasis : JNTileEntity
{
public JNRandomSystem Random => Context.GetSync().GetSystem<JNRandomSystem>();
//获取当前权限瓦块随机点
public LVector3 GetTileRandom()
{
if (Context.GetSync() is JNSSTileServerService tileServer)
{
return new LVector3(
Random.Float(tileServer.MinContains.x,tileServer.MaxContains.x),
LFloat.Zero,
Random.Float(tileServer.MinContains.y,tileServer.MaxContains.y)
);
}
return LVector3.Down;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b0f4f8b42fdc465b9ad60b8e574aa996
timeCreated: 1725096772

View File

@ -1,15 +1,14 @@
using DotRecast.Detour.Crowd; using System;
using DotRecast.Detour.Crowd;
using Game.Logic.System.Usual; using Game.Logic.System.Usual;
using JNGame.Math; using JNGame.Math;
using JNGame.Sync.Entity.Component;
using JNGame.Sync.State.Tile.Entity.Component;
namespace Game.JNGFrame.Logic.Entity.Components namespace Game.Logic.Entity.Nodes.Component.Components
{ {
/// <summary> /// <summary>
/// 移动组件 /// 移动组件
/// </summary> /// </summary>
public class EDMoveComponent : JNTileComponent public class EDMoveComponent : EDEntityComponent
{ {
public DMapSystem Map => GetSystem<DMapSystem>(); public DMapSystem Map => GetSystem<DMapSystem>();
@ -35,6 +34,16 @@ namespace Game.JNGFrame.Logic.Entity.Components
} }
} }
public LVector3 MoveTarget
{
get
{
DtCrowdAgent agent = Map.GetAgent(Entity.Id);
if (agent is null) return LVector3.Zero;
return new LVector3(agent.targetPos.X,agent.targetPos.Y,agent.targetPos.Z);
}
}
public override void OnSyncStart() public override void OnSyncStart()
{ {
base.OnSyncStart(); base.OnSyncStart();
@ -98,11 +107,19 @@ namespace Game.JNGFrame.Logic.Entity.Components
Map.VectorMoveAgent(Entity.Id, vector * Speed); Map.VectorMoveAgent(Entity.Id, vector * Speed);
} }
public override void OnSyncUpdate() public bool IsNearTarget()
{ {
base.OnSyncUpdate(); if (MoveTarget == LVector3.Zero) return true;
DtCrowdAgent agent = Map.GetAgent(Entity.Id);
return EntityBasis.Transform.IsRange(MoveTarget, LFloat.L1 + agent.option.radius);
}
public override void OnSyncUpdate(int dt)
{
base.OnSyncUpdate(dt);
var npos = Map.GetAgent(Entity.Id).npos; var npos = Map.GetAgent(Entity.Id).npos;
Entity.Transform.Position = new LVector3((LFloat)npos.X, (LFloat)npos.Y, (LFloat)npos.Z); Entity.Transform.Position = new LVector3((LFloat)npos.X, (LFloat)npos.Y, (LFloat)npos.Z);
} }
public override void OnSyncDestroy() public override void OnSyncDestroy()

View File

@ -1,5 +1,6 @@
using Game.Input; using Game.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Components; using Game.Logic.Entity.Nodes.Component;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Math; using JNGame.Math;
using JNGame.Sync.State.Tile.Entity.Component; using JNGame.Sync.State.Tile.Entity.Component;
@ -8,14 +9,35 @@ namespace Game.JNGFrame.Logic.Entity.Controller
/// <summary> /// <summary>
/// Boss控制器 /// Boss控制器
/// </summary> /// </summary>
public class EDBossController : JNTileComponent public class EDBossController : EDEntityComponent
{ {
public EDMoveComponent Move => Entity.GetComponent<EDMoveComponent>();
public override void OnSyncStart() public override void OnSyncStart()
{ {
base.OnSyncStart(); base.OnSyncStart();
//Boss 同步到从服务器 //Boss 同步到从服务器
TileEntity.IsSyncSlave = true; TileEntity.IsSyncSlave = true;
Move.Speed = LFloat.L10;
} }
public override void OnSyncUpdate(int dt)
{
base.OnSyncUpdate(dt);
// 到达目标则移动
if (Move.IsNearTarget())
{
Move.Go(EntityBasis.GetTileRandom());
}
}
} }
} }

View File

@ -1,14 +1,14 @@
using Game.Input; using Game.Input;
using Game.JNGFrame.Logic.Entity.Components; using Game.Logic.Entity.Nodes.Component;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Math; using JNGame.Math;
using JNGame.Sync.State.Tile.Entity.Component;
namespace Game.JNGFrame.Logic.Entity.Controller namespace Game.JNGFrame.Logic.Entity.Controller
{ {
/// <summary> /// <summary>
/// 角色控制器 /// 角色控制器
/// </summary> /// </summary>
public class EDPlayerController : JNTileComponent public class EDPlayerController : EDEntityComponent
{ {
/// <summary> /// <summary>
@ -37,9 +37,9 @@ namespace Game.JNGFrame.Logic.Entity.Controller
Move.Speed = LFloat.L10; Move.Speed = LFloat.L10;
} }
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
OnMoveUpdate(); OnMoveUpdate();
} }

View File

@ -0,0 +1,11 @@
using JNGame.Sync.State.Tile.Entity.Component;
namespace Game.Logic.Entity.Nodes.Component
{
public class EDEntityComponent : JNTileComponent
{
public EDEntityBasis EntityBasis => Entity as EDEntityBasis;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c880d909098c44d59b5ec8d009dc1fe4
timeCreated: 1725097481

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 835547007d6f4d88a441f5c4e782b103
timeCreated: 1725097492

View File

@ -1,9 +1,10 @@
using System; using System;
using Game.JNGFrame.Logic.Entity.Controller; using Game.JNGFrame.Logic.Entity.Controller;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.Frame.Entity.Components;
using JNGame.Util.Types; using JNGame.Util.Types;
namespace Game.JNGFrame.Logic.Entity.Components namespace Game.Logic.Entity.Nodes.Component.Lookup
{ {
public class EDBoosLookup : JNEntityLookup public class EDBoosLookup : JNEntityLookup
{ {

View File

@ -1,8 +1,9 @@
using System; using System;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.Frame.Entity.Components;
using JNGame.Util.Types; using JNGame.Util.Types;
namespace Game.JNGFrame.Logic.Entity.Components namespace Game.Logic.Entity.Nodes.Component.Lookup
{ {
public class EDNodeLookup : JNEntityLookup public class EDNodeLookup : JNEntityLookup
{ {

View File

@ -1,10 +1,10 @@
using System; using System;
using Game.JNGFrame.Logic.Entity.Controller; using Game.JNGFrame.Logic.Entity.Controller;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.Frame.Entity.Components;
using JNGame.Util.Types; using JNGame.Util.Types;
using UnityEngine;
namespace Game.JNGFrame.Logic.Entity.Components namespace Game.Logic.Entity.Nodes.Component.Lookup
{ {
public class EDPlayerLookup : JNEntityLookup public class EDPlayerLookup : JNEntityLookup
{ {

View File

@ -1,5 +1,6 @@
using Game.JNGFrame.Logic.Entity.Components; using Game.JNGFrame.Logic.Entity.Controller;
using Game.JNGFrame.Logic.Entity.Controller; using Game.Logic.Entity.Nodes;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Sync.Frame.Entity; using JNGame.Sync.Frame.Entity;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;

View File

@ -1,4 +1,5 @@
using Game.JNGFrame.Logic.Entity.Components; using Game.Logic.Entity.Nodes;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Sync.Frame.Entity; using JNGame.Sync.Frame.Entity;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;

View File

@ -1,5 +1,6 @@
using Game.JNGFrame.Logic.Entity.Components; using Game.JNGFrame.Logic.Entity.Controller;
using Game.JNGFrame.Logic.Entity.Controller; using Game.Logic.Entity.Nodes;
using Game.Logic.Entity.Nodes.Component.Components;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;
namespace Game.JNGFrame.Logic.Entity.Contexts namespace Game.JNGFrame.Logic.Entity.Contexts

View File

@ -1,14 +1,13 @@
using Game.JNGFrame.Logic.Entity.Components; using Game.JNGFrame.Logic.Entity.Controller;
using Game.JNGFrame.Logic.Entity.Controller;
using Game.JNGState.Logic.Data; using Game.JNGState.Logic.Data;
using Game.Logic.Entity.Nodes.Component.Components;
using Game.Logic.Entity.Nodes.Component.Lookup;
using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.Frame.Entity.Components;
using JNGame.Sync.State.Tile.Entity;
using JNGame.Sync.System.Data; using JNGame.Sync.System.Data;
using NotImplementedException = System.NotImplementedException;
namespace Game.JNGFrame.Logic.Entity namespace Game.Logic.Entity.Nodes
{ {
public class EDBoss : JNTileEntity public class EDBoss : EDEntityBasis
{ {
public EDMoveComponent Move => CLookup.Query<EDMoveComponent>(this); public EDMoveComponent Move => CLookup.Query<EDMoveComponent>(this);

View File

@ -1,13 +1,13 @@
using Game.JNGFrame.Logic.Entity.Components; using Game.JNGState.Logic.Data;
using Game.JNGState.Logic.Data; using Game.Logic.Entity.Nodes.Component.Components;
using Game.Logic.Entity.Nodes.Component.Lookup;
using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.Frame.Entity.Components;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;
using JNGame.Sync.System.Data; using JNGame.Sync.System.Data;
using NotImplementedException = System.NotImplementedException;
namespace Game.JNGFrame.Logic.Entity namespace Game.Logic.Entity.Nodes
{ {
public class EDNode : JNTileEntity public class EDNode : EDEntityBasis
{ {
public EDMoveComponent Move => CLookup.Query<EDMoveComponent>(this); public EDMoveComponent Move => CLookup.Query<EDMoveComponent>(this);

View File

@ -1,15 +1,14 @@
using Game.JNGFrame.Logic.Entity.Components; using Game.JNGFrame.Logic.Entity.Controller;
using Game.JNGFrame.Logic.Entity.Controller;
using Game.JNGState.Logic.Data; using Game.JNGState.Logic.Data;
using JNGame.Math; using Game.Logic.Entity.Nodes.Component.Components;
using Game.Logic.Entity.Nodes.Component.Lookup;
using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.Frame.Entity.Components;
using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.State.Tile.Entity;
using JNGame.Sync.System.Data; using JNGame.Sync.System.Data;
using NotImplementedException = System.NotImplementedException;
namespace Game.JNGFrame.Logic.Entity namespace Game.Logic.Entity.Nodes
{ {
public class EDPlayer : JNTileEntity public class EDPlayer : EDEntityBasis
{ {
public EDMoveComponent Move => CLookup.Query<EDMoveComponent>(this); public EDMoveComponent Move => CLookup.Query<EDMoveComponent>(this);

View File

@ -2,6 +2,7 @@
using Game.Input; using Game.Input;
using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Contexts; using Game.JNGFrame.Logic.Entity.Contexts;
using Game.Logic.Entity.Nodes;
using JNGame.Math; using JNGame.Math;
namespace Game.Logic.System.Logic namespace Game.Logic.System.Logic
@ -18,9 +19,9 @@ namespace Game.Logic.System.Logic
public DInputSystem Input => GetSystem<DInputSystem>(); public DInputSystem Input => GetSystem<DInputSystem>();
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
//创建Boss //创建Boss
GetSystem<DInputSystem>().SInput<IDWorld>().ForEach(child => GetSystem<DInputSystem>().SInput<IDWorld>().ForEach(child =>

View File

@ -2,6 +2,7 @@
using Game.Input; using Game.Input;
using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Contexts; using Game.JNGFrame.Logic.Entity.Contexts;
using Game.Logic.Entity.Nodes;
using JNGame.Math; using JNGame.Math;
namespace Game.Logic.System.Logic namespace Game.Logic.System.Logic
@ -18,9 +19,9 @@ namespace Game.Logic.System.Logic
public DInputSystem Input => GetSystem<DInputSystem>(); public DInputSystem Input => GetSystem<DInputSystem>();
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
//创建角色 //创建角色
GetSystem<DInputSystem>().SInput<IDWorld>().ForEach(child => GetSystem<DInputSystem>().SInput<IDWorld>().ForEach(child =>

View File

@ -2,6 +2,7 @@
using Game.Input; using Game.Input;
using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.Entity;
using Game.JNGFrame.Logic.Entity.Contexts; using Game.JNGFrame.Logic.Entity.Contexts;
using Game.Logic.Entity.Nodes;
using JNGame.Math; using JNGame.Math;
namespace Game.Logic.System.Logic namespace Game.Logic.System.Logic
@ -16,10 +17,10 @@ namespace Game.Logic.System.Logic
//Node 第一个节点 //Node 第一个节点
public Queue<EDNode> NodeQueue = new(); public Queue<EDNode> NodeQueue = new();
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
if (GetSystem<DInputSystem>().SInputOne<IDWorld>() is not IDWorld { IsAdd: true }) return; if (GetSystem<DInputSystem>().SInputOne<IDWorld>() is not IDWorld { IsAdd: true }) return;
//超过500 则 销毁第一个实体 //超过500 则 销毁第一个实体

View File

@ -23,9 +23,9 @@ namespace Game.Logic.System.Usual
Debug.Log($"DemoMapService - 加载完成地图"); Debug.Log($"DemoMapService - 加载完成地图");
} }
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
Root.Update(new LFloat(null,Sync.DeltaTime)); Root.Update(new LFloat(null,Sync.DeltaTime));
} }

View File

@ -18,9 +18,9 @@ namespace Game.JNGFrame.View
}; };
} }
public override void OnSyncUpdate() public override void OnSyncUpdate(int dt)
{ {
base.OnSyncUpdate(); base.OnSyncUpdate(dt);
foreach (var view in views) foreach (var view in views)
{ {
view.Execute(); view.Execute();