-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathReparentingSystem.cs
More file actions
88 lines (76 loc) · 3.59 KB
/
ReparentingSystem.cs
File metadata and controls
88 lines (76 loc) · 3.59 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
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Transforms;
using UnityEngine;
namespace HelloCube.Reparenting
{
public partial struct ReparentingSystem : ISystem
{
bool attached;
float timer;
const float interval = 0.7f;
[BurstCompile]
public void OnCreate(ref SystemState state)
{
timer = interval;
attached = true;
state.RequireForUpdate<ExecuteReparenting>();
state.RequireForUpdate<RotationSpeed>();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
timer -= SystemAPI.Time.DeltaTime;
if (timer > 0)
{
return;
}
timer = interval;
var rotatorEntity = SystemAPI.GetSingletonEntity<RotationSpeed>();
var ecb = new EntityCommandBuffer(Allocator.Temp);
if (attached)
{
// Detach all children from the rotator by removing the Parent component from the children.
// (The next time TransformSystemGroup updates, it will update the Child buffer and transforms accordingly.)
DynamicBuffer<Child> children = SystemAPI.GetBuffer<Child>(rotatorEntity);
for (int i = 0; i < children.Length; i++)
{
// Using an ECB is the best option here because calling EntityManager.RemoveComponent()
// instead would invalidate the DynamicBuffer, meaning we'd have to re-retrieve
// the DynamicBuffer after every EntityManager.RemoveComponent() call.
ecb.RemoveComponent<Parent>(children[i].Value);
}
// Alternative solution instead of the above loop:
// A single call that removes the Parent component from all entities in the array.
// Because the method expects a NativeArray<Entity>, we create a NativeArray<Entity> alias of the DynamicBuffer.
/*
ecb.RemoveComponent<Parent>(children.AsNativeArray().Reinterpret<Entity>());
*/
}
else
{
// Attach all the small cubes to the rotator by adding a Parent component to the cubes.
// (The next time TransformSystemGroup updates, it will update the Child buffer and transforms accordingly.)
var parentLocalToWorld = SystemAPI.GetComponent<LocalToWorld>(rotatorEntity);
foreach (var (localToWorld, entity) in
SystemAPI.Query<RefRO<LocalToWorld>>()
.WithNone<RotationSpeed>()
.WithEntityAccess())
{
ecb.AddComponent(entity, new Parent { Value = rotatorEntity });
float3 localPosition = math.transform(math.inverse(parentLocalToWorld.Value), localToWorld.ValueRO.Position);
ecb.SetComponent(entity, new LocalTransform { Position = localPosition, Rotation = quaternion.identity, Scale = 0.5f });
}
// Alternative solution instead of the above loop:
// Add a Parent value to all entities matching a query.
/*
var query = SystemAPI.QueryBuilder().WithAll<LocalTransform>().WithNone<RotationSpeed>().Build();
ecb.AddComponent(query, new Parent { Value = rotatorEntity });
*/
}
ecb.Playback(state.EntityManager);
attached = !attached;
}
}
}