You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Plugins/Animancer/Utilities/PixelPerfectPositioning.cs

74 lines
2.9 KiB
C#

// Animancer // Copyright 2020 Kybernetik //
using UnityEngine;
namespace Animancer
{
/// <summary>
/// Adjusts the <see cref="Transform.localPosition"/> every frame to keep this object aligned to a grid with a size
/// determined by the <see cref="Renderer"/> while wrapping the value to keep it as close to 0 as possible.
/// </summary>
[AddComponentMenu(Strings.MenuPrefix + "Pixel Perfect Positioning")]
[HelpURL(Strings.APIDocumentationURL + "/Pixel Perfect Positioning")]
public sealed class PixelPerfectPositioning : MonoBehaviour
{
/************************************************************************************************************************/
[SerializeField]
private SpriteRenderer _Renderer;
/// <summary>[<see cref="SerializeField"/>]
/// The <see cref="SpriteRenderer"/> that will have its position adjusted.
/// </summary>
public SpriteRenderer Renderer
{
get { return _Renderer; }
set { _Renderer = value; }
}
/************************************************************************************************************************/
#if UNITY_EDITOR
private void Reset()
{
_Renderer = Editor.AnimancerEditorUtilities.GetComponentInHierarchy<SpriteRenderer>(gameObject);
}
#endif
/************************************************************************************************************************/
private void Update()
{
var transform = _Renderer.transform;
var position = transform.position;
// Snap the position to the pixel grid.
var pixelsPerUnit = _Renderer.sprite.pixelsPerUnit;
transform.position = new Vector3(
Mathf.Round(position.x / pixelsPerUnit) * pixelsPerUnit,
Mathf.Round(position.y / pixelsPerUnit) * pixelsPerUnit,
Mathf.Round(position.z / pixelsPerUnit) * pixelsPerUnit);
// Keep the local position as small as possible while staying on the grid.
var maxLocalPosition = 0.5f / pixelsPerUnit;
position = transform.localPosition;
WrapValue(ref position.x, maxLocalPosition);
WrapValue(ref position.y, maxLocalPosition);
WrapValue(ref position.z, maxLocalPosition);
transform.localPosition = position;
}
/************************************************************************************************************************/
private void WrapValue(ref float value, float max)
{
value %= max * 2;
if (value > max) value -= max * 2;
else if (value < -max) value += max * 2;
}
/************************************************************************************************************************/
}
}