Home > front end >  Unity, C# - pointer using mouse
Unity, C# - pointer using mouse

Time:09-17

I'm currently working on a pointer that will visually display where exactly player is currently pointing. This is supposed to have 2 functions:

  1. point out middle of the screen
  2. allow player to interact with whatever he's pointing at (as the pointer has collider)

code:

public class MousePosition3D : MonoBehaviour {
[SerializeField] private Camera mainCamera;

private void Update()
{
    Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    if (Physics.Raycast(ray, out RaycastHit raycastHit))
    {
        transform.position = raycastHit.point;
    }
}}

What above code do is setting transform.position of the pointer on the closest object that has collider on it. This work great, but when I add a collider to my pointer (to allow player to interact with other objects) it starts infinitely looping to the object from where is my POV as each frame it's colliding with it's own collider constantly changing position.

Video for reference: https://vimeo.com/606446838

Does anybody know how to fix this? Or maybe there is a better alternative? My goal is to have a pointer in the middle of the screen (moving and camera rotation is done separately) and let player interact with other objects in the scene.

CodePudding user response:

Set your cursor collider to a dedicated Layer

Then you can ignore this specific layer in the PhysicsRacast using e.g. a LayerMask.

// Configure this via the Isnpector and select only layers you want to hit 
[SerializeField] private LayerMask layersToHit;

private void Update()
{
    Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);

    if (Physics.Raycast(ray, out var raycastHit, Mathf.Infinity, layersToHit))
    {
        transform.position = raycastHit.point;
    }
}

or alternatively only set the layers you ant to ignore and use

// Configure this via the Isnpector and select only layers you want to ignore
[SerializeField] private LayerMask layersToIgnore;

private void Update()
{
    Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);

    // The "~" inverts the bitmask so we hit every layer except the ones selected in the mask
    // see https://docs.microsoft.com/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#bitwise-complement-operator-
    if (Physics.Raycast(ray, out var raycastHit, Mathf.Infinity, ~layersToIgnore))
    {
        transform.position = raycastHit.point;
    }
}
  • Related