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.
74 lines
2.9 KiB
C#
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;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
}
|
|
}
|