您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
130 行
5.3 KiB
130 行
5.3 KiB
using System;
|
|
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
using Unity.Jobs;
|
|
using Unity.NetCode;
|
|
using Unity.NetCode.Extensions;
|
|
using static Unity.Entities.SystemAPI;
|
|
using Random = Unity.Mathematics.Random;
|
|
|
|
namespace Unity.MegaCity.Gameplay
|
|
{
|
|
/// <summary>
|
|
/// System to set the player info.
|
|
/// </summary>
|
|
[BurstCompile]
|
|
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
|
|
public partial struct SetPlayerInfoSystem : ISystem
|
|
{
|
|
#region Jobs
|
|
|
|
[BurstCompile]
|
|
private partial struct FindAvailableNameJob : IJob
|
|
{
|
|
public NativeArray<BotNameElement> Names;
|
|
public NativeList<FixedString64Bytes> UsedNames;
|
|
public Random Random;
|
|
|
|
[BurstCompile]
|
|
public void Execute()
|
|
{
|
|
var availablePlayerNames = GetAvailableNames();
|
|
if (availablePlayerNames.Length == 0)
|
|
{
|
|
UsedNames.Clear();
|
|
availablePlayerNames = GetAvailableNames();
|
|
}
|
|
|
|
// Choose a random player name from the list of available player names
|
|
var randomIndex = Random.NextInt(0, availablePlayerNames.Length);
|
|
var botName = availablePlayerNames[randomIndex];
|
|
UsedNames.Add(botName);
|
|
}
|
|
|
|
private NativeList<FixedString64Bytes> GetAvailableNames()
|
|
{
|
|
var availablePlayerNames = new NativeList<FixedString64Bytes>(Allocator.TempJob);
|
|
|
|
// Get a list of player names that have not been used
|
|
foreach (var name in Names)
|
|
{
|
|
if (!UsedNames.Contains(name.Name))
|
|
{
|
|
availablePlayerNames.Add(name.Name);
|
|
}
|
|
}
|
|
|
|
return availablePlayerNames;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
private NativeList<FixedString64Bytes> m_UsedNames;
|
|
private Random m_Random;
|
|
private EntityQuery m_ConnectedPlayers;
|
|
|
|
public void OnCreate(ref SystemState state)
|
|
{
|
|
state.RequireForUpdate<PlayerConnectedElement>();
|
|
state.RequireForUpdate<BotNameElement>();
|
|
m_UsedNames = new NativeList<FixedString64Bytes>(Allocator.Persistent);
|
|
var seed = DateTime.Now.Ticks / (DateTime.Now.Second + DateTime.Now.Day);
|
|
m_Random = new Random((uint)seed);
|
|
m_ConnectedPlayers = state.GetEntityQuery(ComponentType.ReadOnly<GhostOwner>());
|
|
state.RequireForUpdate<ReceiveRpcCommandRequest>();
|
|
state.RequireForUpdate<SetPlayerInfoRequest>();
|
|
|
|
UnityEngine.Debug.Log("SetPlayerInfoSystem has been loaded and initialized!");
|
|
}
|
|
|
|
//TODO : Optimize for DOTS?
|
|
public void OnUpdate(ref SystemState state)
|
|
{
|
|
var playersConnected = GetSingletonBuffer<PlayerConnectedElement>();
|
|
var commandBuffer = new EntityCommandBuffer(Allocator.TempJob);
|
|
var names = GetSingletonBuffer<BotNameElement>().ToNativeArray(Allocator.TempJob);
|
|
|
|
foreach (var (info, request, requestEntity) in
|
|
Query<SetPlayerInfoRequest, ReceiveRpcCommandRequest>().WithEntityAccess())
|
|
{
|
|
var entityNetwork = request.SourceConnection;
|
|
var networkId = GetComponent<NetworkId>(entityNetwork);
|
|
|
|
foreach (var (ghostOwner, entity) in Query<RefRO<GhostOwner>>()
|
|
.WithEntityAccess())
|
|
{
|
|
if (ghostOwner.ValueRO.NetworkId == networkId.Value)
|
|
{
|
|
var findANewNameJob = new FindAvailableNameJob
|
|
{
|
|
Names = names,
|
|
UsedNames = m_UsedNames,
|
|
Random = m_Random
|
|
};
|
|
state.Dependency = findANewNameJob.Schedule(state.Dependency);
|
|
state.Dependency.Complete();
|
|
|
|
// If the requester is not a client should use one from the bank of names.
|
|
var name = info.IsClient ? info.Name : m_UsedNames[m_UsedNames.Length - 1];
|
|
var playerID = info.PlayerId;
|
|
|
|
commandBuffer.SetComponent(entity, new PlayerName { Name = name });
|
|
commandBuffer.AddComponent(entity, new MultiversePlayerID { PlayerId = playerID });
|
|
|
|
playersConnected.Add(new PlayerConnectedElement { Name = name, PlayerId = playerID, Value = entity });
|
|
UnityEngine.Debug.Log($"Client: {name} ({playerID}) has joined the game! (Thin = {!info.IsClient})\nConnected Players: {m_ConnectedPlayers.CalculateEntityCount()}");
|
|
// If any players are connected, cancel the auto shutdown task
|
|
MultiverseSDKWrapper.Instance.CancelShutdown();
|
|
break;
|
|
}
|
|
}
|
|
|
|
commandBuffer.DestroyEntity(requestEntity);
|
|
}
|
|
|
|
commandBuffer.Playback(state.EntityManager);
|
|
}
|
|
}
|
|
}
|