`
This commit is contained in:
parent
4824e84575
commit
01c68cc0b4
@ -140,6 +140,19 @@ namespace XNet.Business
|
||||
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]
|
||||
public class PlayerInitReq
|
||||
{
|
||||
|
||||
@ -50,10 +50,5 @@ namespace XNet.Business.Entity
|
||||
/// 当前线性插值欧拉角,角色朝向
|
||||
/// </summary>
|
||||
public Vec3 CurrentEuler { get; set; } = new Vec3();
|
||||
|
||||
/// <summary>
|
||||
/// 路径导航索引下标
|
||||
/// </summary>
|
||||
public int AgentIndex { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using DotRecast.Detour.Crowd;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.WebSockets;
|
||||
|
||||
namespace XNet.Business.Entity
|
||||
@ -14,5 +15,12 @@ namespace XNet.Business.Entity
|
||||
public bool IsAI { get; set; } = false;
|
||||
|
||||
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
10
XNet.Business/Global.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace XNet.Business
|
||||
{
|
||||
public class Global
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户端传上来的位置,角度等为了省流量,存成整形,这里处理成单精度浮点型要除以 LocationMultiply
|
||||
/// </summary>
|
||||
public const float LocationMultiply = 1000f;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using MessagePack;
|
||||
using System.Net.WebSockets;
|
||||
using XNet.Business.PathNavigation;
|
||||
using XNet.Business.Tank.Manager;
|
||||
|
||||
namespace XNet.Business.Net
|
||||
@ -8,11 +9,11 @@ namespace XNet.Business.Net
|
||||
{
|
||||
private static ActionManager? ActionManager = null;
|
||||
// 启动WebSocket监听
|
||||
public static void MapWebSocketServer(this WebApplication app, WsConnectionManager wsManager)
|
||||
public static void MapWebSocketServer(this WebApplication app, WsConnectionManager wsManager, NavMeshManager navMeshManager)
|
||||
{
|
||||
if (ActionManager == null)
|
||||
{
|
||||
ActionManager = new ActionManager(wsManager);
|
||||
ActionManager = new ActionManager(wsManager, navMeshManager);
|
||||
}
|
||||
app.Map("/ws", async context =>
|
||||
{
|
||||
|
||||
@ -149,12 +149,12 @@ namespace XNet.Business.PathNavigation
|
||||
/// 获取指定副本实例底层的 NavMesh 和 Query 对象
|
||||
/// 注意:返回的对象是共享资源,请勿 Dispose,也请勿修改其拓扑结构
|
||||
/// </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!;
|
||||
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;
|
||||
|
||||
navMesh = template.NavMesh;
|
||||
@ -162,13 +162,24 @@ namespace XNet.Business.PathNavigation
|
||||
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. 高性能寻路
|
||||
// ==========================================
|
||||
|
||||
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;
|
||||
|
||||
const int MAX_POLYS = 256;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using XNet.Business.Net;
|
||||
using XNet.Business.PathNavigation;
|
||||
|
||||
namespace XNet.Business.Tank.Manager
|
||||
{
|
||||
@ -11,10 +12,12 @@ namespace XNet.Business.Tank.Manager
|
||||
private readonly PlayerManager _playerManager;
|
||||
|
||||
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;
|
||||
_playerManager = new PlayerManager(wsManager, navMeshManager);
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
@ -4,15 +4,18 @@ using NanoidDotNet;
|
||||
using System.Numerics;
|
||||
using XNet.Business.Entity;
|
||||
using XNet.Business.Net;
|
||||
using XNet.Business.PathNavigation;
|
||||
|
||||
namespace XNet.Business.Tank.Manager
|
||||
{
|
||||
public class PlayerManager
|
||||
{
|
||||
private readonly WsConnectionManager _wsManager;
|
||||
public PlayerManager(WsConnectionManager wsManager)
|
||||
private readonly NavMeshManager _navMeshManager;
|
||||
public PlayerManager(WsConnectionManager wsManager, NavMeshManager navMeshManager)
|
||||
{
|
||||
_wsManager = wsManager;
|
||||
_navMeshManager = navMeshManager;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
//var playerState = _wsManager.GetConnectionInfo(connId);
|
||||
//if (playerState != null)
|
||||
//{
|
||||
// await _wsManager.SendMessageToRoomBatchAsync(playerState.FirstRoomId, data, [connId]);
|
||||
//}
|
||||
var posReq = MessagePackSerializer.Deserialize<PlayerPosReq>(data);
|
||||
if (posReq != null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ app.UseStaticFiles();
|
||||
app.UseWebSockets();
|
||||
|
||||
// 启动WebSocket服务
|
||||
app.MapWebSocketServer(app.Services.GetRequiredService<WsConnectionManager>());
|
||||
app.MapWebSocketServer(app.Services.GetRequiredService<WsConnectionManager>(), app.Services.GetRequiredService<NavMeshManager>());
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user