// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2026 Kybernetik // using System; using UnityEngine; namespace Animancer { /// Left or Right. /// /// Documentation: /// /// Directional Animation Sets /// /// https://kybernetik.com.au/animancer/api/Animancer/Direction2 /// public enum Direction2 { /************************************************************************************************************************/ /// . Left, /// . Right, /************************************************************************************************************************/ } /************************************************************************************************************************/ /// Up, Right, Down, or Left. /// /// Documentation: /// /// Directional Animation Sets /// /// https://kybernetik.com.au/animancer/api/Animancer/Direction4 /// public enum Direction4 { /************************************************************************************************************************/ /// . Up, /// . Right, /// . Down, /// . Left, /************************************************************************************************************************/ } /************************************************************************************************************************/ /// Up, Right, Down, Left, or their diagonals. /// /// Documentation: /// /// Directional Animation Sets /// /// https://kybernetik.com.au/animancer/api/Animancer/Direction8 /// public enum Direction8 { /// . Up, /// . Right, /// . Down, /// . Left, /// (0.7..., 0.7...). UpRight, /// (0.7..., -0.7...). DownRight, /// (-0.7..., -0.7...). DownLeft, /// (-0.7..., 0.7...). UpLeft, } /************************************************************************************************************************/ /// /// Utilities relating to , and . /// /// /// Documentation: /// /// Directional Animation Sets /// /// https://kybernetik.com.au/animancer/api/Animancer/Directions /// public static class Directions { /************************************************************************************************************************/ /// 1 / (Square Root of 2). public const float InverseSqrt2 = 0.70710678118f; /// A vector with a magnitude of 1 pointing up to the right. /// The value is approximately (0.7, 0.7). public static Vector2 UpRight => new(InverseSqrt2, InverseSqrt2); /// A vector with a magnitude of 1 pointing down to the right. /// The value is approximately (0.7, -0.7). public static Vector2 DownRight => new(InverseSqrt2, -InverseSqrt2); /// A vector with a magnitude of 1 pointing down to the left. /// The value is approximately (-0.7, -0.7). public static Vector2 DownLeft => new(-InverseSqrt2, -InverseSqrt2); /// A vector with a magnitude of 1 pointing up to the left. /// The value is approximately (-0.707, 0.707). public static Vector2 UpLeft => new(-InverseSqrt2, InverseSqrt2); /************************************************************************************************************************/ /// Returns the opposite of the given `direction`. public static Direction2 GetOppositeDirection(this Direction2 direction) => (Direction2)(1 - direction); /// Returns the opposite of the given `direction`. public static Direction4 GetOppositeDirection(this Direction4 direction) => (Direction4)((int)(direction + 2) % 4); /// Returns the opposite of the given `direction`. public static Direction8 GetOppositeDirection(this Direction8 direction) => (Direction8)((int)(direction + 4) % 8); /************************************************************************************************************************/ /// Returns a vector representing the specified `direction`. public static Vector2 ToVector2(this Direction2 direction) => direction switch { Direction2.Left => Vector2.left, Direction2.Right => Vector2.right, _ => throw AnimancerUtilities.CreateUnsupportedArgumentException(direction), }; /// Returns a vector representing the specified `direction`. public static Vector2 ToVector2(this Direction4 direction) => direction switch { Direction4.Up => Vector2.up, Direction4.Right => Vector2.right, Direction4.Down => Vector2.down, Direction4.Left => Vector2.left, _ => throw AnimancerUtilities.CreateUnsupportedArgumentException(direction), }; /// Returns a vector representing the specified `direction`. public static Vector2 ToVector2(this Direction8 direction) => direction switch { Direction8.Up => Vector2.up, Direction8.Right => Vector2.right, Direction8.Down => Vector2.down, Direction8.Left => Vector2.left, Direction8.UpRight => UpRight, Direction8.DownRight => DownRight, Direction8.DownLeft => DownLeft, Direction8.UpLeft => UpLeft, _ => throw AnimancerUtilities.CreateUnsupportedArgumentException(direction), }; /************************************************************************************************************************/ /// Returns the direction closest to the specified `vector.x`. /// Negative `direction` returns , 0 or positive returns . public static Direction2 ToDirection2(Vector2 vector) => ToDirection2(vector.x); /// Returns the direction closest to the specified `direction`. /// Negative `direction` returns , 0 or positive returns . public static Direction2 ToDirection2(float direction) => direction < 0 ? Direction2.Left : Direction2.Right; /************************************************************************************************************************/ /// Returns the direction closest to the specified `vector`. public static Direction4 ToDirection4(Vector2 vector) { if (vector.x >= 0) { if (vector.y >= 0) return vector.x > vector.y ? Direction4.Right : Direction4.Up; else return vector.x > -vector.y ? Direction4.Right : Direction4.Down; } else { if (vector.y >= 0) return vector.x < -vector.y ? Direction4.Left : Direction4.Up; else return vector.x < vector.y ? Direction4.Left : Direction4.Down; } } /// Returns the direction closest to the specified `vector`. public static Direction4 ToDirection4(Vector2Int vector) { if (vector.x >= 0) { if (vector.y >= 0) return vector.x > vector.y ? Direction4.Right : Direction4.Up; else return vector.x > -vector.y ? Direction4.Right : Direction4.Down; } else { if (vector.y >= 0) return vector.x < -vector.y ? Direction4.Left : Direction4.Up; else return vector.x < vector.y ? Direction4.Left : Direction4.Down; } } /************************************************************************************************************************/ /// Returns the direction closest to the specified `vector`. public static Direction8 ToDirection8(Vector2 vector) { var angle = Mathf.Atan2(vector.y, vector.x); var octant = Mathf.RoundToInt(8 * angle / (2 * Mathf.PI) + 8) % 8; return octant switch { 0 => Direction8.Right, 1 => Direction8.UpRight, 2 => Direction8.Up, 3 => Direction8.UpLeft, 4 => Direction8.Left, 5 => Direction8.DownLeft, 6 => Direction8.Down, 7 => Direction8.DownRight, _ => throw new ArgumentOutOfRangeException("Invalid octant"), }; } /************************************************************************************************************************/ /// Returns a copy of the `vector` pointing in the closest . public static Vector2 SnapToDirection2(Vector2 vector) => vector.x < 0 ? new(-vector.magnitude, 0) : new(vector.magnitude, 0); /// Returns a copy of the `vector` pointing in the closest . public static Vector2 SnapToDirection4(Vector2 vector) { var magnitude = vector.magnitude; var direction = ToDirection4(vector); vector = direction.ToVector2() * magnitude; return vector; } /// Returns a copy of the `vector` pointing in the closest . public static Vector2 SnapToDirection8(Vector2 vector) { var magnitude = vector.magnitude; var direction = ToDirection8(vector); vector = direction.ToVector2() * magnitude; return vector; } /************************************************************************************************************************/ } }