- Home /
CircleCastAll layermask doesn't seem to work...
Hi there, I have made a script in which my AI character circlecasts around itself to detect food. My script appears to work fine except the layermask doesn't seem to be doing anything. This is my script so far:
public class FindFood01 : MonoBehaviour {
float rayRadius = 2;
Vector2 position2D;
void FixedUpdate () {
if (GetComponent<AI> ().targetFood == null) {
RaycastHit2D[] hit;
position2D = new Vector2 (transform.position.x, transform.position.y);
hit = Physics2D.CircleCastAll (position2D, rayRadius, position2D, 0f, 9);
GetComponent<AI> ().targetFood = hit [0].transform.gameObject;
}
}
}
And I have an AI script that deals with moving the charactor to the target. That bit works fine. The integer 9 is the layer for the food, and I seem to have put this in the correct place. The results though, are that the character detects everything. I can't tell if it detects anything preferentially or not, but it appears to detect food, the player or sometimes itself (and moves in a straight line forever trying to chase itself). Any ideas on what I've missed here?
To clarify in advance, the AI script does nothing until there is a target, and then moves towards it, so it's not that. And I've checked and tripple checked that food is definately layer 9, and that the layer food is only assigned to the food, everything else is on default layer.
Cheers in advance,
Pete
Answer by Xarbrough · Jun 18, 2015 at 11:25 PM
Layermasks in Unity are stored as a bitmask, so you don't input the layer number into the function, but it's bit-value. So something like 1 << 9 (a bitshift to the left 9 times). To make this much more easy, I would define a public LayerMask field and use the built-in enum dropdown of the Inspector to pick my layer mask.
Answer by iron_attorney · Jun 19, 2015 at 10:27 AM
Hey thanks man! That's perfect. It hadn't occured to me that I should actually read about how the layerMasks work, thought they would just be the straight forward layer numbers. To clarify, this is my solution based on your answer:
public class FindFoodSmellClosest : MonoBehaviour {
float rayRadius;
Vector2 position2D;
LayerMask foodMask;
void Start () {
foodMask = LayerMask.GetMask ("Food");
rayRadius = Random.Range (1.0f, 5.0f);
}
void FixedUpdate () {
if (GetComponent<AI> ().targetFood == null) {
RaycastHit2D[] hit;
position2D = new Vector2 (transform.position.x, transform.position.y);
hit = Physics2D.CircleCastAll (position2D, rayRadius, position2D, 0f, foodMask);
if (hit [0] != null) {
GetComponent<AI> ().targetFood = hit [0].transform.gameObject;
}
}
}
Using the line "foodMask = LayerMask.GetMask ("Food");" I don't have to find out what the actual the number is, though I debugged it and it's 512. This means the number must be 2 ^ (layer number, in this case 9), which admittedly is what you already said with "1 << 9 (a bitshift to the left 9 times)".
Cheers very much man!
Pete
Glad I could help. And also remember, that if you make a Layer$$anonymous$$ask variable public or [SerializeField] it will show a nice dropdown in the Inspector to pick from. That way you don't have to use constants in your script.
Ah right! That's what you meant, I get ya now, that's even better. Out of interest, could I add the bit values of multiple different layer masks together to search for multiple layers? Like if I wanted layer 3 (100 / 4) and layer 5 (10000 / 16) I could search for 10100 (or 20). If on the off chance it searched based on the active bits, there's a possibility that could work right? Or is there another way of doing that without just doing another raycast?
Yes that's why they chose to use bitmasks, because you can select multiple ones in one number. So if you want layer 3 and 6 you could do (4 || 16) using the OR operator. You can lookup AND OR Bitshifting Bitmasks if you want a detailed tutorial. Generally, keep in $$anonymous$$d that if you want to include several layers you need OR because you don't care if it is layer 3 or layer 5. If you use AND (&&) it will only work if objects have layer 3 and layer 5.
Awesome stuff! That's solved a different problem that I was going to face soon. Cheers for all your help buddy!
Pete