This commit is contained in:
wuyanchen 2025-12-30 17:55:08 +08:00
parent 4824e84575
commit 01c68cc0b4
9 changed files with 80 additions and 21 deletions

View File

@ -140,6 +140,19 @@ namespace XNet.Business
public string PlayerId { get; set; } = string.Empty; public string PlayerId { get; set; } = string.Empty;
} }
[MessagePackObject]
public class PlayerPosReq
{
[Key("roomId")]
public string RoomId { get; set; } = string.Empty;
[Key("isAI")]
public bool IsAI { get; set; } = false;
[Key("endPos")]
public Vec3? EndPos { get; set; }
}
[MessagePackObject] [MessagePackObject]
public class PlayerInitReq public class PlayerInitReq
{ {

View File

@ -50,10 +50,5 @@ namespace XNet.Business.Entity
/// 当前线性插值欧拉角,角色朝向 /// 当前线性插值欧拉角,角色朝向
/// </summary> /// </summary>
public Vec3 CurrentEuler { get; set; } = new Vec3(); public Vec3 CurrentEuler { get; set; } = new Vec3();
/// <summary>
/// 路径导航索引下标
/// </summary>
public int AgentIndex { get; set; } = 0;
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Concurrent; using DotRecast.Detour.Crowd;
using System.Collections.Concurrent;
using System.Net.WebSockets; using System.Net.WebSockets;
namespace XNet.Business.Entity namespace XNet.Business.Entity
@ -14,5 +15,12 @@ namespace XNet.Business.Entity
public bool IsAI { get; set; } = false; public bool IsAI { get; set; } = false;
public byte SetIdx { get; set; } public byte SetIdx { get; set; }
public bool IsCanControl { get; set; } = false;
/// <summary>
/// 路径导航索引
/// </summary>
public DtCrowdAgent Agent { get; set; } = null!;
} }
} }

10
XNet.Business/Global.cs Normal file
View File

@ -0,0 +1,10 @@
namespace XNet.Business
{
public class Global
{
/// <summary>
/// 客户端传上来的位置,角度等为了省流量,存成整形,这里处理成单精度浮点型要除以 LocationMultiply
/// </summary>
public const float LocationMultiply = 1000f;
}
}

View File

