Hi,
We are working on a prototype of a golf like game and decided to test Havok for it and we are actually really happy with how stable the physics are especially compared to PhysX. But we have hit a bump on the road (literally)
Our issue is that we need high speed precision for a ball to roll on the ground at high and slow speeds.
So for high speeds we want to enable contact point welding and disable it for slow speeds.
for this we wrote some code that changes the Custom Tag on the Ball. it looks like follows.
But we have very persisting instabilities. It does not switch properly even though in the video you can see (on the left side after minute 1:13) that it changes based on speed. What you can see in the latter part of the video that even if it should enable contact welding it completely ignores it there are a lot of ghost hits. Sometimes it enables contact welding and never disables it and that prevents the ball from going into the hole as it floats over the holes. I can make a separate video about this if requested. I can also upload the project.
Either we did the code wrong or its not possible to switch custom tags at runtime.
We didn’t find a good documentation on this stuff so a lot of trial and error was involved.
It does not have to be exactly this solution (speed based) as long as we getthe stability at high speeds and accuracy at low speeds.
We are open to new/other solutions.
Unity Version: 2021.1.2f1
Havok Physics 0.6.0 preview.3
This is the code in question. We also have another script that runs this function below this
public static void SetWeldingTags(EntityManager manager)
{
foreach (Entity entity in manager.GetAllEntities())
{
if (manager.HasComponent<PhysicsVelocity>(entity))
{
PhysicsVelocity vel = manager.GetComponentData<PhysicsVelocity>(entity);
PhysicsCustomTags customTags = manager.GetComponentData<PhysicsCustomTags>(entity);
Debug.Log(
$"Entity Velocity: {vel} Entity Index: {entity.Index} Entity Custom Tag: {customTags.Value}");
float speed = Vector3.Magnitude(new Vector3(vel.Linear.x, vel.Linear.y, vel.Linear.z));
if ( speed > 0.8f )
{
customTags.Value = 2;
}
else
{
customTags.Value = CustomPhysicsBodyTags.Nothing.Value;
}
manager.SetComponentData(entity, customTags);
}
if (manager.HasComponent<HavokConfiguration>(entity))
{
HavokConfiguration conf = manager.GetComponentData<HavokConfiguration>(entity);
manager.AddComponentData(entity, conf);
}
}
}
[UpdateBefore(typeof(Unity.Physics.Systems.BuildPhysicsWorld))]
//[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
public class FollowBall : MonoBehaviour
{
public Entity Ball;
//public float3 offset = float3.zero;
public float DifferenceDivider = 512f;
public LineRenderer LR;
[HideInInspector]
public Rotation objectRot;
private EntityManager manager;
// Update is called once per frame
private void Update()
{
EntityObjectTracker.ShootFunction(manager, Ball, LR);
EntityObjectTracker.SetWeldingTags(manager);
}
private void Awake()
{
manager = World.DefaultGameObjectInjectionWorld.EntityManager;
}
private void LateUpdate()
{
if(Ball == null) { return; }
Translation ballPos = manager.GetComponentData<Translation>(Ball);
objectRot = manager.GetComponentData<Rotation>(Ball);
// Debug.Log(mfd.ForceAmount);
transform.position = ballPos.Value;
}
}