228 lines
8.9 KiB
C#
228 lines
8.9 KiB
C#
// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2026 Kybernetik //
|
|
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Animancer
|
|
{
|
|
/// <summary>A generic set of objects corresponding to up/right/down/left with diagonals as well.</summary>
|
|
/// <remarks>
|
|
/// <strong>Documentation:</strong>
|
|
/// <see href="https://kybernetik.com.au/animancer/docs/manual/playing/directional-sets">
|
|
/// Directional Animation Sets</see>
|
|
/// </remarks>
|
|
/// https://kybernetik.com.au/animancer/api/Animancer/DirectionalSet8_1
|
|
///
|
|
[AnimancerHelpUrl(typeof(DirectionalSet8<>))]
|
|
public class DirectionalSet8<T> : DirectionalSet4<T>
|
|
{
|
|
/************************************************************************************************************************/
|
|
#region Fields and Properties
|
|
/************************************************************************************************************************/
|
|
|
|
[SerializeField]
|
|
private T _UpRight;
|
|
|
|
/// <summary>[<see cref="SerializeField"/>] The object for <see cref="Direction8.UpRight"/>.</summary>
|
|
/// <exception cref="ArgumentException"><see cref="AllowChanges"/> was not called before setting this value.</exception>
|
|
public T UpRight
|
|
{
|
|
get => _UpRight;
|
|
set
|
|
{
|
|
AssertAllowChanges();
|
|
_UpRight = value;
|
|
AnimancerUtilities.SetDirty(this);
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
[SerializeField]
|
|
private T _DownRight;
|
|
|
|
/// <summary>[<see cref="SerializeField"/>] The object for <see cref="Direction8.DownRight"/>.</summary>
|
|
/// <exception cref="ArgumentException"><see cref="AllowChanges"/> was not called before setting this value.</exception>
|
|
public T DownRight
|
|
{
|
|
get => _DownRight;
|
|
set
|
|
{
|
|
AssertAllowChanges();
|
|
_DownRight = value;
|
|
AnimancerUtilities.SetDirty(this);
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
[SerializeField]
|
|
private T _DownLeft;
|
|
|
|
/// <summary>[<see cref="SerializeField"/>] The object for <see cref="Direction8.DownLeft"/>.</summary>
|
|
/// <exception cref="ArgumentException"><see cref="AllowChanges"/> was not called before setting this value.</exception>
|
|
public T DownLeft
|
|
{
|
|
get => _DownLeft;
|
|
set
|
|
{
|
|
AssertAllowChanges();
|
|
_DownLeft = value;
|
|
AnimancerUtilities.SetDirty(this);
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
[SerializeField]
|
|
private T _UpLeft;
|
|
|
|
/// <summary>[<see cref="SerializeField"/>] The object for <see cref="Direction8.UpLeft"/>.</summary>
|
|
/// <exception cref="ArgumentException"><see cref="AllowChanges"/> was not called before setting this value.</exception>
|
|
public T UpLeft
|
|
{
|
|
get => _UpLeft;
|
|
set
|
|
{
|
|
AssertAllowChanges();
|
|
_UpLeft = value;
|
|
AnimancerUtilities.SetDirty(this);
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
#endregion
|
|
/************************************************************************************************************************/
|
|
#region Directions
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
public override int DirectionCount
|
|
=> 8;
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
protected override string GetDirectionName(int direction)
|
|
=> ((Direction8)direction).ToString();
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Returns the object associated with the specified `direction`.</summary>
|
|
public T Get(Direction8 direction)
|
|
=> direction switch
|
|
{
|
|
Direction8.Up => Up,
|
|
Direction8.Right => Right,
|
|
Direction8.Down => Down,
|
|
Direction8.Left => Left,
|
|
Direction8.UpRight => _UpRight,
|
|
Direction8.DownRight => _DownRight,
|
|
Direction8.DownLeft => _DownLeft,
|
|
Direction8.UpLeft => _UpLeft,
|
|
_ => throw AnimancerUtilities.CreateUnsupportedArgumentException(direction),
|
|
};
|
|
|
|
/// <inheritdoc/>
|
|
public override T Get(int direction)
|
|
=> Get((Direction8)direction);
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
public override T Get(Vector2 direction)
|
|
{
|
|
var angle = Mathf.Atan2(direction.y, direction.x);
|
|
var octant = Mathf.RoundToInt(8 * angle / (2 * Mathf.PI) + 8) % 8;
|
|
return octant switch
|
|
{
|
|
0 => Right,
|
|
1 => _UpRight,
|
|
2 => Up,
|
|
3 => _UpLeft,
|
|
4 => Left,
|
|
5 => _DownLeft,
|
|
6 => Down,
|
|
7 => _DownRight,
|
|
_ => throw new ArgumentOutOfRangeException("Invalid octant"),
|
|
};
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Sets the object associated with the specified `direction`.</summary>
|
|
public void Set(Direction8 direction, T value)
|
|
{
|
|
switch (direction)
|
|
{
|
|
case Direction8.Up: Up = value; break;
|
|
case Direction8.Right: Right = value; break;
|
|
case Direction8.Down: Down = value; break;
|
|
case Direction8.Left: Left = value; break;
|
|
case Direction8.UpRight: UpRight = value; break;
|
|
case Direction8.DownRight: DownRight = value; break;
|
|
case Direction8.DownLeft: DownLeft = value; break;
|
|
case Direction8.UpLeft: UpLeft = value; break;
|
|
default: throw AnimancerUtilities.CreateUnsupportedArgumentException(direction);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override void Set(int direction, T value)
|
|
=> Set((Direction8)direction, value);
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
public override Vector2 GetDirection(int direction)
|
|
=> ((Direction8)direction).ToVector2();
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
public override int GetDirection(string name)
|
|
{
|
|
var direction = AnimancerUtilities.GetDirection(name);
|
|
|
|
if (direction.x == 0)
|
|
{
|
|
if (direction.y > 0)
|
|
return (int)Direction8.Up;
|
|
else if (direction.y < 0)
|
|
return (int)Direction8.Down;
|
|
else
|
|
return -1;
|
|
}
|
|
else if (direction.x > 0)
|
|
{
|
|
if (direction.y > 0)
|
|
return (int)Direction8.UpRight;
|
|
else if (direction.y < 0)
|
|
return (int)Direction8.DownRight;
|
|
else
|
|
return (int)Direction8.Right;
|
|
}
|
|
else
|
|
{
|
|
if (direction.y > 0)
|
|
return (int)Direction8.UpLeft;
|
|
else if (direction.y < 0)
|
|
return (int)Direction8.DownLeft;
|
|
else
|
|
return (int)Direction8.Left;
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
public override Vector2 Snap(Vector2 vector)
|
|
=> Directions.SnapToDirection8(vector);
|
|
|
|
/************************************************************************************************************************/
|
|
#endregion
|
|
/************************************************************************************************************************/
|
|
}
|
|
}
|
|
|