using System; using UnityEngine; [CreateAssetMenu] public class MapData : ScriptableObject { static readonly Vector2[] AxialDirections = { new Vector2(0, 1), new Vector2(1, 0), new Vector2(1, -1), new Vector2(0, -1), new Vector2(-1, 0), new Vector2(-1, 1) }; //With flat hexes public enum Direction { Up = 0, UpRight = 1, DownRight = 2, Down = 3, DownLeft = 4, UpLeft = 5 } /* With pointy hexes enum Direction { Right, UpRight, UpLeft, Left, DownLeft, DownRight }*/ public float hexSize = 1f; //TODO would be nice if I could store a Matrix2x2 public Vector3 AxialToWorld(Vector2 axial) => hexSize * new Vector3( (3f / 2) * axial.x, 0, (Mathf.Sqrt(3) / 2) * axial.x + Mathf.Sqrt(3) * axial.y ); public Vector2 WorldToAxial(Vector2 position) => RoundAxial(new Vector2( 2f / 3 * position.x, -1f / 3 * position.x + Mathf.Sqrt(3) / 3 * position.y ) / hexSize); public Vector2 WorldToAxial(Vector3 position) => WorldToAxial(new Vector2(position.x, position.z)); public static Vector2 RoundAxial(Vector2 axial) { Vector3 cube = AxialToCube(axial); Vector3 nearestCube = new Vector3( Mathf.Round(cube.x), Mathf.Round(cube.y), Mathf.Round(cube.z) ); Vector3 diff = new Vector3( Mathf.Abs(nearestCube.x - cube.x), Mathf.Abs(nearestCube.y - cube.y), Mathf.Abs(nearestCube.z - cube.z) ); if (diff.x > diff.y && diff.x > diff.z) nearestCube.x = -nearestCube.y - nearestCube.z; else if (diff.y > diff.z) nearestCube.y = -nearestCube.x - nearestCube.z; else nearestCube.z = -nearestCube.x - nearestCube.y; return CubeToAxial(nearestCube); } public static Vector3 AxialToCube(Vector2 axial) => new Vector3(axial.x, -axial.x - axial.y, axial.y); public static Vector2 CubeToAxial(Vector3 cube) => new Vector2(cube.x, cube.z); public static Vector2 GetNeighbor(Vector2 axial, Direction direction) => axial + AxialDirections[(int) direction]; }