I'm trying to pick up objects on my game. so the object that the user is directly looking at can be picked up on a button click. I have LookObject
which is a gameObejct
that stores the objects that I'm currently looking at. The issue I'm facing here is that the LookObject
is NOT accurately showing the objects that I'm looking at. please see this image.
as seen in this image the reticle is not exactly on the cube, yet the look object is showing the cube. How can I make it accurate?
[Header("InteractableInfo")]
public float sphereCastRadius = 0.5f;
public int interactableLayerIndex;
private Vector3 raycastPos;
public GameObject lookObject;
private PhysicsObjects physicsObject;
private Camera mainCamera;
public GameObject winUI;
private InteractiveObjects interactiveObjects;
void Update()
{
//Here we check if we're currently looking at an interactable object
raycastPos = mainCamera.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, 0));
RaycastHit hit;
if (Physics.SphereCast(raycastPos, sphereCastRadius, mainCamera.transform.forward, out hit, maxDistance, 1 << interactableLayerIndex))
{
lookObject = hit.collider.transform.gameObject;
}
Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit, maxDistance);
if (hit.transform)
{
interactiveObjects = hit.transform.GetComponent<InteractiveObjects>();
}
else
{
lookObject = null;
interactiveObjects = null;
}
//if we press the button of choice
if (Input.GetKeyDown(KeyCode.Space))
{
//and we're not holding anything
if (currentlyPickedUpObject == null)
{
//and we are looking an interactable object
if (lookObject != null )
{
PickUpObject(); }
}
}
}
The cube and all other interactable objects have this script:
public class PhysicsObjects : MonoBehaviour
{
public float waitOnPickup = 0.2f;
public float breakForce = 35f;
[HideInInspector] public bool pickedUp = false;
[HideInInspector] public PlayerInteractions playerInteractions;
private void OnCollisionEnter(Collision collision)
{
if (pickedUp)
{
if (collision.relativeVelocity.magnitude > breakForce)
{
playerInteractions.BreakConnection();
}
}
}
//this is used to prevent the connection from breaking when you just picked up the object as it sometimes fires a collision with the ground or whatever it is touching
public IEnumerator PickUp()
{
yield return new WaitForSecondsRealtime(waitOnPickup);
pickedUp = true;
}
}
You are doing
if (Physics.SphereCast(raycastPos, sphereCastRadius, mainCamera.transform.forward, out hit, maxDistance, 1 << interactableLayerIndex))
{
lookObject = hit.collider.transform.gameObject;
}
with a radius of 0.5
meters!
Then next you do
Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit, maxDistance);
without any layer filter so you hit eg the floor.
So the check
if (hit.transform)
{
interactiveObjects = hit.transform.GetComponent<InteractiveObjects>();
}
else
{
lookObject = null;
interactiveObjects = null;
}
enters the if
case, even then when the hit.transform
of the second cast is not he same as the first one.
I don't really understand why you do two casts in the first place. You probably rather want to simply stick with
if (Physics.SphereCast(mainCamera.ViewportPointToRay(Vector2.one * 0.5f), sphereCastRadius, mainCamera.transform.forward, out var hit, maxDistance, 1 << interactableLayerIndex))
// or if you don't want to use a sphere cast anyway
//if(Physics.Raycast(mainCamera.ViewportPointToRay(Vector2.one * 0.5f), maxDistance, 1 << interactableLayerIndex))
{
var lookObject = hit.collider.gameObject;
if(lookObject.TryGetComponent<InteractiveObjects>(out var interactiveObject))
{
if (Input.GetKeyDown(KeyCode.Space))
{
//and we're not holding anything
if (!currentlyPickedUpObject)
{
// whatever happens in here
PickUpObject(interactiveObject);
}
}
}
}
and simply use a smaller radius for the sphere cast or as commented use the simple RayCast directly if you don't want to use a radius anyway.
in general I would also recommend to rather use a
public LayerMask interactableLayers;
and then directly use interactableLayers
instead of 1 << interactableLayerIndex
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.