@ -1,5 +1,6 @@
using MessagePack; using MessagePack;
using System.Net.WebSockets; using System.Net.WebSockets;
using XNet.Business.PathNavigation;
using XNet.Business.Tank.Manager; using XNet.Business.Tank.Manager;
namespace XNet.Business.Net namespace XNet.Business.Net
@ -8,11 +9,11 @@ namespace XNet.Business.Net
{ {
private static ActionManager? ActionManager = null; private static ActionManager? ActionManager = null;
// 启动WebSocket监听 // 启动WebSocket监听
public static void MapWebSocketServer(this WebApplication app, WsConnectionManager wsManager) public static void MapWebSocketServer(this WebApplication app, WsConnectionManager wsManager, NavMeshManager navMeshManager)
{ {
if (ActionManager == null) if (ActionManager == null)
{ {
ActionManager = new ActionManager(wsManager); ActionManager = new ActionManager(wsManager, navMeshManager);
} }
app.Map("/ws", async context => app.Map("/ws", async context =>
{ {

View File

@ -149,12 +149,12 @@ namespace XNet.Business.PathNavigation
/// 获取指定副本实例底层的 NavMesh 和 Query 对象 /// 获取指定副本实例底层的 NavMesh 和 Query 对象
/// 注意:返回的对象是共享资源,请勿 Dispose也请勿修改其拓扑结构 /// 注意:返回的对象是共享资源,请勿 Dispose也请勿修改其拓扑结构
/// </summary> /// </summary>
public bool GetNavMeshAndQuery(string instanceId, out DtNavMesh navMesh, out DtNavMeshQuery query) public bool GetNavMeshAndQuery(string roomId, out DtNavMesh navMesh, out DtNavMeshQuery query)
{ {
navMesh = null!; navMesh = null!;
query = null!; query = null!;
if (!_instanceMap.TryGetValue(instanceId, out var templateId)) return false; if (!_instanceMap.TryGetValue(roomId, out var templateId)) return false;
if (!_templates.TryGetValue(templateId, out var template)) return false; if (!_templates.TryGetValue(templateId, out var template)) return false;
navMesh = template.NavMesh; navMesh = template.NavMesh;
@ -162,13 +162,24 @@ namespace XNet.Business.PathNavigation
return true; return true;
} }
public RcVec3f? GetClosetPoint(string roomId, Vector3 originPt)
{
if (!_instanceMap.TryGetValue(roomId, out var templateId)) return null;
if (!_templates.TryGetValue(templateId, out var template)) return null;
var query = template.Query;
var startPos = new RcVec3f(originPt.X, originPt.Y, originPt.Z);
query.FindNearestPoly(startPos, _extents, _filter, out long startRef, out var startPt, out var _);
return startPt;
}
// ========================================== // ==========================================
// 4. 高性能寻路 // 4. 高性能寻路
// ========================================== // ==========================================
public List<Vector3>? FindPath(string instanceId, Vector3 start, Vector3 end) public List<Vector3>? FindPath(string roomId, Vector3 start, Vector3 end)
{ {
if (!_instanceMap.TryGetValue(instanceId, out var templateId)) return null; if (!_instanceMap.TryGetValue(roomId, out var templateId)) return null;
if (!_templates.TryGetValue(templateId, out var template)) return null; if (!_templates.TryGetValue(templateId, out var template)) return null;
const int MAX_POLYS = 256; const int MAX_POLYS = 256;

View File

@ -1,5 +1,6 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using XNet.Business.Net; using XNet.Business.Net;
using XNet.Business.PathNavigation;
namespace XNet.Business.Tank.Manager namespace XNet.Business.Tank.Manager
{ {
@ -11,10 +12,12 @@ namespace XNet.Business.Tank.Manager
private readonly PlayerManager _playerManager; private readonly PlayerManager _playerManager;
private readonly WsConnectionManager _wsManager; private readonly WsConnectionManager _wsManager;
public ActionManager(WsConnectionManager wsManager) private readonly NavMeshManager _navMeshManager;
public ActionManager(WsConnectionManager wsManager, NavMeshManager navMeshManager)
{ {
_playerManager = new PlayerManager(wsManager); _navMeshManager = navMeshManager;
_wsManager = wsManager; _wsManager = wsManager;
_playerManager = new PlayerManager(wsManager, navMeshManager);
Init(); Init();
} }

View File

@ -4,15 +4,18 @@ using NanoidDotNet;
using System.Numerics; using System.Numerics;
using XNet.Business.Entity; using XNet.Business.Entity;
using XNet.Business.Net; using XNet.Business.Net;
using XNet.Business.PathNavigation;
namespace XNet.Business.Tank.Manager namespace XNet.Business.Tank.Manager
{ {
public class PlayerManager public class PlayerManager
{ {
private readonly WsConnectionManager _wsManager; private readonly WsConnectionManager _wsManager;
public PlayerManager(WsConnectionManager wsManager) private readonly NavMeshManager _navMeshManager;
public PlayerManager(WsConnectionManager wsManager, NavMeshManager navMeshManager)
{ {
_wsManager = wsManager; _wsManager = wsManager;
_navMeshManager = navMeshManager;
} }
public async Task SubcribeRoom(string connId, byte[] data) public async Task SubcribeRoom(string connId, byte[] data)
@ -239,11 +242,26 @@ namespace XNet.Business.Tank.Manager
public async Task RequestPath(string connId, byte[] data) public async Task RequestPath(string connId, byte[] data)
{ {
//var playerState = _wsManager.GetConnectionInfo(connId); var posReq = MessagePackSerializer.Deserialize<PlayerPosReq>(data);
//if (playerState != null) if (posReq != null)
//{ {
// await _wsManager.SendMessageToRoomBatchAsync(playerState.FirstRoomId, data, [connId]); var playerState = _wsManager.GetConnectionInfo(connId);
//} //if (playerState != null)
//{
// await _wsManager.SendMessageToRoomBatchAsync(playerState.FirstRoomId, data, [connId]);
//}
if (playerState != null && playerState.IsCanControl && posReq.EndPos != null)
{
var room = _wsManager.GetPlayerRoomInfo(playerState.FirstRoomId, connId);
var toPt = new Vector3(posReq.EndPos.X, posReq.EndPos.Y, posReq.EndPos.Z) / Global.LocationMultiply;
var closetPt = _navMeshManager.GetClosetPoint(room?.RoomId!, toPt);
if (closetPt != null)
{
room?.Crowd?.RequestMoveTarget(playerState.Agent, 1, closetPt.Value);
}
}
}
await Task.CompletedTask; await Task.CompletedTask;
} }
} }

View File

@ -46,7 +46,7 @@ app.UseStaticFiles();
app.UseWebSockets(); app.UseWebSockets();
// 启动WebSocket服务 // 启动WebSocket服务
app.MapWebSocketServer(app.Services.GetRequiredService<WsConnectionManager>()); app.MapWebSocketServer(app.Services.GetRequiredService<WsConnectionManager>(), app.Services.GetRequiredService<NavMeshManager>());
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())