Created
June 22, 2017 11:35
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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