forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShootingSystem.cs
More file actions
109 lines (98 loc) · 4.63 KB
/
Copy pathShootingSystem.cs
File metadata and controls
109 lines (98 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Transforms;
using Unity.NetCode;
namespace Samples.HelloNetcode
{
[UpdateInGroup(typeof(HelloNetcodePredictedSystemGroup))]
[RequireMatchingQueriesForUpdate]
public partial struct ShootingSystem : ISystem
{
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<NetworkTime>();
state.RequireForUpdate<Hit>();
}
public void OnDestroy(ref SystemState state)
{
}
public void OnUpdate(ref SystemState state)
{
var collisionHistory = SystemAPI.GetSingleton<PhysicsWorldHistorySingleton>();
var physicsWorld = SystemAPI.GetSingleton<PhysicsWorldSingleton>().PhysicsWorld;
var networkTime = SystemAPI.GetSingleton<NetworkTime>();
var ghostComponentFromEntity = SystemAPI.GetComponentLookup<GhostComponent>();
#if !ENABLE_TRANSFORM_V1
var scaleFromEntity = SystemAPI.GetComponentLookup<PostTransformScale>();
#else
var scaleFromEntity = SystemAPI.GetComponentLookup<NonUniformScale>();
#endif
var lagCompensationEnabledFromEntity = SystemAPI.GetComponentLookup<LagCompensationEnabled>();
var predictingTick = networkTime.ServerTick;
// Do not perform hit-scan when rolling back, only when simulating the latest tick
if (!networkTime.IsFirstTimeFullyPredictingTick)
return;
foreach (var (character, interpolationDelay, hitComponent) in SystemAPI.Query<CharacterAspect, RefRO<CommandDataInterpolationDelay>, RefRW<Hit>>().WithAll<Simulate>())
{
if (character.Input.SecondaryFire.IsSet)
{
hitComponent.ValueRW.Entity = character.Self;
hitComponent.ValueRW.Tick = predictingTick;
continue;
}
if (!character.Input.PrimaryFire.IsSet)
{
continue;
}
// Get the collision world to use given the tick currently being predicted and the interpolation delay for the connection
var delay = lagCompensationEnabledFromEntity.HasComponent(character.Self)
? interpolationDelay.ValueRO.Delay
: 0;
collisionHistory.GetCollisionWorldFromTick(predictingTick, delay, ref physicsWorld, out var collWorld);
var cameraRotation = math.mul(quaternion.RotateY(character.Input.Yaw), quaternion.RotateX(-character.Input.Pitch));
var offset = math.rotate(cameraRotation, CharacterControllerCameraSystem.k_CameraOffset);
var cameraPosition = character.Transform.LocalPosition + offset;
var forward = math.mul(cameraRotation, math.forward());
var rayInput = new RaycastInput
{
Start = cameraPosition + forward,
End = cameraPosition + forward * 1000,
Filter = CollisionFilter.Default
};
bool hit = collWorld.CastRay(rayInput, out var closestHit);
if (!hit)
{
continue;
}
var hitEntity = Entity.Null;
var hitPoint = closestHit.Position;
if (ghostComponentFromEntity.HasComponent(closestHit.Entity))
{
hitEntity = closestHit.Entity;
var rigidTransform = collWorld.Bodies[closestHit.RigidBodyIndex].WorldFromBody;
hitPoint -= rigidTransform.pos;
hitPoint = math.mul(math.inverse(rigidTransform.rot), hitPoint);
#if !ENABLE_TRANSFORM_V1
if (scaleFromEntity.HasComponent(closestHit.Entity))
{
var scaleMatrix = scaleFromEntity[closestHit.Entity].Value;
var scaleX = math.length(scaleMatrix.c0.xyz);
var scaleY = math.length(scaleMatrix.c1.xyz);
var scaleZ = math.length(scaleMatrix.c2.xyz);
hitPoint /= new float3(scaleX, scaleY, scaleZ);
}
#else
if (scaleFromEntity.HasComponent(closestHit.Entity))
{
hitPoint /= scaleFromEntity[closestHit.Entity].Value;
}
#endif
}
hitComponent.ValueRW.Entity = hitEntity;
hitComponent.ValueRW.HitPoint = hitPoint;
hitComponent.ValueRW.Tick = predictingTick;
}
}
}
}