using Unity.Burst; using Unity.Entities; using UnityEngine; using GarmentButton.PlayerTags; using Unity.Transforms; using Unity.Physics; using GarmentButton.PhysicFillters; using Unity.Mathematics; namespace GarmentButton.CameraGeneral { public partial struct SetCameraTransformSystem : ISystem, ISystemStartStop { public void OnCreate(ref SystemState state) { state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); } public void OnStartRunning(ref SystemState state) { var playerEntity = SystemAPI.GetSingletonEntity(); var playerTransform = SystemAPI.GetComponent(playerEntity); foreach (var (cameraProperty, basedRotation, offset) in SystemAPI.Query, RefRW, RefRW>()) offset.ValueRW.Value = (float3)cameraProperty.ValueRO.Transform.Value.position - playerTransform.Position; } public void OnStopRunning(ref SystemState state) { } public void OnUpdate(ref SystemState state) { var playerEntity = SystemAPI.GetSingletonEntity(); var playerTransform = SystemAPI.GetComponentRO(playerEntity); foreach (var (camera, cameraRotation, cameraPosition, playerScreenPosition, directionToPlayer) in SystemAPI.Query, RefRW, RefRW, RefRW, RefRW>()) { cameraRotation.ValueRW.Value = camera.ValueRO.Transform.Value.rotation; cameraPosition.ValueRW.Value = camera.ValueRO.Transform.Value.position; playerScreenPosition.ValueRW.Value = camera.ValueRO.Value.Value.WorldToViewportPoint(playerTransform.ValueRO.Position); directionToPlayer.ValueRW.Value = playerTransform.ValueRO.Position - cameraPosition.ValueRO.Value; } foreach (var item in SystemAPI.Query>()) { item.ValueRO.Value.Value.SetPositionAndRotation(playerTransform.ValueRO.Position, playerTransform.ValueRO.Rotation); } } } [UpdateAfter(typeof(SetCameraTransformSystem))] [BurstCompile] public partial struct CheckSomeBetweenCameraAndPlayerSystem : ISystem { [BurstCompile] public void OnCreate(ref SystemState state) { state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); } [BurstCompile] public void OnUpdate(ref SystemState state) { var playerEntity = SystemAPI.GetSingletonEntity(); var playerTransform = SystemAPI.GetComponent(playerEntity); var physicsWorld = SystemAPI.GetSingleton(); foreach (var (position, rotation, baseRotation, desireRotation, shouldRotate, offset) in SystemAPI.Query, RefRO, RefRO, RefRW, EnabledRefRW, RefRO>().WithPresent()) { var startPosition = playerTransform.Position + offset.ValueRO.Value; var endPosition = startPosition + (-offset.ValueRO.Value * 0.9f); Debug.DrawLine(startPosition, endPosition, Color.green); quaternion wantedRotation; var rayCastInput = new RaycastInput() { Start = startPosition, End = endPosition, Filter = new CollisionFilter { BelongsTo = (uint)CollisionLayer.Defualt, CollidesWith = (uint)(CollisionLayer.Ground) } }; if (physicsWorld.CastRay(rayCastInput, out var hit)) { var angle = math.radians(45); //var angle = 45 * Time.deltaTime; quaternion rotationX = quaternion.RotateX(angle); wantedRotation = math.mul(rotationX, baseRotation.ValueRO.Value); } else { wantedRotation = baseRotation.ValueRO.Value; } wantedRotation = math.slerp(rotation.ValueRO.Value, wantedRotation, 10f * Time.deltaTime); if (!Approximately(wantedRotation, rotation.ValueRO.Value)) { var wantedRotationClearer = RoundSmallValuesToZero(wantedRotation); desireRotation.ValueRW.Value = RoundSmallValuesToZero(wantedRotationClearer); shouldRotate.ValueRW = true; } else { shouldRotate.ValueRW = false; } } } public bool Approximately(quaternion q1, quaternion q2, float epsilon = 1e-5f) { // Calculate the dot product between the two quaternions float dot = math.dot(q1.value, q2.value); // Quaternions are approximately equal if their dot product is close to 1 return math.abs(dot - 1f) < epsilon; } public quaternion RoundSmallValuesToZero(quaternion q, float threshold = 1e-5f) { return new quaternion( math.abs(q.value.x) < threshold ? 0f : q.value.x, math.abs(q.value.y) < threshold ? 0f : q.value.y, math.abs(q.value.z) < threshold ? 0f : q.value.z, math.abs(q.value.w) < threshold ? 0f : q.value.w ); } } [UpdateAfter(typeof(CheckSomeBetweenCameraAndPlayerSystem))] public partial struct RotateCameraBased : ISystem { public void OnCreate(ref SystemState state) { var query = SystemAPI.QueryBuilder().WithAll().Build(); state.RequireForUpdate(query); } public void OnUpdate(ref SystemState state) { foreach (var (camera, rotation) in SystemAPI.Query>()) { camera.Transform.Value.rotation = rotation.ValueRO.Value; } } } }