forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinearDashpotBehaviour.cs
More file actions
120 lines (99 loc) · 4.05 KB
/
Copy pathLinearDashpotBehaviour.cs
File metadata and controls
120 lines (99 loc) · 4.05 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
110
111
112
113
114
115
116
117
118
119
using System;
using Unity.Physics;
using Unity.Physics.Extensions;
using Unity.Physics.Systems;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics.Authoring;
using UnityEngine;
/*
* Issues:
* - setting up constraints if not using GameObjects
* - providing utility functions for Component and Direct data manipulation
* - assigning multiple Components of the same type to a single Entity
*/
public struct LinearDashpot : IComponentData
{
public Entity localEntity;
public float3 localOffset;
public Entity parentEntity;
public float3 parentOffset;
public int dontApplyImpulseToParent;
public float strength;
public float damping;
}
public class LinearDashpotBehaviour : MonoBehaviour, IConvertGameObjectToEntity
{
public PhysicsBody parentBody;
public float3 parentOffset;
public float3 localOffset;
public bool dontApplyImpulseToParent = false;
public float strength;
public float damping;
void OnEnable() { }
void IConvertGameObjectToEntity.Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
if (enabled)
{
// Note: GetPrimaryEntity currently creates a new Entity
// if the parentBody is not a child in the scene hierarchy
var componentData = new LinearDashpot
{
localEntity = entity,
localOffset = localOffset,
parentEntity = parentBody == null ? Entity.Null : conversionSystem.GetPrimaryEntity(parentBody),
parentOffset = parentOffset,
dontApplyImpulseToParent = dontApplyImpulseToParent ? 1 : 0,
strength = strength,
damping = damping
};
ComponentType[] componentTypes = new ComponentType[] { typeof(LinearDashpot) };
Entity dashpotEntity = dstManager.CreateEntity(componentTypes);
#if UNITY_EDITOR
var nameEntityA = dstManager.GetName(componentData.localEntity);
var nameEntityB = dstManager.GetName(componentData.parentEntity);
dstManager.SetName(dashpotEntity, $"LinearDashpot({nameEntityA},{nameEntityB})");
#endif
dstManager.SetComponentData(dashpotEntity, componentData);
}
}
}
#region System
[UpdateAfter(typeof(BuildPhysicsWorld)), UpdateBefore(typeof(StepPhysicsWorld))]
public class LinearDashpotSystem : ComponentSystem
{
BuildPhysicsWorld m_BuildPhysicsWorldSystem;
protected override void OnCreate()
{
m_BuildPhysicsWorldSystem = World.GetOrCreateSystem<BuildPhysicsWorld>();
}
protected override void OnUpdate()
{
// Make sure the world has finished building before querying it
m_BuildPhysicsWorldSystem.FinalJobHandle.Complete();
Entities.ForEach( (ref LinearDashpot dashpot) =>
{
if (0 == dashpot.strength)
return;
var eA = dashpot.localEntity;
var eB = dashpot.parentEntity;
var world = m_BuildPhysicsWorldSystem.PhysicsWorld;
// Find the rigid bodies in the physics world
int rbAIdx = world.GetRigidBodyIndex(eA);
int rbBIdx = world.GetRigidBodyIndex(eB);
// Calculate and apply the impulses
RigidBody rbA = rbAIdx >= 0 ? world.Bodies[rbAIdx] : RigidBody.Zero;
RigidBody rbB = rbBIdx >= 0 ? world.Bodies[rbBIdx] : RigidBody.Zero;
var posA = math.transform(rbA.WorldFromBody, dashpot.localOffset);
var posB = math.transform(rbB.WorldFromBody, dashpot.parentOffset);
var lvA = world.GetLinearVelocity(rbAIdx, posA);
var lvB = world.GetLinearVelocity(rbBIdx, posB);
var impulse = dashpot.strength * (posB - posA) + dashpot.damping * (lvB - lvA);
impulse = math.clamp(impulse, new float3(-100.0f), new float3(100.0f));
world.ApplyImpulse(rbAIdx, impulse, posA);
if (0 == dashpot.dontApplyImpulseToParent)
world.ApplyImpulse(rbBIdx, -impulse, posB);
});
}
}
#endregion