Script won't Disable Outline Script

Hello, I’m fairly new to Unity scripting but I’m using ray cast hit to enable a script on an object that outlines the material however hovering onto it’s great and works however when I hover off I get an error and nothing happens? any advice thank you.

Outline Raycast Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OulineDisable : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
        float distance = 100f;
        Debug.DrawRay(ray.origin, ray.direction * distance, Color.green);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {

            // hit!
            Debug.Log("Raycast is hitting " + hit.transform.gameObject);

            if (hit.transform.tag == "Select")
            {

                hit.collider.GetComponentInChildren<Outline>().enabled = true; // this works

            }
            else
            {
                hit.collider.GetComponentInChildren<Outline>().enabled = false;  //Does not work
            }
        }

    }
}

Well think about the logic of your code. How does this actually tell when a game object has left the ray sent from the camera? It doesn’t, is the answer. It will turn on the outline for anything with the “Select” tag, and then probably run head-long into a null-ref for everything else.

You want to check first IF a selectable game-object is in view of the player, and if so, cache that result and turn on the outline. Then IF the player is no longer looking at something selectable, turn off the cached object and clear the cache. OR, if you are looking at a different game object, turn off the previous one, then cache and turn on the new game object.

Something like this off the top of my head:

public class OulineDisable : MonoBehaviour
{
    private Outline _currentOutline;
   
    // Update is called once per frame
    private void Update()
    {
        Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
        float distance = 100f;
        Debug.DrawRay(ray.origin, ray.direction * distance, Color.green);
        RaycastHit hit;
       
        if (Physics.Raycast(ray, out hit))
        {
            var outline = hit.collider.GetComponentInChildren<Outline>();
           
            // looking at nothing selectable
            if (outline == null && _currentOutline != null)
            {
                ClearCurrentOutline();
                return;
            }
           
            // we are looking at a different outline object
            if (outline != _currentOutline)
            {
                SetCurrentOutline(outline);
            }
        }
    }
   
    private void SetCurrentOutline(Outline outline)
    {
        if (_currentOutline != null)
        {
            ClearCurrentOutline();
        }
       
        outline.enabled = true;
        _currentOutline = outline;
    }
   
    private void ClearCurrentOutline()
    {       
        _currentOutline.enabled = false;
        _currentOutline = null;
    }
}

I understand now thank you, so if the player is looking at an object it caches it as the current object until you move on to the next object and clears that object while turning off the script and moves on the next current object and cache that instead?

Yeah pretty much. On top of what you’ve said, you also need to acount for when the player is looking at nothing that can be outlined and clear the current state.

At a fundamental level it’s about maintaining some form of ‘state’ and being able either modify said state, or change your logic depending on the existing state.

You’ll may also need to deselect if the ray doesn’t hit anything at all.

A simpler way to select things by hovering over them might be to use OnMouseEnter, OnMouseOver and OnMouseExit.