I want to make a system where items can be picked up, carried and dropped by holding them in front of the camera like in many games, I have a prototype but it doesn’t work fully.
For example, when I pick up an object and look towards the ground, the object interacts with the colliders and applies force to the character (even though there is the Rigidbody > Exclude Layers turned on for the Player).
But if I turn off the colliders, this time it passes through other objects, a situation I don’t want to happen. When I pick up a Grabable object, I don’t want it to apply any force, but I want the collider to be on (except Player’s collider) and when I let it go, it falls where it is.
Also, when I move an object, I want it to move smoothly, but now it moves with a blurry image.
I am open to all your advice
- A grabable object:
- Object Grabbable Script:
ObjectGrabbable.cs (1.4 KB)
using System.Collections;
using System.Collections.Generic;
using MyScripts;
using UnityEngine;
public class ObjectGrabbable : MonoBehaviour, IGrabbable
{
private Rigidbody objectRigidbody;
private Transform objectGrabPointTransform;
const int cubeMass = 1;
const float cubeAngularDrag = 0.05f;
private void Awake()
{
objectRigidbody = GetComponent<Rigidbody>();
}
public void Grab(Transform objectGrabPointTransform)
{
this.objectGrabPointTransform = objectGrabPointTransform;
objectRigidbody.useGravity = false;
objectRigidbody.mass = 0.01f;
objectRigidbody.angularDrag = cubeAngularDrag;
objectRigidbody.detectCollisions = false;
}
public void Drop()
{
this.objectGrabPointTransform = null;
objectRigidbody.useGravity = true;
objectRigidbody.mass = cubeMass;
objectRigidbody.detectCollisions = true;
}
private void FixedUpdate()
{
if (objectGrabPointTransform != null)
{
float lerpSpeed = 10f;
Vector3 newPosition = Vector3.Slerp(
transform.position,
objectGrabPointTransform.position,
Time.deltaTime * lerpSpeed
);
objectRigidbody.MovePosition(newPosition);
}
}
}
- Player:
using System.Collections;
using System.Collections.Generic;
using MyScripts;
using Sirenix.OdinInspector;
using UnityEngine;
public class PlayerPickUpDrop : MonoBehaviour
{
[SerializeField]
private Transform playerCameraTransform;
[Title("Where to place the grabbable object:")]
[SerializeField]
private Transform objectGrabPointTransform;
[SerializeField]
private LayerMask pickUpLayerMask;
private IGrabbable objectGrabbable;
private void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
Debug.Log("E Pressed");
if (objectGrabbable == null)
{
// Not carrying an object, try to grab
Debug.Log("Try Pickup Grabbable");
float pickUpDistance = 4f;
if (
Physics.Raycast(
playerCameraTransform.position,
playerCameraTransform.forward,
out RaycastHit raycastHit,
pickUpDistance,
pickUpLayerMask
)
)
{
Debug.Log("Raycast Hit " + raycastHit.transform.gameObject);
if (raycastHit.transform.TryGetComponent(out objectGrabbable))
{
Debug.Log("Pickup Grabbable");
objectGrabbable.Grab(objectGrabPointTransform);
}
}
}
else
{
// Currently carrying something, drop
Debug.Log("Drop Grabbable " + objectGrabbable);
objectGrabbable.Drop();
objectGrabbable = null;
}
}
}
}