using System.Collections.Generic; using Unity.Physics; using Unity.Physics.Extensions; using Unity.Entities; using Unity.Mathematics; using Unity.Rendering; using Unity.Transforms; using UnityEngine; using Collider = Unity.Physics.Collider; using Material = UnityEngine.Material; using Mesh = UnityEngine.Mesh; /// /// Helper for demos set up in C# rather than in the editor /// public class BasePhysicsDemo : MonoBehaviour { public static EntityManager EntityManager => World.Active.EntityManager; protected Entity stepper; public Material dynamicMaterial; public Material staticMaterial; public SimulationType StepType = SimulationType.UnityPhysics; protected void init(float3 gravity) { // Camera control GameObject mainCamera = GameObject.FindGameObjectWithTag("MainCamera"); CameraControl cameraControl = mainCamera.AddComponent(); cameraControl.lookSpeedH = 0.6f; cameraControl.lookSpeedV = 0.6f; cameraControl.zoomSpeed = 1.0f; cameraControl.dragSpeed = 4.0f; // Create the stepper EntityManager entityManager = EntityManager; ComponentType[] componentTypes = { typeof(PhysicsStep), typeof(Unity.Physics.Authoring.PhysicsDebugDisplayData), typeof(MousePick) }; stepper = entityManager.CreateEntity(componentTypes); entityManager.SetComponentData(stepper, new PhysicsStep { SimulationType = StepType, Gravity = gravity, SolverIterationCount = PhysicsStep.Default.SolverIterationCount, ThreadCountHint = PhysicsStep.Default.ThreadCountHint }); // Add options for visually debugging physics information entityManager.SetComponentData(stepper, new Unity.Physics.Authoring.PhysicsDebugDisplayData { }); // Load assets //dynamicMaterial = (Material)Resources.Load("Materials/PhysicsDynamicMaterial"); //staticMaterial = (Material)Resources.Load("Materials/PhysicsStaticMaterial"); } protected virtual void Start() { init(new float3(0, -9.81f, 0)); } // // Object creation // private Entity CreateBody(float3 position, quaternion orientation, BlobAssetReference collider, float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic) { EntityManager entityManager = EntityManager; Entity entity = entityManager.CreateEntity(new ComponentType[] { }); entityManager.AddComponentData(entity, new LocalToWorld { }); entityManager.AddComponentData(entity, new Translation { Value = position }); entityManager.AddComponentData(entity, new Rotation { Value = orientation }); var colliderComponent = new PhysicsCollider { Value = collider }; entityManager.AddComponentData(entity, colliderComponent); Mesh mesh = new Mesh(); List meshes; unsafe { meshes = Unity.Physics.Authoring.DisplayBodyColliders.DrawComponent.BuildDebugDisplayMesh(colliderComponent.ColliderPtr); } CombineInstance[] instances = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { instances[i] = new CombineInstance { mesh = meshes[i].Mesh, transform = Matrix4x4.TRS(meshes[i].Position, meshes[i].Orientation, meshes[i].Scale) }; } mesh.CombineMeshes(instances); entityManager.AddSharedComponentData(entity, new RenderMesh { mesh = mesh, material = isDynamic ? dynamicMaterial : staticMaterial }); if (isDynamic) { entityManager.AddComponentData(entity, PhysicsMass.CreateDynamic(colliderComponent.MassProperties, mass)); float3 angularVelocityLocal = math.mul(math.inverse(colliderComponent.MassProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.AddComponentData(entity, new PhysicsVelocity() { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.AddComponentData(entity, new PhysicsDamping() { Linear = 0.01f, Angular = 0.05f }); } return entity; } protected Entity CreateStaticBody(float3 position, quaternion orientation, BlobAssetReference collider) { return CreateBody(position, orientation, collider, float3.zero, float3.zero, 0.0f, false); } protected Entity CreateDynamicBody(float3 position, quaternion orientation, BlobAssetReference collider, float3 linearVelocity, float3 angularVelocity, float mass) { return CreateBody(position, orientation, collider, linearVelocity, angularVelocity, mass, true); } protected unsafe Entity CreateJoint(BlobAssetReference jointData, Entity entityA, Entity entityB, bool enableCollision = false) { EntityManager entityManager = World.Active.EntityManager; ComponentType[] componentTypes = new ComponentType[1]; componentTypes[0] = typeof(PhysicsJoint); Entity jointEntity = entityManager.CreateEntity(componentTypes); entityManager.SetComponentData(jointEntity, new PhysicsJoint { JointData = jointData, EntityA = entityA, EntityB = entityB, EnableCollision = (enableCollision ? 1 : 0) }); return jointEntity; } // // Helper methods // protected void SetDebugDisplay(Unity.Physics.Authoring.PhysicsDebugDisplayData debugDisplay) { EntityManager.SetComponentData(stepper, debugDisplay); } protected RigidTransform GetBodyTransform(Entity entity) { EntityManager entityManager = EntityManager; return new RigidTransform( entityManager.GetComponentData(entity).Value, entityManager.GetComponentData(entity).Value); } }