- Home /
How can I make that the interactable raycast shoot will not pass through some objects like doors ?
I have a window the window layer is set to Interactable :
This small script is attached to the window :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemInformation : UnityEngine.MonoBehaviour
{
[TextArea]
public string description;
}
And this script is attached to the FPSController (Player) :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DetectInteractable : UnityEngine.MonoBehaviour
{
public Camera cam;
public float distanceToSee;
public string objectHit;
public bool interactableObject = false;
public Transform parentToSearch;
public Scaling scaling;
public LayerMask layermask;
public int spinX = 0;
public int spinY = 0;
public int spinZ = 0;
public GameObject navi;
public GameObject itemsDescriptionCanvas;
public Text itemsDescriptionText;
private RaycastHit whatObjectHit;
private void Update()
{
if (cam.enabled == true)
{
if (Input.GetMouseButtonDown(0) && !scaling.scaleUp)
{
if (whatObjectHit.collider != null)
ExecuteActions(whatObjectHit.collider.gameObject);
}
Debug.DrawRay(cam.transform.position, cam.transform.forward * distanceToSee, Color.magenta);
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out whatObjectHit, distanceToSee, layermask.value)) //layerMask))
{
objectHit = whatObjectHit.collider.gameObject.name;
interactableObject = true;
print("Hit ! " + whatObjectHit.collider.gameObject.name);
if (scaling.objectToScale.transform.localScale == scaling.minSize)
{
scaling.objectToScale.transform.Rotate(spinX, spinY, spinZ);
}
ProcessItemsDescripations(parentToSearch);
itemsDescriptionCanvas.SetActive(true);
}
else
{
if (scaling.objectToScale.transform.localScale == scaling.minSize)
{
navi.transform.rotation = new Quaternion(0, 0, 0, 0);
}
itemsDescriptionCanvas.SetActive(false);
print("Not Hit !");
}
}
}
private void ExecuteActions(GameObject go)
{
var ia = go.GetComponent<ItemAction>();
if (ia != null)
{
ia.ItemMove();
}
}
void ProcessItemsDescripations(Transform parent, int level = 0)
{
foreach (Transform child in parent)
{
if (child.GetComponent<ItemInformation>() != null)
{
ItemInformation iteminformation = child.GetComponent<ItemInformation>();
if (child.name == objectHit)
{
itemsDescriptionText.text = iteminformation.description;
}
}
// Process next deeper level
ProcessItemsDescripations(child, level + 1);
}
}
public class ViewableObject : UnityEngine.MonoBehaviour
{
public string displayText;
public bool isInteractable;
}
}
The problem is that I'm setting the raycast distance to 15. If for example the player is in a large space room I want him to be able to detect and see information on objects around the room.
But then if the player is standing behind a close the door the raycast is pass through the door and detect an object in the other room. And I don't want it to detect objects behind doors or through other objects.
You can see in this screenshot the window is inside the room after the door but the raycast detect the window even if there is door and show the information of the window "Window wow" :
In my logic the raycast should detect objects that are only have a clear eye view. And not through doors for example or through other objects.
I tried for testing to set the door layer to : Ignore Raycast but it didn't change anything.
$$anonymous$$ight sound like a silly question, but do you have colliders on the object’s that the raycast passes through?
On the door parent in the screenshot there is no any collider. But the door have many children and lot of them have a box collider.
It should not pass through other objects by default ?
This is the door screenshot with the hierarchy :
It's the same door it's just when it's green the is unlocked and red locked but the same door. Almost all the children of the door have a box collider.
I didn't try yet other objects for now I see the problem with the window and the door.
Answer by Bunny83 · May 26, 2019 at 03:47 PM
You just don't use a layermask at all. Or if you actually want to use one, make sure all layers that should be able to being hit are included. Keep in mind that the layermask is not meant to just restrict what objects can be returned. It literally filters out any object that is not in the layermask as if it's not there. So just don't use a layermask on your raycast and just check for the layer or tag of the object you hit to determine if it's actually an object you can interact with or not.
To check if the object hit belongs to a layer you specified in your layermask you can simply do:
if ((1<<gameObjectHit.layer)&layermask.value != 0)
{
// gameObjectHit is on a layer we care about
}
As a side note: GetComponentsInChildren does already return an array with all components on the given object as well as any nested child object, no matter how deep it's nested. So you don't have to manually iterate through all objects yourself. Also if the objects in the "parentToSearch" doesn't change (so you don't add new ones or remove old ones) you could simply save the array that "GetComponentsInChildren" returns in Start and just reuse that. There would be other optimisations possible (like a dictionary lookup) but it highly depends on your setup what makes sense.
I just removed the layer$$anonymous$$ask part in my script and also used the GetComponentsInChildren in the Start.
Then I changed in the editor the door changed back the layer to default and untagged. The window I changed the layer to default and the tag changed it to Interactable.
This is how the script looks like now :
But now it's not detecting at all. Just does nothing.
Ah, Sorry
I forgot to mention why I tried to use layermask.
The problem is that in the game the player FPSController object have a child object. The child object is position a bit in front of the player and moving with the player. The child object is part of the game.
Now when not using layermask and trying to check if the object that was hit with a tag named "Interactable" like the window but the raycast hit first all the time the child object and not move through it.
So I'm stuck here.
This is a screenshot of the player and you can see the NAVI is the child that position a bit in front of the player and moving with him.
You can see in the right in the screenshot the navi.
I forgot that I tried this before using only by checking the tag of the hitting object but since it's hitting the NAVI first the tag will be never "Interactable" and therefore it will never detect the window or any other interactable tagged object.
Your answer
Follow this Question
Related Questions
How can i use raycast hit to detect object by the object tag name ? 1 Answer
Why the player is keep moving sometimes out of the grid area ? 0 Answers
Script for a hue rainbow scroll on the material 1 Answer
How can i make the camera to lookat the next target and then rotate and move to the next target ? 0 Answers
How can i use the object pool script to create and destroy gameobjects ? 0 Answers