- Home /
RaycastAll related question
Hello everyone,
I have this code:
GameObject GetClickedGameObject()
{
Ray ray = MyCamera.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray,out hit))
{
return hit.transform.gameObject;
}
else
{
return null;
}
}
Which shoots a single ray and as soon it hits an collider it returns the info. The problem is, that if I have another colider in front of the tageted colider, it will not work anymore.
How can I use the RaycastAll to search for that specidifc colider I'm interested in? The info i'm passing further for processing is stored in: hit.transform.gameObject
Thank you.
Anyone? I gave more information in the hereunder response.
Answer by axCed · Oct 03, 2013 at 01:35 PM
1) raycastAll 2) foreach transform in raycast result 3) if transform.name == something 4) you got it
Thanks for pointing this out. I tried it but it isn't working. $$anonymous$$y code:
//This is basically to target the spell casting with your mouse.
if(Input.Get$$anonymous$$ouseButtonDown(0))
{
clickedGmObj = GetClickedGameObject();
Invoke("TeamCast", 0);
if(isaoe==true){
Invoke("AOE", 0);
}
}
Then,
//here I'm trying to send a ray from the mouse position and attribute the hit objects to the clickedGmObj, for later use in TeamCast()
GameObject GetClickedGameObject()
{
RaycastHit[] hits;
hits = Physics.RaycastAll(transform.position, transform.forward, 100.0F);
foreach(RaycastHit hit in hits)
{
return hit = clickedGmObj;
}
}
Finally,
//First I check what type of collider it is (enemy or friendly taged) then for the clickedGmObj I apply effects.
public void TeamCast()
{
if(hit.collider.tag == "RayEnemy" & dealdamage==true & spells.lightningBool == true)
{
var bounds = hit.collider.bounds;
var v3 = bounds.center;
v3.y -= bounds.extents.y;
damagePrefab = Instantiate(particle, v3, transform.rotation) as GameObject;
damagePrefab.transform.parent = clickedGmObj.transform;
AudioSource.PlayClipAtPoint(lightningBolt, v3);
//DA$$anonymous$$AGE
....
What needs changed or corrected in GetClickedGameObject() ?
What property does the object you want to find have that the blocking object(s) don't? Say it is a tag like "SpecialObject". Then you could do:
GameObject GetClickedGameObject()
{
RaycastHit[] hits;
hits = Physics.RaycastAll(transform.position, transform.forward, 100.0F);
foreach(RaycastHit hit in hits)
{
if (hit.collider.tag == "SpecialObject")
return hit.collider.gameObject;
}
return null;
}
The problem is i'm searching for two types of game objects. One has the tag RayEnemy the other RayFriendly. They are set on objects that behave like units in an RTS game. So sometimes they overlap, so I can't cast the spell on the enemy for example because the friendly unit is blocking the ray.
Can I store the hit.collider.gameObject so can't use it differently, depending if I need to click on an enemy or friend?
I only half understand your comment. You can change the tag you are looking for depending on what you want:
if (hit.collider.tag == tag)
Then you could set 'tag' equal to "RayEnemy" or "RayFriendly" depending on what you are looking for. Note that the results you get back from RaycastAll() are not guaranteed to be sorted by distance.
You know... you should be able to find the answer by yourself. Anyway. ;)
private IEnumerator YourRaycastAll$$anonymous$$ethod ()
{
Ray ray;//ABOUT: Ray from mouse in camera.
RaycastHit[] hits;
ray = mainCamera.ScreenPointToRay($$anonymous$$ouse.Position);
hits = Physics.RaycastAll(ray);
yield return null;//INFO: Step one is done.
foreach(RaycastHit hit in hits)
{
//YOUR CODE:
if(hit.collider.tag == "RayEnemy") { return hit.collider.tag = enemy; } else if (hit.collider.tag == "RayFriendly") { return hit.collider.tag = friendly; }
//DON'T USE IT
//make a list or two and store it in the class instance, so you can call the method only once no matter the number of target and keep the raycast result in memory.
}
}
Read the Unity doc.
Note: I don't remember if I used coroutine and yield for performance reason or because Unity needs that extra frame to process the raycast.