Checking whether an object is being hit by a ray
I know how to check if the ray hits anything. But does it work the other way? Something like collisions:
void OnCollisionEnter(Collision other) { if (other.gameObject.CompareTag ("Tag")
So I need something like this: void BeingHitByTheRay { if(RaysName = Ray) do something }
How do I achieve that?
Answer by Statement · Oct 24, 2015 at 11:50 PM
I'm going through my hexes by shooting a ray from camera into them. If a hex IS hit by a ray it is highlighted. If it is NOT hit -- not highlighted.
So the script 'BeingHitByRay' is on my hexes prefabs, not on the Ray itself. How should I alter it? Thanks in advance :)
It sounds like you want simple mouse over events. You can let Unity handle that with EventSystem and PhysicsRaycaster.
If you haven't got an EventSystem in your scene, add one from GameObject/UI/Event System.
If you haven't got a PhysicsRaycaster in your scene, select your camera and Add Component Physics Raycaster.
On the BeingHitByRay script, implement IPointerEnterHandler and IPointerExitHandler.
// Use namespace...
using UnityEngine.EventSystems;
// Implement interfaces...
public class BeingHitByRay : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
// Handle event
void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
{
// SetColor(highlighted);
}
// Handle event
void IPointerExitHandler.OnPointerExit(PointerEventData eventData)
{
// SetColor(notHighlighted);
}
}
And you should be good to go.
If you wanted to tell the object being hit (like letting the other object respond to a bullet hit for example) you can use SendMessage (Old system, easy to use) or ExecuteEvents.Execute (New system, typesafe, you define and implement interfaces). SendMessage can pass zero or one arguments and it cannot be null.
using UnityEngine;
// Put this on something looking directly at the cube, within 10 meter distance
public class RaycastExample : MonoBehaviour
{
// These methods will be called on the object it hits.
const string OnRaycastExitMessage = "OnRaycastExit";
const string OnRaycastEnterMessage = "OnRaycastEnter";
GameObject previous;
void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, 10f))
{
GameObject current = hit.collider.gameObject;
if (previous != current)
{
SendMessageTo(previous, OnRaycastExitMessage);
SendMessageTo(current, OnRaycastEnterMessage);
previous = current;
}
}
else
{
SendMessageTo(previous, OnRaycastExitMessage);
previous = null;
}
}
void SendMessageTo(GameObject target, string message)
{
if (target)
target.SendMessage(message, gameObject,
SendMessageOptions.DontRequireReceiver);
}
}
And then you have some kind of receiver.
using UnityEngine;
// Put this on the cube.
public class RaycastReceiver : MonoBehaviour
{
// These methods will be called by RaycastExample
void OnRaycastEnter(GameObject sender)
{
print("Hit by " + sender.name);
}
// These methods will be called by RaycastExample
void OnRaycastExit(GameObject sender)
{
print("No longer hit by " + sender.name);
}
}
@statement Nice answer! Thanks a not, I think it works! However the question is: with the method you described above, how do I say that my hex IS NO LONGER HIT by my ray, after it had been hit and now it is not?
Use a bool and set it to true or false.
public bool hitted = false;
if(Physics.Raycast(ray, out hit))
{
if(hit.collider.tag == "Proximity$$anonymous$$ine")
{
hitted = true;
}
}
else
{
hitted = false;
}
thanks for your answer! but i think it wont work. all my hexes have the same tag :)
"how do I say that my hex IS NO LONGER HIT by my ray"
See my updated example
I'm still thinking this over :)) this is way too complex imo, how come there is no such function, similar to Collision(other), but only CollisionWithRay :) Anyway, thanks, that's what I was searching for; working on it.
Updated my example with a sender and a receiver. But again, if you are doing mouse over stuff, the first method to do it would be most preferred because it also plays nice with UI.
Yay!! It worked! Just a sec, I think I owe you a video of what actually happened :)
Answer by nyonge · Oct 24, 2015 at 01:48 PM
Physics.Raycast is your friend here! If you need to check if it hits SPECIFIC objects, make a public LayerMask property and define that in your editor, so that it only affects objects on the layer you need it to.
Note: if you're trying to hit a trigger with your raycast, make sure under Edit > Project Settings > Physics, you have "Raycasts Hit Triggers" checked.
Thanks for the reply but I still dont get it )
Vector3 fwd = transform.TransformDirection(Vector3.forward); if (Physics.Raycast(transform.position, fwd, 10)) { print("There is something in front of the object!"); }
Yeah, I know this thing, but I cant apply it.
$$anonymous$$aybe I have to explain what Im doing to make it more clear. I have a grid. I'm going through my hexes by shooting a ray from camera into them. If a hex IS hit by a ray it is highlighted. If it is NOT hit -- not highlighted. So the script 'BeingHitByRay' is on my hexes prefabs, not on the Ray itself. How should I alter it? Thanks in advance :)
Oh okay, what you're looking for is probably Bounds.IntersectRay
http://docs.unity3d.com/ScriptReference/Bounds.IntersectRay.html
Basically it'd be like if (myBounds.IntersectRay(myRay)) { Debug.Log("I'm hit!"); } else { Debug.Log("I'm not hit"); } And from there you'd just call whatever function you need. However note that your ray isn't colliding with the colliders, it's just intersecting their bounds, so it'll pass through things and can intersect with multiple bounds.
Your answer
Follow this Question
Related Questions
Ray from camera not working in VR? 0 Answers
An probably very easy question about Raycast system... 1 Answer
Make an object look in a direction 0 Answers
Raycast are not always updating in FixedUpdate 0 Answers
Moving an object along the ray 1 Answer