Hi. So I was working through Quill18’s Simple Hex Based Game tutorial and for some reason the raycast hits the spheres sometimes depending on where they are but not other times. I think it has something to do with the position they start in but I can’t figure it out. I’ve included my code that I’m using to click them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class MouseManager : MonoBehaviour {
Unit selectedUnit;
void Start () {
}
void Update () {
if (EventSystem.current.IsPointerOverGameObject ()) {
return;
}
Debug.Log ("Mouse Position: " + Input.mousePosition);
Vector2 mapPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast (mapPoint, Vector2.zero);
if (hit.collider != null) {
GameObject hitObject = hit.collider.transform.parent.gameObject;
if (hitObject.GetComponent<Hex> () != null) {
MouseOver_Hex (hitObject);
} else if (hitObject.GetComponent<Unit> () != null) {
MouseOver_Unit (hitObject);
}
}
}
void MouseOver_Hex(GameObject hitObject) {
Debug.Log ("You hit: " + hitObject.name);
if (Input.GetMouseButtonDown (0)) {
SpriteRenderer sr = hitObject.GetComponentInChildren<SpriteRenderer> ();
if (sr.color == Color.cyan) {
sr.color = Color.white;
} else {
sr.color = Color.cyan;
}
if (selectedUnit != null) {
selectedUnit.destination = hitObject.transform.position;
}
}
}
void MouseOver_Unit(GameObject hitObject) {
Debug.Log ("You hit: " + hitObject.name);
if (Input.GetMouseButtonDown (0)) {
selectedUnit = hitObject.GetComponent<Unit> ();
}
}
}
Using a Raycast of zero length isn’t the most effective way of doing this; try using Physics2D.OverlapPoint instead.
You also might want to zero Z like this to see if it helps:
var position = Input.mousePosition;
position.z = 0.0f;
position = Camera.main.ScreenToWorldPoint(position);
Thanks! I tried the code you gave me but it didn’t work. I’ll look into OverlapPoint to see if that helps.
Edit:
…So I’m using Physics2D.OverlapPoint but it’s giving me the same issue, in which it doesn’t seem to sense where my second object is occasionally. Both items are prefabs and the only thing I’ve changed is the x position. And for instance, when circle1 is on 0,0 and circle2 is on 3,0, it senses circle2, but not circle1, but then if I move circle2 3.6,0, it senses circle1 but not circle2. And then if I move circle2 to 0,0 as well, it senses both of them. I’ve even added a third circle, and now it’s not working with any of them.
So actually, I moved all the circles off the board onto -7,0/3/6 respectively, and it let me move all of them like normal. So I think it might be something to do with the board blocking the raycast. I have the tiles set to a lower sorting layer though, so I dont know what to do…
Edit:
Actually, despite the fact that my game is 2D, I moved the circled to -5 on the z axis and I can move them all perfectly! So… I dont know exactly what it was but it worked!
Just try simplifying your code as a test to see what’s going wrong.
First step is ensuring you’re not getting errors like NULL references in the console.
Next is to remove the following to ensure it’s not this:
if (EventSystem.current.IsPointerOverGameObject ()) {
return;
}
The following code is doing a lot of assumed work with no checks:
GameObject hitObject = hit.collider.transform.parent.gameObject;
If the object doesn’t have a parent then you’d be seeing NullReferenceException.
You could just try the following to ensure it’s not something else as this WILL work:
using UnityEngine;
public class MouseManagerTest : MonoBehaviour
{
void Update ()
{
var position = Input.mousePosition;
position.z = 0.0f;
position = Camera.main.ScreenToWorldPoint(position);
var collider = Physics2D.OverlapPoint (position);
if (collider)
Debug.Log (collider.gameObject.name);
}
}
Also, this is all presuming you’re using an orthographic camera set-up. If you’re using perspective then this won’t necessarily work correctly. If you’re trying to perform pseudo-3D raycasts then you can use GetRayIntersection (All/NonAlloc).
Also note that the calls you’re using only return a single item.
Thanks! I’m glad you’re still helping here because my fix was very obviously temporary and now the raycast is detecting collisions where the models aren’t