您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
86 行
3.6 KiB
86 行
3.6 KiB
using System.Diagnostics;
|
|
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
using Unity.Mathematics;
|
|
using Unity.NetCode;
|
|
|
|
namespace Unity.MegaCity.Gameplay
|
|
{
|
|
/// <summary>
|
|
/// System to handle input for the thin client
|
|
/// </summary>
|
|
[UpdateInGroup(typeof(GhostInputSystemGroup))]
|
|
[WorldSystemFilter(WorldSystemFilterFlags.ThinClientSimulation)]
|
|
public partial struct MegaCityThinInputSystem : ISystem
|
|
{
|
|
private NativeReference<Random> m_Rand;
|
|
|
|
public void OnCreate(ref SystemState state)
|
|
{
|
|
state.RequireForUpdate<NetworkId>();
|
|
state.RequireForUpdate<NetworkStreamInGame>();
|
|
state.RequireForUpdate<NetworkTime>();
|
|
m_Rand = new NativeReference<Random>(Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
|
|
m_Rand.Value = Random.CreateFromIndex((uint) Stopwatch.GetTimestamp());
|
|
}
|
|
|
|
[BurstCompile]
|
|
public void OnDestroy(ref SystemState state)
|
|
{
|
|
m_Rand.Dispose();
|
|
}
|
|
|
|
[BurstCompile]
|
|
public void OnUpdate(ref SystemState state)
|
|
{
|
|
if (!SystemAPI.TryGetSingletonRW<CommandTarget>(out var commandTargetRw))
|
|
return;
|
|
|
|
// Ensure AI has input entity:
|
|
if (commandTargetRw.ValueRO.targetEntity == Entity.Null || !state.EntityManager.HasComponent<PlayerVehicleInput>(commandTargetRw.ValueRO.targetEntity))
|
|
{
|
|
var inputEntity = state.EntityManager.CreateEntity();
|
|
commandTargetRw.ValueRW.targetEntity = inputEntity;
|
|
|
|
var connectionId = SystemAPI.GetSingleton<NetworkId>().Value;
|
|
|
|
state.EntityManager.SetName(inputEntity, $"{nameof(MegaCityThinInputSystem)}-RandInput");
|
|
state.EntityManager.AddComponent<PlayerVehicleInput>(inputEntity);
|
|
// NOTE: The buffer type might not be recognized in your IDE but it will be generated and Unity will recognize it.
|
|
// TODO : verify this buffer
|
|
//state.EntityManager.AddBuffer<Unity.MegaCity.Gameplay.Generated.PlayerVehicleInputInputBufferData>(inputEntity);
|
|
|
|
state.EntityManager.AddComponentData(inputEntity, new GhostOwner { NetworkId = connectionId });
|
|
|
|
return; // Return as the EntityManager has now had a structural change, invalidating `commandTargetRw`.
|
|
}
|
|
|
|
// Recalculate AI action every x ticks:
|
|
var networkTime = SystemAPI.GetSingleton<NetworkTime>();
|
|
if (networkTime.ServerTick.TickIndexForValidTick % 30 == 0)
|
|
{
|
|
var input = state.EntityManager.GetComponentData<PlayerVehicleInput>(commandTargetRw.ValueRO.targetEntity);
|
|
var rand = m_Rand.Value;
|
|
|
|
// Movement:
|
|
input.ControlDirection = (rand.NextFloat3() * 2) - new float3(1);
|
|
input.GamepadDirection = (rand.NextFloat3() * 2) - new float3(1);
|
|
|
|
// Drive:
|
|
input.Acceleration = rand.NextInt() < 0.8f ? 1 : 0;
|
|
input.Brake = rand.NextInt() < 0.1f ? 1 : 0;
|
|
|
|
// Roll:
|
|
input.LeftRoll = rand.NextInt() < 0.1f ? 1 : 0;
|
|
input.RightRoll = input.LeftRoll <= 0f && rand.NextInt() < 0.1f ? 1 : 0;
|
|
|
|
// Shooting:
|
|
input.Shoot = rand.NextInt() < 0.3f;
|
|
|
|
m_Rand.Value = rand;
|
|
state.EntityManager.SetComponentData(commandTargetRw.ValueRO.targetEntity, input);
|
|
}
|
|
}
|
|
}
|
|
}
|