Home > OS >  how to write a raycast hit script that recognises a specific game object and doesn't use tags
how to write a raycast hit script that recognises a specific game object and doesn't use tags

Time:03-24

So I'm trying to write a script, it should work in a way that I'm able to put a game object in the inspector, have that object be recognised when looked at with a camera, and when looked, it should also enable an animation and image sprite. I want to use this script without tags as it doesn't single out the specific aniamtion I want played, but it's almost impossible to get it working right and there's almost no tutorials on identifying RayCast.hit with GameObject instead of Tag.

Is there a way to do it, or can this only be accomplished with tags?

using UnityEngine;

public class selectionManager : MonoBehaviour
{
    public Animator outlineAnim;
    public GameObject image;
    public GameObject hitObject;
    public Vector3 collision = Vector3.zero;
    public LayerMask layer;


    private void Update()
    {
        var ray = new Ray(this.transform.position, this.transform.forward);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit) && hit.collider.gameObject.name(hitObject))
        {
            if (hitObject != null)
            {
                outlineAnim.SetBool("outlineOff", true);
                outlineAnim.SetBool("outlineOn", false);
            }
            outlineAnim.SetBool("outlineOn", true);
            image.SetActive(true);
        }
        else if (hitObject != null)
        {
            outlineAnim.SetBool("outlineOff", true);
            outlineAnim.SetBool("outlineOn", false);
        }
    }

CodePudding user response:

If you can use no more filters (layers, tags) etc but you solely want to rely on the GameObject reference (note that the name is quite unreliable) then I would rather use Physics.RaycastAll and do e.g.

using System.Linq;

public GameObject hitObject;

private void Update()
{
    var ray = new Ray(this.transform.position, this.transform.forward);

    var hits = Physics.RaycastAll(ray);

    var hittingTheHitObject = hits.Any(hit => hit.transform.gameObject == hitObject);

    outlineAnim.SetBool("outlineOff", hittingTheHitObject);
    outlineAnim.SetBool("outlineOn", !hittingTheHitObject);

    image.SetActive(hittingTheHitObject);
}

where hits.Any(hit => hit.transform.gameObject == hitObject) basically equals doing

private bool Any(RaycastHit[] hits)
{
    foreach(var hit in hits)
    {
        if(hit.transform.gameObject == hitObject) return true;
    }

    return false;
}

CodePudding user response:

If you change the if condition, for example, like this

 private void Update()
{
    var ray = new Ray(this.transform.position, this.transform.forward);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit) && hit.collider.gameObject != null)
    {
        hitObject = hitInfo.collider.gameObject;
        if (hitObject != null)
        {
            outlineAnim.SetBool("outlineOff", true);
            outlineAnim.SetBool("outlineOn", false);
        }
        outlineAnim.SetBool("outlineOn", true);
        image.SetActive(true);
    }
    else if (hitObject != null)
    {
        outlineAnim.SetBool("outlineOff", true);
        outlineAnim.SetBool("outlineOn", false);
    }
}
  • Related