Initial commit
This commit is contained in:
138
Assets/Scripts/ItemPickup.cs
Normal file
138
Assets/Scripts/ItemPickup.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class ItemPickup : MonoBehaviour
|
||||
{
|
||||
[Header("Layer Settings")]
|
||||
public LayerMask pickupLayer;
|
||||
[Header("Input Settings")]
|
||||
public InputActionAsset inputActionAsset;
|
||||
|
||||
[Header("Pickup Settings")]
|
||||
public float pickupSpeed = 10f; // How fast it snaps to your hand
|
||||
public float holdDistance = 3f; // Default distance
|
||||
|
||||
private InputAction pickUpAction;
|
||||
private Camera mainCamera;
|
||||
|
||||
// We store the Rigidbody instead of the GameObject
|
||||
private Rigidbody currentPickedRB = null;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
mainCamera = Camera.main;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (inputActionAsset != null)
|
||||
{
|
||||
pickUpAction = inputActionAsset.FindAction("PickUp");
|
||||
if (pickUpAction != null)
|
||||
{
|
||||
pickUpAction.Enable();
|
||||
pickUpAction.started += OnPickUpStarted;
|
||||
pickUpAction.canceled += OnPickUpCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (pickUpAction != null)
|
||||
{
|
||||
pickUpAction.started -= OnPickUpStarted;
|
||||
pickUpAction.canceled -= OnPickUpCanceled;
|
||||
pickUpAction.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPickUpStarted(InputAction.CallbackContext context)
|
||||
{
|
||||
// 1. Raycast to find object
|
||||
Vector2 mousePos = Mouse.current.position.ReadValue();
|
||||
Ray ray = mainCamera.ScreenPointToRay(mousePos);
|
||||
RaycastHit hit;
|
||||
|
||||
if (Physics.Raycast(ray, out hit))
|
||||
{
|
||||
// Check if it has a Rigidbody and match layer
|
||||
if (hit.collider.TryGetComponent(out Rigidbody rb) &&
|
||||
((1 << hit.collider.gameObject.layer) & pickupLayer) != 0)
|
||||
{
|
||||
currentPickedRB = rb;
|
||||
|
||||
// --- CRITICAL FIX START ---
|
||||
// If we pick it off a Shelf, it is frozen (Kinematic).
|
||||
// We must unfreeze it immediately so we can apply velocity.
|
||||
currentPickedRB.isKinematic = false;
|
||||
// --- CRITICAL FIX END ---
|
||||
|
||||
// 2. Setup Physics for "Holding"
|
||||
currentPickedRB.useGravity = false;
|
||||
|
||||
// Add damping so it doesn't drift around like it's on ice
|
||||
currentPickedRB.linearDamping = 10;
|
||||
currentPickedRB.angularDamping = 5;
|
||||
|
||||
// Optional: Calculate distance to keep it where we clicked
|
||||
holdDistance = hit.distance;
|
||||
|
||||
// Notify RayCastSystem
|
||||
RayCastSystem rayCastSystem = GetComponent<RayCastSystem>();
|
||||
if (rayCastSystem != null)
|
||||
{
|
||||
rayCastSystem.SetCurrentPickedRB(rb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPickUpCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
if (currentPickedRB != null)
|
||||
{
|
||||
// 3. Reset Physics properties
|
||||
currentPickedRB.useGravity = true;
|
||||
currentPickedRB.linearDamping = 0; // Reset to default (usually 0)
|
||||
currentPickedRB.angularDamping = 0.05f;
|
||||
|
||||
currentPickedRB = null;
|
||||
// Notify RayCastSystem that an object is no longer picked up
|
||||
RayCastSystem rayCastSystem = GetComponent<RayCastSystem>();
|
||||
if (rayCastSystem != null)
|
||||
{
|
||||
rayCastSystem.SetCurrentPickedRB(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Physics movement must be in FixedUpdate
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (currentPickedRB != null)
|
||||
{
|
||||
MoveObjectPhysics();
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveObjectPhysics()
|
||||
{
|
||||
Vector2 mousePos = Mouse.current.position.ReadValue();
|
||||
Ray ray = mainCamera.ScreenPointToRay(mousePos);
|
||||
|
||||
// Where we want the object to be
|
||||
Vector3 targetPosition = ray.GetPoint(holdDistance);
|
||||
|
||||
// Calculate direction vector: Target - Current
|
||||
Vector3 direction = targetPosition - currentPickedRB.position;
|
||||
|
||||
// Apply Velocity
|
||||
// We multiply by pickupSpeed to make it responsive
|
||||
// The physics engine handles the rest (Mass 1 vs Mass 100 collisions)
|
||||
currentPickedRB.linearVelocity = direction * pickupSpeed;
|
||||
|
||||
// Note: In Unity versions older than 2023.3, use 'velocity' instead of 'linearVelocity'
|
||||
// currentPickedRB.velocity = direction * pickupSpeed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user