- Home /
I need help with some grid calculation for a digital board game.
So first of all I should show you an image of the board so you have a visual.
So this is how the board will look like and the White Dot in the bottom is a capsule which is currently representing the player. The basic movement is like this. You throw a dice, you get a random number between 1 and 6. If you get for example 4, the tiles that are 4 tiles away from the one your currently standing on will light up and become clickable. This is all working just fine and without problems.
What I do need a little help with is making only the tiles that are clockwise light up. So the player can only move clockwise on the board. I started programming this by checking the X- and Z-axis of the tile and comparing them with the current position of the player and check if the tile is clockwise or not. This is working for 90% but isn't really optimized or very good for performance.
So somebody told me I should do it like this.
Calculate the angle between the position of the player and the position of the tile with polar coordinates and if it's higher then it is clockwise otherwise it's not. I gave this a shot, but the coordinates that are returned seem like they are not on a grid from 0 degrees - 360 degrees. So I was wondering if someone could help me on how I should calculate this, or if they have an even better idea on how to handle this?
Please show us your clockwise checking code.
Note you may be getting your result in radians; I know more than half my trig-related stuff is done in radians.
private bool CheckIsTileClockwise(int Control$$anonymous$$ovementTileId, Vector3 tilePos, Vector3 playerPos)
{
switch (Control$$anonymous$$ovementTileId)
{
case 1:
{
if(tilePos.x < playerPos.x + 0.01f && tilePos.z < playerPos.z +0.01f)
return true;
else
return false;
}
case 2:
{
if(tilePos.x < playerPos.x + 0.01f && tilePos.z > playerPos.z +0.01f)
return true;
else
return false;
}
case 3:
if(tilePos.x < playerPos.x + 0.01f && tilePos.z > playerPos.z + 0.01f)
return true;
else
return false;
case 4:
if(tilePos.x > playerPos.x + 0.01f && tilePos.z > playerPos.z + 0.01f)
return true;
else
return false;
case 5:
if(tilePos.x > playerPos.x + 0.01f && tilePos.z < playerPos.z + 0.01f)
return true;
else
return false;
case 6:
if(tilePos.x > playerPos.x + 0.01f && tilePos.z < playerPos.z + 0.01f)
return true;
else
return false;
default:
return true;
}
}
Answer by AlwaysSunny · Feb 09, 2015 at 03:32 PM
I take it your tiles are part of a collection? And you can easily get a collection of tiles to check with something like
List<Tiles> clickable = GetAllTilesWithinStepsOf(int steps, Tile playerTile);
This way you've only got to run your IsClockwise() check on the tiles which actually matter.
I'm in a hurry and can't test this, but I think this should get you very close. You may need to reverse which argument comes first (playerPosition or tilePosition).
The .z in the sign test might need to be .x or .y depending on the planar orientation you've chosen for your project.
Just pass in the tile's position for a and the player's position for b, and this should give you useful data. Note that a and b must share the same "height" in whatever planar orientation you're using for this to be foolproof.
bool IsClockwise( Vector3 a, Vector3 b ) {
return ( Vector3.Cross(a,b).y < 0 );
}
What should this line of code be doing?
signedAngle *= $$anonymous$$athf.Sign( Vector3.Cross(a,b).z );
Because I set a debug.log(signedAngle); before that line and after it and the value is exactly the same.
Also how do I check what my planar orientation is? is that the axis that is pointing upwards?
Code you gave me seems to do partly what I want in to do, but still very buggy.
Hey hey, alright, here we go... The cross product of two vectors returns a vector that is perpendicular to the plane on which the two argument vectors lie.
http://docs.unity3d.com/ScriptReference/Vector3.Cross.html
Unity expects you to use X as width, Y as height, and Z as depth, but now that I re-exa$$anonymous$$e you're screenshot, I see that you are using the XZ plane for your 2D game. (Not what Unity intends, but I do that too!) When folks say things like planar orientation or "on what plane does the game take place" they typically mean, on which axis is there no motion. In your case, your plane is the XZ plane, because the omitted axis is Y.
Anyway, the .z becomes .y in the line you pointed out. Sorry for the mix-up.
The line you've indicated says, "Find me a vector perpendicular to the plane on which the other two lie, and return the sign of its significant component." It just so happens the sign of this data Sign(Cross(a,b).y) informs you whether the second vector is clockwise or anti-clockwise versus the first.
This was taken from my "signed angle" method. I just realized you don't NEED the signed angle. So your whole method could be
bool IsClockwise( Vector3 a, Vector3 b ) {
return ( Vector3.Cross(a,b).y < 0 );
}
AlwaysSunny, You've made my day!!! the code is working perfectly like I want it to work :D Seems a bit strange at first since the previous code seems to be almost exactly the same and I tested it with .x, .y and .z and in the new code it seems like you've only changed the .z to .y xD
But thanks a lot! been searching for this a while now and only got it to work buggy, now it works like a charm!
Glad to hear it! Passing along trade tricks is always a pleasure.
Your answer
Follow this Question
Related Questions
Checker Board Grid 0 Answers
Building a Chessboard 2 Answers
Touch and Drag 3D Objects on a Grid (for Android) 0 Answers
Creating a 2D Movement Grid 0 Answers