Skip to content

Instantly share code, notes, and snippets.

@leegrey
Created June 22, 2017 11:35
Show Gist options
  • Save leegrey/d72964eb4675999eae65dc9b5076fbe9 to your computer and use it in GitHub Desktop.
Save leegrey/d72964eb4675999eae65dc9b5076fbe9 to your computer and use it in GitHub Desktop.
A Unity3D class for snapping pixel art to multiples of a whole (design scale) pixel
using UnityEngine;
/*
A Unity3D class for snapping pixel art to multiples of a whole (design scale) pixel
Use in conjunction with an appropriately scaled Otho Camera
License: MIT
Written by Lee Grey (@mothteeth)
*/
namespace lg
{
// a static config... shared throughout the entire pixel snap system
public static class PixelConfig
{
private static int pixelsPerUnit = 16;
private static float pixelSize = 1f / pixelsPerUnit;
public static bool DefaultSetDepth = false;
public static float PixelSize { get { return pixelSize; } }
public static int PixelsPerUnit {
get { return pixelsPerUnit; }
set
{
pixelsPerUnit = value;
pixelSize = 1f / pixelsPerUnit;
}
}
}
public class PixelController : MonoBehaviour
{
// body object is an optional child object to snap,
// otherwise the top level object is snapped
public GameObject bodyObject;
public bool setWorldDepth = PixelConfig.DefaultSetDepth;
public bool snapEveryFrame = false;
void Start()
{
// if no bodyObject is supplied, use self
if (bodyObject == null)
{
bodyObject = gameObject;
}
}
public int X {
get
{
//float snapSize = 1f / PixelConfig.PixelsPerUnit;
Vector2 pos = gameObject.transform.position;
return Mathf.RoundToInt(pos.x / PixelConfig.PixelSize);
}
set
{
Vector2 pos = gameObject.transform.position;
pos.x = value * PixelConfig.PixelSize;
transform.position = pos;
}
}
public int Y
{
get
{
Vector2 pos = gameObject.transform.position;
return Mathf.RoundToInt(pos.y / PixelConfig.PixelSize);
}
set
{
Vector2 pos = gameObject.transform.position;
pos.y = value * PixelConfig.PixelSize;
transform.position = pos;
}
}
public Vector2 pixelPosition {
get
{
Vector2 pos = gameObject.transform.position;
pos.x = Mathf.Floor(pos.x / PixelConfig.PixelSize);
pos.y = Mathf.Floor(pos.y / PixelConfig.PixelSize);
return pos;
}
set
{
var pos = gameObject.transform.position;
pos.x = Mathf.Round(pos.x * PixelConfig.PixelsPerUnit) / PixelConfig.PixelsPerUnit;
pos.y = Mathf.Round(pos.y * PixelConfig.PixelsPerUnit) / PixelConfig.PixelsPerUnit;
if (setWorldDepth)
{
pos.z = pos.y;
transform.position = pos;
}
bodyObject.transform.position = pos;
}
}
// Update is called once per frame
void Update()
{
if (bodyObject != null)
{
Snap();
}
// deactivate this component if it is not set to snap every frame
// (ie it is just a first-startup snap event)
if (snapEveryFrame == false)
{
enabled = false;
}
}
// NOTE: snap leaves depth as assigned, as it doesn't affect the snapping
public void Snap()
{
// if no bodyObject is supplied, use self
if (bodyObject == null)
{
bodyObject = gameObject;
}
var pos = gameObject.transform.position;
pos.x = Mathf.Round(pos.x * PixelConfig.PixelsPerUnit) / PixelConfig.PixelsPerUnit;
pos.y = Mathf.Round(pos.y * PixelConfig.PixelsPerUnit) / PixelConfig.PixelsPerUnit;
if (setWorldDepth)
{
pos.z = pos.y;
transform.position = pos;
}
bodyObject.transform.position = pos;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment