I’m trying to find some information on raycasting but everything i’ve read is way over my head.
Essentially i have a first person perspective targeting reticle that i want to use to select an enemy in the distance. I know i need to set up some sort of ray casting system, but i’m totaly lost on where to even begin,
I know that the enemy must have some sort of colider, and the reticle must emit a ray, but beyond that i’m lost
any help / posting of a rudimentary script would be most appreciated…
ok, so i’ve been fidling with this for a better pat of the day and i’m still unsure how to implement the actual raycast.
As far as i understand (correct me if i’m wrong)
camera.screenPointToRay is setting the direction of the cast, and Physics.Raycast is actually casting the ray.
this is what i’ve put down so far and got the ray projecting through debug.DrawRay the way i want, but i’m unsure how to pass this on to the actual raycast
then receive info on what has been hit
function Update() {
var ray = camera.ScreenPointToRay (Vector3(371,210,0));
Debug.DrawRay (ray.origin, ray.direction * 400, Color.blue);
}
Check out the documentation for Physics.Raycast() again. Towards the middle of the page, under the second overload of the function, is an example showing how to perform a raycast and then access the returned data.
To see how to get the necessary info from the ray in order to pass it to the raycast function, check out the documentation for Ray. To see what information is returned by the raycast, check out the documentation for RaycastHit.
The documentation is usually a good place to start for this sort of thing; I find that typing whatever I’m interested in in the script reference ‘search’ box usually leads me to the information that I need. (Other good resources are the forums and Unity Answers; searching for ‘raycast’ on either site will most likely turn up many examples.)
Thanks Jesse, i got it working just the way i need it.
Perhaps you could shed some light on the next step… how do i go about collecting information from the object assigned to the collider that the raycast has hit, then send it back to perform a new function based on the results of the gathered information?
You can acquire a reference to the game object through several of RaycastHit’s member fields, such as ‘collider’ or ‘transform’ (which you may already know).
Once you have access to the game object, there are many ways you can ‘communicate’ with it. One is to acquire references to components using GetComponent() and interact with the components directly. Another would be to use the GameObject messaging functions to invoke functions that you’ve associated with the game object via scripts (see the GameObject documentation for info and examples).
Beyond that, it really depends on what you want to do with the object exactly. If you have a particular example in mind and can describe it, someone could probably offer some more specific feedback.
ok, i guess more specifically i just need a selection border (in the form of a gameobject i’ve already created) to apear around the intended object when the ray hits. Then a seperate input (spacebar) to destroy the objects in the selection
The ‘selection border’ question has come up before in the forums; maybe try searching for ‘highlight object’ or ‘outline object’ and see if you can find any of those threads.
For deleting the objects, you’ll probably need to keep track of which objects are selected, either by storing them in a container or somehow flagging them as being selected. Then, when the space bar (or whatever control) is pressed, you would invoke GameObject.Destroy() on all selected objects.
Thanks for all the assistance jesse, it’s been very helpfull, i’ve got another question.
Here’s my script for selecting the objects in question
function DrawGreenRay() {
var ray = camera.ScreenPointToRay (Vector3(371,210,0));
Debug.DrawRay (ray.origin, ray.direction * 400, Color.green);
var hit : RaycastHit;
if (Physics.Raycast (transform.position, transform.forward, hit, 400)){
if(hit.collider.gameObject.tag=="GreenEnemy" ){
var go = GameObject.Find("EnemySelectionReticle");
go.GetComponent(SelectionReticleAnimator).selected = true;
yield WaitForSeconds (.1);
go.GetComponent(SelectionReticleAnimator).selected = false;
print ("Green Selected" + hit.collider);
}
else
print ("wrong color");
}
}
Everything works the way i want, however i’m stumped as to how to make the GameObject.Find(“EnemySelectionReticle”) search only within the hierarchy of the object “GreenEnemy” instead of the entire scene.
a summary of what i’m trying to do:
select objects based on their color (in this case i’ve taged them) then once selected press “execute” to destroy the active selection. Works fine on multiple enemies of different colors, but as soon as i have 2 of the same it targets only the first of that color in the scene hierarchy no matter what object is being aimed at
Here’s my scripts
function DrawYellowRay() {
var ray = camera.ScreenPointToRay (Vector3(371,210,0));
Debug.DrawRay (ray.origin, ray.direction * 400, Color.yellow);
var hit : RaycastHit;
if (Physics.Raycast (transform.position, transform.forward, hit, 400)){
if(hit.collider.gameObject.tag=="YellowEnemy" ){
print ("Yellow Selected" + hit.collider);
transform.Find("/Yellow Enemy/ReticleObject/EnemySelectionReticle") .GetComponent (SelectionReticleAnimator) .selected = true;
yield WaitForSeconds (.1);
transform.Find("/Yellow Enemy/ReticleObject/EnemySelectionReticle") .GetComponent (SelectionReticleAnimator) .selected = false;
print ("Yellow Selected" + hit.collider);
}
else
print ("wrong color");
}
}
var SelectTargetSound : AudioSource;
var selected = false;
var selectionActive = false;
var AnimationSpeed = 1;
var destroyer = false;
function Update () {
if (selected == true)
{ playSelectionReticleAnimation(); }
//execute is spacebar
if (Input.GetButtonDown ("Execute"))
{ DestroySelected(); }
}
function playSelectionReticleAnimation()
{
if (selectionActive == true) {
print ("Already Selected") ;
}
else if (selectionActive == false) {
SelectTargetSound.Play();
animation.Play ("ReticleSelect");
animation ["ReticleSelect"].speed = AnimationSpeed;
selectionActive = true;
}
}
function DestroySelected() {
if (selectionActive == true){
Destroy ( transform.root.gameObject );
print ("Destroyed!!!");
}
}
thanks for the help but i’m really confused on how to implement what you’re talking about. i understand i need to get rid of the transform.find lines, but the rest is over my head, sorry… not my specialty here
Your YellowEnemy script (or Enemy script, or whatever script it is that you’ve attached to your YellowEnemy-tagged objects) would then have a SetSelected function that did what the find functions tried to do.
private var animatorComponent : SelectionReticleAnimator;
function Start() {
animatorComponent = GetComponentInChildren(SelectionReticleAnimator);
}
function SetSelected() {
animatorComponent.selected = true;
yield WaitForSeconds(0.1);
animatorComponent.selected = false;
}
Just chiming in again to say major thanks to both of you, i think that was the last of my issues in this matter. Cant wait to show off what i’ve got working here in the coming weeks!