You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
14 KiB
318 lines
14 KiB
// Animancer // https://kybernetik.com.au/animancer // Copyright 2021 Kybernetik // |
|
|
|
using System; |
|
using UnityEngine; |
|
|
|
namespace Animancer |
|
{ |
|
/// <summary>A set of up/right/down/left animations with diagonals as well.</summary> |
|
/// <remarks> |
|
/// Documentation: <see href="https://kybernetik.com.au/animancer/docs/manual/playing/directional-sets">Directional Animation Sets</see> |
|
/// </remarks> |
|
/// https://kybernetik.com.au/animancer/api/Animancer/DirectionalAnimationSet8 |
|
/// |
|
[CreateAssetMenu(menuName = Strings.MenuPrefix + "Directional Animation Set/8 Directions", order = Strings.AssetMenuOrder + 11)] |
|
[HelpURL(Strings.DocsURLs.APIDocumentation + "/" + nameof(DirectionalAnimationSet8))] |
|
public class DirectionalAnimationSet8 : DirectionalAnimationSet |
|
{ |
|
/************************************************************************************************************************/ |
|
|
|
[SerializeField] |
|
private AnimationClip _UpRight; |
|
|
|
/// <summary>[<see cref="SerializeField"/>] The animation facing diagonally up-right ~(0.7, 0.7).</summary> |
|
/// <exception cref="ArgumentException"><see cref="AllowSetClips"/> was not called before setting this value.</exception> |
|
public AnimationClip UpRight |
|
{ |
|
get => _UpRight; |
|
set |
|
{ |
|
AssertCanSetClips(); |
|
_UpRight = value; |
|
AnimancerUtilities.SetDirty(this); |
|
} |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
[SerializeField] |
|
private AnimationClip _DownRight; |
|
|
|
/// <summary>[<see cref="SerializeField"/>] The animation facing diagonally down-right ~(0.7, -0.7).</summary> |
|
/// <exception cref="ArgumentException"><see cref="AllowSetClips"/> was not called before setting this value.</exception> |
|
public AnimationClip DownRight |
|
{ |
|
get => _DownRight; |
|
set |
|
{ |
|
AssertCanSetClips(); |
|
_DownRight = value; |
|
AnimancerUtilities.SetDirty(this); |
|
} |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
[SerializeField] |
|
private AnimationClip _DownLeft; |
|
|
|
/// <summary>[<see cref="SerializeField"/>] The animation facing diagonally down-left ~(-0.7, -0.7).</summary> |
|
/// <exception cref="ArgumentException"><see cref="AllowSetClips"/> was not called before setting this value.</exception> |
|
public AnimationClip DownLeft |
|
{ |
|
get => _DownLeft; |
|
set |
|
{ |
|
AssertCanSetClips(); |
|
_DownLeft = value; |
|
AnimancerUtilities.SetDirty(this); |
|
} |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
[SerializeField] |
|
private AnimationClip _UpLeft; |
|
|
|
/// <summary>[<see cref="SerializeField"/>] The animation facing diagonally up-left ~(-0.7, 0.7).</summary> |
|
/// <exception cref="ArgumentException"><see cref="AllowSetClips"/> was not called before setting this value.</exception> |
|
public AnimationClip UpLeft |
|
{ |
|
get => _UpLeft; |
|
set |
|
{ |
|
AssertCanSetClips(); |
|
_UpLeft = value; |
|
AnimancerUtilities.SetDirty(this); |
|
} |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Returns the animation closest to the specified `direction`.</summary> |
|
public override AnimationClip GetClip(Vector2 direction) |
|
{ |
|
var angle = Mathf.Atan2(direction.y, direction.x); |
|
var octant = Mathf.RoundToInt(8 * angle / (2 * Mathf.PI) + 8) % 8; |
|
switch (octant) |
|
{ |
|
case 0: return Right; |
|
case 1: return _UpRight; |
|
case 2: return Up; |
|
case 3: return _UpLeft; |
|
case 4: return Left; |
|
case 5: return _DownLeft; |
|
case 6: return Down; |
|
case 7: return _DownRight; |
|
default: throw new ArgumentOutOfRangeException("Invalid octant"); |
|
} |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
#region Directions |
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Constants for each of the diagonal directions.</summary> |
|
/// <remarks> |
|
/// Documentation: <see href="https://kybernetik.com.au/animancer/docs/manual/playing/directional-sets">Directional Animation Sets</see> |
|
/// </remarks> |
|
/// https://kybernetik.com.au/animancer/api/Animancer/Diagonals |
|
/// |
|
public static class Diagonals |
|
{ |
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>1 / (Square Root of 2).</summary> |
|
public const float OneOverSqrt2 = 0.70710678118f; |
|
|
|
/// <summary>A vector with a magnitude of 1 pointing up to the right.</summary> |
|
/// <remarks>The value is approximately (0.7, 0.7).</remarks> |
|
public static Vector2 UpRight => new Vector2(OneOverSqrt2, OneOverSqrt2); |
|
|
|
/// <summary>A vector with a magnitude of 1 pointing down to the right.</summary> |
|
/// <remarks>The value is approximately (0.7, -0.7).</remarks> |
|
public static Vector2 DownRight => new Vector2(OneOverSqrt2, -OneOverSqrt2); |
|
|
|
/// <summary>A vector with a magnitude of 1 pointing down to the left.</summary> |
|
/// <remarks>The value is approximately (-0.7, -0.7).</remarks> |
|
public static Vector2 DownLeft => new Vector2(-OneOverSqrt2, -OneOverSqrt2); |
|
|
|
/// <summary>A vector with a magnitude of 1 pointing up to the left.</summary> |
|
/// <remarks>The value is approximately (-0.707, 0.707).</remarks> |
|
public static Vector2 UpLeft => new Vector2(-OneOverSqrt2, OneOverSqrt2); |
|
|
|
/************************************************************************************************************************/ |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
public override int ClipCount => 8; |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Up, Right, Down, Left, or their diagonals.</summary> |
|
/// <remarks> |
|
/// Documentation: <see href="https://kybernetik.com.au/animancer/docs/manual/playing/directional-sets">Directional Animation Sets</see> |
|
/// </remarks> |
|
/// https://kybernetik.com.au/animancer/api/Animancer/Direction |
|
/// |
|
public new enum Direction |
|
{ |
|
/// <summary><see cref="Vector2.up"/>.</summary> |
|
Up, |
|
|
|
/// <summary><see cref="Vector2.right"/>.</summary> |
|
Right, |
|
|
|
/// <summary><see cref="Vector2.down"/>.</summary> |
|
Down, |
|
|
|
/// <summary><see cref="Vector2.left"/>.</summary> |
|
Left, |
|
|
|
/// <summary><see cref="Vector2"/>(0.7..., 0.7...).</summary> |
|
UpRight, |
|
|
|
/// <summary><see cref="Vector2"/>(0.7..., -0.7...).</summary> |
|
DownRight, |
|
|
|
/// <summary><see cref="Vector2"/>(-0.7..., -0.7...).</summary> |
|
DownLeft, |
|
|
|
/// <summary><see cref="Vector2"/>(-0.7..., 0.7...).</summary> |
|
UpLeft, |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
protected override string GetDirectionName(int direction) => ((Direction)direction).ToString(); |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Returns the animation associated with the specified `direction`.</summary> |
|
public AnimationClip GetClip(Direction direction) |
|
{ |
|
switch (direction) |
|
{ |
|
case Direction.Up: return Up; |
|
case Direction.Right: return Right; |
|
case Direction.Down: return Down; |
|
case Direction.Left: return Left; |
|
case Direction.UpRight: return _UpRight; |
|
case Direction.DownRight: return _DownRight; |
|
case Direction.DownLeft: return _DownLeft; |
|
case Direction.UpLeft: return _UpLeft; |
|
default: throw new ArgumentException($"Unsupported {nameof(Direction)}: {direction}"); |
|
} |
|
} |
|
|
|
public override AnimationClip GetClip(int direction) => GetClip((Direction)direction); |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Sets the animation associated with the specified `direction`.</summary> |
|
public void SetClip(Direction direction, AnimationClip clip) |
|
{ |
|
switch (direction) |
|
{ |
|
case Direction.Up: Up = clip; break; |
|
case Direction.Right: Right = clip; break; |
|
case Direction.Down: Down = clip; break; |
|
case Direction.Left: Left = clip; break; |
|
case Direction.UpRight: UpRight = clip; break; |
|
case Direction.DownRight: DownRight = clip; break; |
|
case Direction.DownLeft: DownLeft = clip; break; |
|
case Direction.UpLeft: UpLeft = clip; break; |
|
default: throw new ArgumentException($"Unsupported {nameof(Direction)}: {direction}"); |
|
} |
|
} |
|
|
|
public override void SetClip(int direction, AnimationClip clip) => SetClip((Direction)direction, clip); |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Returns a vector representing the specified `direction`.</summary> |
|
public static Vector2 DirectionToVector(Direction direction) |
|
{ |
|
switch (direction) |
|
{ |
|
case Direction.Up: return Vector2.up; |
|
case Direction.Right: return Vector2.right; |
|
case Direction.Down: return Vector2.down; |
|
case Direction.Left: return Vector2.left; |
|
case Direction.UpRight: return Diagonals.UpRight; |
|
case Direction.DownRight: return Diagonals.DownRight; |
|
case Direction.DownLeft: return Diagonals.DownLeft; |
|
case Direction.UpLeft: return Diagonals.UpLeft; |
|
default: throw new ArgumentException($"Unsupported {nameof(Direction)}: {direction}"); |
|
} |
|
} |
|
|
|
public override Vector2 GetDirection(int direction) => DirectionToVector((Direction)direction); |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Returns the direction closest to the specified `vector`.</summary> |
|
public new static Direction VectorToDirection(Vector2 vector) |
|
{ |
|
var angle = Mathf.Atan2(vector.y, vector.x); |
|
var octant = Mathf.RoundToInt(8 * angle / (2 * Mathf.PI) + 8) % 8; |
|
switch (octant) |
|
{ |
|
case 0: return Direction.Right; |
|
case 1: return Direction.UpRight; |
|
case 2: return Direction.Up; |
|
case 3: return Direction.UpLeft; |
|
case 4: return Direction.Left; |
|
case 5: return Direction.DownLeft; |
|
case 6: return Direction.Down; |
|
case 7: return Direction.DownRight; |
|
default: throw new ArgumentOutOfRangeException("Invalid octant"); |
|
} |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
|
|
/// <summary>Returns a copy of the `vector` pointing in the closest direction this set type has an animation for.</summary> |
|
public new static Vector2 SnapVectorToDirection(Vector2 vector) |
|
{ |
|
var magnitude = vector.magnitude; |
|
var direction = VectorToDirection(vector); |
|
vector = DirectionToVector(direction) * magnitude; |
|
return vector; |
|
} |
|
|
|
public override Vector2 Snap(Vector2 vector) => SnapVectorToDirection(vector); |
|
|
|
/************************************************************************************************************************/ |
|
#endregion |
|
/************************************************************************************************************************/ |
|
#region Name Based Operations |
|
/************************************************************************************************************************/ |
|
#if UNITY_EDITOR |
|
/************************************************************************************************************************/ |
|
|
|
public override int SetClipByName(AnimationClip clip) |
|
{ |
|
var name = clip.name; |
|
|
|
var directionCount = ClipCount; |
|
for (int i = directionCount - 1; i >= 0; i--) |
|
{ |
|
if (name.Contains(GetDirectionName(i))) |
|
{ |
|
SetClip(i, clip); |
|
return i; |
|
} |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
/************************************************************************************************************************/ |
|
#endif |
|
/************************************************************************************************************************/ |
|
#endregion |
|
/************************************************************************************************************************/ |
|
} |
|
}
|
|
|