- Home /
Multiple hit detection with Raycasting?
How can I detect whenever two of my colliders got hit by the raycast at the same time?
Here is my current code:
for(int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
Ray ray = camera.ScreenPointToRay(Input.touches[i].position);
Physics.Raycast(ray, out hit);
//If A is touched
if(hit.collider.tag == "A")
{
Debug.Log("A");
}
//If B is touched
if(hit.collider.tag == "B")
{
Debug.Log("B");
}
//If A and B is touched at the same time
if(hit.collider.tag == "A" && hit.collider.tag == "B")
{
Debug.Log("C");
}
}
What I want here to happen is to have Debug.Log("C");
executed.
But instead the things being executed are Debug.Log("A");
and Debug.Log("B");
I don't want "A" and "B" executed, I only want "C".
EDIT: "C" does not get executed. Only A and B.
Is there a simple way I can do this?
Thanks!!
you will still be debug.log a and b because if a gets hit it will debug log a and if b gets hit it will debug log b but if you know it already works just delete the debug.log a and b.By the way does your C work?
@Albert han The C doesn't work. Only A and B. I guess I'll just make it an 'else if' statement if I didn't want A and B, but C doesn't work either way.
maybe it actually not being touched at the same time.I would do a yield wait for seconds and check for the other touch and then debug log it.
That was my guess too. It's not really being touched at the same exact time. Is there a better and easier way of doing this to get the effect I wanted? Thanks :)
I'm also still a huge stranger to 'yield'.
$$anonymous$$ight also work if there was something to check if the collider is being hit, not just if it got hit. Like, it would return true if it was being touched, then would automatically return false if the touch ended.
Though I'm not sure if this is possible at all.
It is possible but do you still want it to do if the user holds the screen?
Answer by Albert-han · Jul 15, 2014 at 03:16 AM
i did this for you but i leaved somethings for you to fix yourself.Sorry :D but if you cant fix it just let me know i'll do it for you but please try.If you find this answer helpful please vote.Hehe :D Things To fix: 1.Raycast hit the Object 2.TouchScreen
using UnityEngine;
using System.Collections;
public class Raycast : MonoBehaviour {
//public GameObject CubeA;
//public GameObject CubeB;
private Ray ray;
private RaycastHit hit;
public bool AisTouch;
public bool BisTouch;
// Use this for initialization
void Start () {
AisTouch = false;
BisTouch = false;
}
// Update is called once per frame
void Update () {
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray,out hit, Mathf.Infinity) && Input.GetMouseButtonDown (0))
{
if(hit.collider.gameObject.tag == "Wood");
{
BisTouch = true;
Debug.Log ("B");
}
}
if (hit.collider.gameObject.tag == "Grass");
{
AisTouch = true;
Debug.Log ("A");
}
if (AisTouch && BisTouch == true);
{
Debug.Log ("C is Done");
}
}
}
Is there a way I can do it that it will only execute C is done if it's currently holding A and B? And when he lets go, it will stop executing. Thanks.
If touchphase end aistouch and bistouch = false If aistouch and bistouch c is touch = true
How do I do that? Sorry, I'm still kind of noobish in scripting.
this script works like this.
1.if a is touched it will execute a.
2.if b is touched it will execute b.
3.if both is touch it will execute c.
4.if c is executed, a and b wont be executed but c will keep on running.
5.if user is not touching screen, a,b and c is not executed.
This script has not been tried out caused i wrote it on my smartphone.Normally i wont write whole scripts for people because they wont learn anything but this script should leave you with some reasonably errors to fix.
using UnityEngine;
using System.Collections;
public class Raycast : $$anonymous$$onoBehaviour {
//public GameObject CubeA;
//public GameObject CubeB;
private Ray ray;
private RaycastHit hit;
public bool AisTouch;
public bool BisTouch;
public bool CisTouch;
// Use this for initialization
void Start () {
AisTouch = false;
BisTouch = false;
}
// Update is called once per frame
void Update () {
int i = 0;
while (i < Input.touchCount)
if (Input.GetTouch(i).phase == TouchPhase.Began) {
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
{
if(hit.collider.gameObject.tag == "Wood");
{
BisTouch = true;
Debug.Log ("B");
}
}
if (hit.collider.gameObject.tag == "Grass");
{
AisTouch = true;
Debug.Log ("A");
}
if(TouchPhase.Ended);
{
AisTouch = false;
BisTouch = false;
CisTouch = false;
}
if (AisTouch && BisTouch == true);
{
CisTouch = true;
}
if (CisTouch == true);
{
CisTouch = true;
AisTouch = false;
BisTouch = false;
}
}
}
}
Hi, is there a RaycastHit 2d version of this?
Answer by ycode · Feb 10, 2018 at 12:06 AM
I had the same problem and came here, but another answer here rather confused me in my case, unfortunately, so that I leave another approach that effectively worked for me under Unity 2017.3.0f3. I hope it could help some others.
The point is that Raycast method can have a Layer Mask, with which the raycast only sense the objects that belong to the specific layers.
If you have the multiple objects to raycast, belong to different Layers, by raycasting to the same Ray by Layer, you can virtually hit both of them.
In my case, it is more effective than hitting everything over the ray.
Firstly, prepare your GameObjects as each of them belongs to a specific Layer.
Then, the raycast code would be like:
var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit0 = new RaycastHit();
RaycastHit hit1 = new RaycastHit();
if (Physics.Raycast(ray, out hit0, Mathf.Infinity, 1 << LayerMask.NameToLayer("Item"))
&& hit0.collider)
print("Raycast hit one of items");
if (Physics.Raycast(ray, out hit1, Mathf.Infinity, 1 << LayerMask.NameToLayer("World"))
&& hit1.collider)
print("Raycast hit one of world");
By the way, Layer Mask is a set of Layers, which is a bit map data, although you would see it as int value in debuggers. Each Layer is represented as int data, and by converting it to bits data, you can bundle multiple Layers into a Layer Mask.
For example, if you'd like to get a raycast hit from one of the game objects belonging to either "Item" or "Player" Layer, then code would be:
Physics.Raycast(ray, out hit0, Mathf.Infinity, (1 << LayerMask.NameToLayer("Item")) ^ (1 << LayerMask.NameToLayer("Player"))