- Home /
Raycast Object Selection
What's wrong here? I have this in the update function and I debuted the thing… it see's the click but never does the if it even when it should be hitting…
if (Input.GetMouseButtonDown(0))// when button clicked...
{
gui = "no";
RaycastHit hit; // cast a ray from mouse pointer:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// if enemy hit...
if (Physics.Raycast(ray, out hit))
{
Debug.Log("selecting");
DeselectPlanet(); // deselect previous target (if any)...
selectedPlanet = hit.transform; // set the new one...
planetselect(); // and select it
}
}
I have this working in another script only thing I can think is it has to do with the fact that for this one the camera is in a empty object so I can move the camera. Also maybe since the camera is angled?
It is unclear what problem you are having. $$anonymous$$y guess is that your raycast is hitting something you don't expect. This results in 'selectedPlanet' getting set to some transform that is not a planet and therefore does not have the components you need. To check insert this line between lines 32 and 33.
Debug.Log(hit.collider.tag+", "+hit.collider.name);
Answer by Tomer-Barkan · Nov 30, 2013 at 05:46 AM
First, do you have just the one camera? If you have two cameras, you might want to use a reference to the camera inside your script instead of Camera.main (in general you might want to use it for performance benefits).
Second, I can recommend a perhaps simpler way to handle clicks on items: OnMouseUpAsButton. This method is invoked in any MonoBehaviour
attached to an object that is clicked - meaning button is pressed and released on top of the object (as long as the object has a collider). You also have OnMouseDown
to handle button pressed (without releasing), OnMouseDrag
to handle holding the button down, OnMouseUp
, etc.
Now, I would create a simple script that detects clicks on an object, and calls a method on your HUD script:
public class MapHud : MonoBehaviour { // all your code here
// handle clicks on objects
public void ObjectClicked(ClickableObject obj) {
Debug.Log("selecting");
DeselectPlanet(); // deselect previous target (if any)...
selectedPlanet = obj.transform; // set the new one...
planetselect(); // and select it
}
}
public class ClickableObject : MonoBehaviour { private MapHud hud;
public void Start() {
hud = Object.FindObjectOfType(typeof(MapHud)) as MapHud;
}
public void OnMouseUpAsButton() {
hud.ObjectClicked(this);
}
}
Then simply attach the ClickableObject script to any object you want selectable. Remember to make sure they all have colliders. In this case it doesn't matter how many cameras you have.
Cool so now what if I want different actions for each clicked object? Where would I add this? In the clickableobject script… I would assume using tags? Wait… its still getting the transform so my tag system still works I think...
Also I am getting a error saying:
Assets/Scripts/ClickableObject.cs(10,13): error CS0266: Cannot implicitly convert type UnityEngine.Object' to
$$anonymous$$apHud'. An explicit conversion exists (are you missing a cast?)
Right, fixed the error (added as $$anonymous$$apHud
).
As long as the message is always being sent to the $$anonymous$$apHud, you can use the code as is, and check for tags, names, or any other identifiers in the ObjectClicked()
method, since it receives the monobehaviour, so it has access to all the GameObject components.
If you want the message to be sent to something other than $$anonymous$$apHud, it's a bit more complicated, you'll need to create an interface that implements ObjectClicked()
(say ObjectClickHandler), and set references to an ObjectClickHandler in each and every ClickableObject via the inspector. I'll get into this more if it's necessary.
Ok now working great just one more thing… I tried putting the gui = no in a else to make it deselect but no go. What am I missing?
if(gui == "yes")
{
if(selectedPlanet.CompareTag("Sol System"))
{
Rect windowSize = new Rect(Screen.width - 300,Screen.height - 505,300,250);
windowSize = GUI.Window(1, windowSize, Planet, "");
}
else
gui = "no";
}
I'm not sure exactly when you want to deselect...
If you want to deselectwhen clicking on nothing, you can add a ClickableObject script and a collider that will surround the entire game world, and deselect when it is the clicked object.
$$anonymous$$aybe easier to deselect when right clicking, then simply add this to your Update():
if (Input.Get$$anonymous$$ouseButtonDown(1)) {
// do what you need to deselect
}
Answer by belvita · Nov 30, 2013 at 05:05 AM
Can u try like this: inside update function
if (Input.GetMouseButtonDown(0))
{
// when button clicked...
gui = "no";
}
RaycastHit hit; // cast a ray from mouse pointer:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// if enemy hit...
if (Physics.Raycast(ray, out hit))
{
Debug.Log("selecting");
DeselectPlanet(); // deselect previous target (if any)...
selectedPlanet = hit.transform; // set the new one...
planetselect(); // and select it
}
Answer by golemsmk · Nov 30, 2013 at 04:56 AM
I think your script is OK, it must be a problem with colliders. Adding a suitable collider to the object will solve your problem. Remember, you can only use the 3D collider, not 2D collider, these 2D colliders won't work. Unity will fix this bug soon. I see someone has reported this to Unity. If this is the right answer, please stick it for other people don't have to look around for the answer.
I'm not sure Unity will fix the 2d thing... They created separate 2d Physics manager, with it's own Raycast, etc... Probably more efficient.
Raycast, you can think that one is a special object, and it only deteches the collision with a collider. $$anonymous$$ake sure your collider is over the face of the object. You should change the code using Debug.DrawLine(ray.origin, hit.point); ins$$anonymous$$d of using Debug.Log("selecting"); then you will see if your ray hits the object. If you don't see the ray, that mean there are some logic error in you project. That's all. Your code works well with me, I tried it.
Unity 4.3 have a new physic system, for only 2D game. So I think can you have problem with them. If you don't, so not need to care about it.