- Home /
Raycast from 2D canvas object to world space
After playing around with the code long enough, I answered my own question. I'll post it here for all or any who have the same problem I had:
Using a Main Camera, with a child Canvas, with a child 'Square UI Object'(cursor). How to make Main Camera use a Raycast that aims at the 'cursor'. And find and get the 'Selected' object returned and use for other scripts...
Using C# in Unity 5.6...
public class MainCameraControl : MonoBehaviour {
public GameObject cursor;
public float cursorSpeed;
public GameObject Selected;
float posX;
float posY;
void Start() {}
void Update () {
KeyboardMove ();
if (Input.GetKeyUp (KeyCode.RightShift)) //The "{ }" doesn't need to be called because there's only one solution
CheckRay (); //Since it's update, you don't want the ray called every frame
if (Input.GetKeyUp (KeyCode.RightControl)) {
if (Selected != null) {
//Destroy (Selected);
Debug.Log ("Last selected: " + Selected.name);
}
}
}
private void CheckRay() {
posX = cursor.transform.localPosition.x + 375f; //These offsets may be needed, or changed for different purposes
posY = cursor.transform.localPosition.y + 150f; //Check your scene while game is running, and make sure DrawRay is active
Ray ray = Camera.main.ScreenPointToRay(new Vector3(posX, posY, 0));
//Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow); //DrawRay - delete back slashes to activate
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
Debug.Log("You have selected the " + hit.collider.name);
Selected = hit.collider.gameObject;
}
private void KeyboardMove(){ //I created these functions down here, to clean the Update space
if (Input.GetKey (KeyCode.UpArrow))
cursor.transform.Translate(Vector2.up * cursorSpeed * Time.deltaTime);
if (Input.GetKey (KeyCode.DownArrow))
cursor.transform.Translate(Vector2.down * cursorSpeed * Time.deltaTime);
if (Input.GetKey (KeyCode.LeftArrow))
cursor.transform.Translate(Vector2.left * cursorSpeed * Time.deltaTime);
if (Input.GetKey (KeyCode.RightArrow))
cursor.transform.Translate(Vector2.right * cursorSpeed * Time.deltaTime);
}
}
Why are you using RayCast2D hit? It should be Physics.RayCast.
Answer by WideEyeNow · Jul 04, 2017 at 03:36 PM
I finally figured it out! The cursor position on the canvas is not only different from worldspace, but it is also a different position when you call ScreenPointToRay (which counts pixels out from the bottom left corner of the canvas, being 0,0).
Here is the proper code for Unity 5.6 in C#:
public GameObject cursor; //drag n drop UI object in inspector
public Canvas canvas; //drag n drop canvas in inspector
float pixelX;
float pixelY;
float posX;
float posY;
void Start ()
{
pixelX = canvas.worldCamera.pixelWidth;
pixelY = canvas.worldCamera.pixelHeight;
}
void Update(){
CheckRay();
}
void CheckRay(){
posX = cursor.transform.localPosition.x + pixelX / 2f;
posY = cursor.transform.localPosition.y + pixelY / 2f;
Vector3 cursorPos = new Vector3 (posX, posY, 0);
//OR- Ray ray = Camera.main.ScreenPointToRay(new Vector3(posX, posY, 0));
Ray ray = Camera.main.ScreenPointToRay(cursorPos);
Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow);
}
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Change Transparency 1 Answer
Unity 5: UI button OnPointerDown not function as expected 1 Answer
Need help with OnUse() script! 1 Answer
[C#] Unity asks for a } for a reason I don't know ( '}' expected ) 1 Answer