Crosshair Distance Indicator

I have this grappling hook that can travel a certain max distance towards terrain and will return if it doesn’t hit anything.

I want the crosshair to indicate a red cross if the distance of the terrain that the player is looking at is too far to grapple to, but remain the same if the player is close enough to grapple to the terrain.

A suggestion was to cast a Physics Ray from the camera and see the distance from the ray to an object, but I don’t know how I would achieve this, nor if this would actually solve the issue.
I thought maybe I could use the float “distanceToHook” as depicted in the first script.
Can someone point me in the right direction? Thanks :slight_smile:

SCRIPTS:

This is the first grappling hook script.

public class GrapplingHook : MonoBehaviour {

public GameObject player;

public GameObject hook;
public GameObject hookHolder;

public float hookTravelSpeed;
public float playerTravelSpeed;

public static bool fired;
public bool hooked;
public GameObject hookedObject;

public float maxDistance;
private float currentDistance;

void Update()
{
    if (Input.GetMouseButtonDown(0) && fired == false)
    {
        fired = true;
    }

    if (fired == true && hooked == false)
    {
        hook.transform.Translate(Vector3.forward * Time.deltaTime * hookTravelSpeed);
        currentDistance = Vector3.Distance(transform.position, hook.transform.position);

        if(currentDistance >= maxDistance)
        {
            ReturnHook();
        }
    }

    if (hooked == true)
    {
        hook.transform.parent = hookedObject.transform;
        transform.position = Vector3.MoveTowards(transform.position, hook.transform.position, Time.deltaTime * playerTravelSpeed);
        float distanceToHook = Vector3.Distance(transform.position, hook.transform.position);

^^^^^^^^^^here is the variable i thought i could use.^^^^^^^^^

        player.GetComponent<PlayerMovement>().gravity = 0f;

        if (Input.GetMouseButtonDown(0)  ||  distanceToHook < 2)
        {
            ReturnHook();
        }
    }
    else
    {
        hook.transform.parent = hookHolder.transform;
        player.GetComponent<PlayerMovement>().gravity = -35f;
    }

}

void ReturnHook()
{
    hook.transform.rotation = hookHolder.transform.rotation;
    hook.transform.position = hookHolder.transform.position;
    fired = false;
    hooked = false;
}

This is the other script that detects if the terrain can be hooked or not.

    public class HookDetector : MonoBehaviour {
public GameObject player;

void OnTriggerEnter(Collider other)
{
      if(other.tag == "Hookable")
      {
        player.GetComponent<GrapplingHook>().hooked = true;
        player.GetComponent<GrapplingHook>().hookedObject = other.gameObject;
    }
}
}

You could run the check like this:

// Pre-distance checks such as mouseDown and notHooked

RaycastHit hit;
Ray ray = Camera.MainCamera.ScreenPointToRay(0.5, 0.5); // You can use Input.mousePosition as an alternative to the middle of the screen (0.5, 0.5)
if (Physics.Raycast(ray, out hit)) {
  if (hit.distance <= maxHookDistance) {
     progressWithHook(hit); // A method that will deal with the actual hook functionality
  } else {
     badHook(1); // A method that creates the red cross etc.
} else {
  badHook(0); // Possible fail states such as 0 being noObjectSelected and 1 being maxDistanceExceeded etc.
}

That code creates a ray from the centre currently outputting camera (unless you replaced 0.5, 0.5) which will tell you (through a RaycastHit object instantiated as hit)
if it hit an object (this is what Physics.Raycast returns), the GameObject which it hit and a distance calculation (of C# type float). Additionally, you could use the hit GameObject to check for a tag or scripts.

Feel free to comment on this or DM me (no idea if unity answers has DM ngl, also hope that unity doesn’t rep limit comments (fairly sure it doesn’t)) if you’ve (being anyone reading this) got any questions.