From c15f207415f8b3ced64d77c69b6cc61f85457265 Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Tue, 9 Sep 2025 14:18:19 +0200 Subject: [PATCH] Fake Physics on Player --- .../Prefabs/Characters/PlayerCharacter.prefab | 40 +++----------- Assets/Scenes/Levels/Quarry.unity | 11 +++- Assets/Scripts/Input/PlayerTouchController.cs | 54 +++++++++++++++++-- 3 files changed, 68 insertions(+), 37 deletions(-) diff --git a/Assets/Prefabs/Characters/PlayerCharacter.prefab b/Assets/Prefabs/Characters/PlayerCharacter.prefab index 8656a2a6..c028c669 100644 --- a/Assets/Prefabs/Characters/PlayerCharacter.prefab +++ b/Assets/Prefabs/Characters/PlayerCharacter.prefab @@ -9,7 +9,6 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 3823830588451517910} - - component: {fileID: 5561047086518554858} - component: {fileID: 8910846343857380832} - component: {fileID: 5148042112194028162} - component: {fileID: 2999879259114430221} @@ -40,33 +39,6 @@ Transform: - {fileID: 3792254836612903466} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!50 &5561047086518554858 -Rigidbody2D: - serializedVersion: 5 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4157358163210553531} - m_BodyType: 0 - m_Simulated: 1 - m_UseFullKinematicContacts: 0 - m_UseAutoMass: 0 - m_Mass: 1 - m_LinearDamping: 0 - m_AngularDamping: 0.05 - m_GravityScale: 0 - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_Interpolate: 1 - m_SleepingMode: 1 - m_CollisionDetection: 0 - m_Constraints: 4 --- !u!70 &8910846343857380832 CapsuleCollider2D: m_ObjectHideFlags: 0 @@ -116,6 +88,10 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 2ecb5bf6d8f447368687404e1b24278d, type: 3} m_Name: m_EditorClassIdentifier: + obstacleMask: + serializedVersion: 2 + m_Bits: 576 + colliderRadius: 1 --- !u!114 &2999879259114430221 MonoBehaviour: m_ObjectHideFlags: 0 @@ -160,8 +136,8 @@ MonoBehaviour: radius: 3 height: 2 canMove: 1 - maxSpeed: 20 - gravity: {x: NaN, y: NaN, z: NaN} + maxSpeed: 25 + gravity: {x: 0, y: 0, z: 0} groundMask: serializedVersion: 2 m_Bits: 4294967295 @@ -283,11 +259,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 7877460049793670011, guid: 361ccc9ef82acef4784b24b72013d971, type: 3} propertyPath: m_LocalPosition.x - value: 0.3 + value: 0 objectReference: {fileID: 0} - target: {fileID: 7877460049793670011, guid: 361ccc9ef82acef4784b24b72013d971, type: 3} propertyPath: m_LocalPosition.y - value: 1.6 + value: -1 objectReference: {fileID: 0} - target: {fileID: 7877460049793670011, guid: 361ccc9ef82acef4784b24b72013d971, type: 3} propertyPath: m_LocalPosition.z diff --git a/Assets/Scenes/Levels/Quarry.unity b/Assets/Scenes/Levels/Quarry.unity index 092cb35b..a111c2db 100644 --- a/Assets/Scenes/Levels/Quarry.unity +++ b/Assets/Scenes/Levels/Quarry.unity @@ -427815,11 +427815,20 @@ PrefabInstance: propertyPath: m_Name value: Player objectReference: {fileID: 0} + - target: {fileID: 5148042112194028162, guid: 301b4e0735896334f8f6fb9a68a7e419, type: 3} + propertyPath: colliderRadius + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5148042112194028162, guid: 301b4e0735896334f8f6fb9a68a7e419, type: 3} + propertyPath: obstacleMask.m_Bits + value: 576 + objectReference: {fileID: 0} - target: {fileID: 7393789300602426170, guid: 301b4e0735896334f8f6fb9a68a7e419, type: 3} propertyPath: maxSpeed value: 25 objectReference: {fileID: 0} - m_RemovedComponents: [] + m_RemovedComponents: + - {fileID: 5561047086518554858, guid: 301b4e0735896334f8f6fb9a68a7e419, type: 3} m_RemovedGameObjects: [] m_AddedGameObjects: [] m_AddedComponents: [] diff --git a/Assets/Scripts/Input/PlayerTouchController.cs b/Assets/Scripts/Input/PlayerTouchController.cs index 72b10696..8a853e77 100644 --- a/Assets/Scripts/Input/PlayerTouchController.cs +++ b/Assets/Scripts/Input/PlayerTouchController.cs @@ -16,6 +16,9 @@ namespace Input private Vector2 lastHoldPosition; private Coroutine pathfindingDragCoroutine; private float pathfindingDragUpdateInterval = 0.1f; // Interval in seconds + [Header("Collision Simulation")] + public LayerMask obstacleMask; + public float colliderRadius = 0.5f; // --- Unity/Component References --- private AIPath aiPath; @@ -153,21 +156,64 @@ namespace Input /// private void MoveDirectlyTo(Vector2 worldPosition) { - if (aiPath == null) return; + if (aiPath == null) + { + return; + } Vector3 current = transform.position; Vector3 target = new Vector3(worldPosition.x, worldPosition.y, current.z); Vector3 toTarget = (target - current); Vector3 direction = toTarget.normalized; float maxSpeed = aiPath.maxSpeed; float acceleration = aiPath.maxAcceleration; - directMoveVelocity = - Vector3.MoveTowards(directMoveVelocity, direction * maxSpeed, acceleration * Time.deltaTime); + directMoveVelocity = Vector3.MoveTowards(directMoveVelocity, direction * maxSpeed, acceleration * Time.deltaTime); if (directMoveVelocity.magnitude > maxSpeed) + { directMoveVelocity = directMoveVelocity.normalized * maxSpeed; + } Vector3 move = directMoveVelocity * Time.deltaTime; if (move.magnitude > toTarget.magnitude) + { move = toTarget; - transform.position += move; + } + // --- Collision simulation --- + Vector3 adjustedVelocity = AdjustVelocityForObstacles(current, directMoveVelocity); + Vector3 adjustedMove = adjustedVelocity * Time.deltaTime; + if (adjustedMove.magnitude > toTarget.magnitude) + { + adjustedMove = toTarget; + } + transform.position += adjustedMove; + } + + /// + /// Simulates collision with obstacles by raycasting in the direction of velocity and projecting the velocity if a collision is detected. + /// + /// Player's current position. + /// Intended velocity for this frame. + /// Adjusted velocity after collision simulation. + private Vector3 AdjustVelocityForObstacles(Vector3 position, Vector3 velocity) + { + if (velocity.sqrMagnitude < 0.0001f) + return velocity; + float moveDistance = velocity.magnitude * Time.deltaTime; + Vector2 origin = new Vector2(position.x, position.y); + Vector2 dir = velocity.normalized; + float rayLength = colliderRadius + moveDistance; + RaycastHit2D hit = Physics2D.Raycast(origin, dir, rayLength, obstacleMask); + Debug.DrawLine(origin, origin + dir * rayLength, Color.red, 0.1f); + if (hit.collider != null) + { + // Draw normal and tangent for debug + Debug.DrawLine(hit.point, hit.point + hit.normal, Color.green, 0.2f); + Vector2 tangent = new Vector2(-hit.normal.y, hit.normal.x); + Debug.DrawLine(hit.point, hit.point + tangent, Color.blue, 0.2f); + // Project velocity onto tangent to simulate sliding + float slideAmount = Vector2.Dot(velocity, tangent); + Vector3 slideVelocity = tangent * slideAmount; + return slideVelocity; + } + return velocity; } void Update()