Created
March 13, 2013 09:17
-
-
Save N-Carter/5150477 to your computer and use it in GitHub Desktop.
Tilemap made up of batched TextMesh prefabs (could also work with other meshes)
This file contains hidden or 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; | |
using System.Collections; | |
public class EndlessTiles : MonoBehaviour | |
{ | |
[SerializeField] protected Tile m_TilePrefab; | |
[SerializeField] protected Material[] m_Materials; | |
[SerializeField] protected Material m_TouchedMaterial; | |
protected Tile[,] m_Tiles; | |
protected int m_Width; | |
protected int m_Height; | |
protected Tile[] m_SpareRow; | |
protected Tile[] m_SpareColumn; | |
protected Vector3 m_Movement; | |
Camera m_MainCamera; | |
protected void Start() | |
{ | |
m_MainCamera = Camera.main; | |
Rect extents = GetViewExtents(); | |
m_MainCamera.transform.position += new Vector3((extents.width + 1.0f) * 0.5f, 0.0f, (extents.height + 1.0f) * 0.5f); | |
m_Width = (int)extents.width + 2; | |
m_Height = (int)extents.height + 2; | |
m_Tiles = new Tile[m_Width, m_Height]; | |
m_SpareRow = new Tile[m_Width]; | |
m_SpareColumn = new Tile[m_Height]; | |
Quaternion rotation = m_TilePrefab.transform.rotation; | |
float scale = m_TilePrefab.textMesh.characterSize * 0.1f; // Why are characters 1/10th of a unit high by default? | |
for(int y = 0; y < m_Height; ++y) | |
{ | |
for(int x = 0; x < m_Width; ++x) | |
{ | |
var tile = (Tile)Instantiate(m_TilePrefab, new Vector3(x, 0, y) * scale, rotation); | |
tile.endlessTiles = this; | |
tile.transform.parent = transform; | |
m_Tiles[x, y] = tile; | |
} | |
} | |
FillTiles(0, m_Width, 0, m_Height); | |
} | |
public Rect GetViewExtents() | |
{ | |
Vector3 minCorner = GetPositionOnPlane(Vector3.zero); | |
Vector3 maxCorner = GetPositionOnPlane(new Vector3(m_MainCamera.pixelWidth, m_MainCamera.pixelHeight, 0.0f)); | |
return new Rect(minCorner.x, minCorner.z, maxCorner.x - minCorner.x, maxCorner.z - minCorner.z); | |
} | |
public Vector3 GetPositionOnPlane(Vector3 screenPosition) | |
{ | |
Ray ray = m_MainCamera.ScreenPointToRay(screenPosition); | |
Plane plane = new Plane(Vector3.up, Vector3.zero); | |
float distance; | |
if(plane.Raycast(ray, out distance)) | |
{ | |
// Debug.DrawRay(ray.origin, ray.direction * distance, Color.green, 1.0f); | |
return ray.origin + ray.direction * distance; | |
} | |
Debug.Log("Plane.Raycast missed the plane! Your camera is pointing in a stupid direction!"); | |
return new Vector3(0, 0, 100); | |
} | |
public Tile GetTileAtPosition(Vector3 position) | |
{ | |
Vector3 transformPosition = transform.position; | |
int x = Mathf.RoundToInt(position.x - transformPosition.x % 1.0f); | |
int y = Mathf.RoundToInt(position.z - transformPosition.z % 1.0f); | |
return m_Tiles[x, y]; | |
} | |
public void Move(Vector3 offset) | |
{ | |
m_Movement = offset; | |
Vector3 position = transform.position; | |
position += offset; | |
if(position.x < 0.0f) | |
{ | |
position.x += 1.0f; | |
MoveTilesRight(); | |
} | |
else if(position.x > 1.0f) | |
{ | |
position.x -= 1.0f; | |
MoveTilesLeft(); | |
} | |
if(position.z < 0.0f) | |
{ | |
position.z += 1.0f; | |
MoveTilesUp(); | |
} | |
else if(position.z > 1.0f) | |
{ | |
position.z -= 1.0f; | |
MoveTilesDown(); | |
} | |
transform.position = position; | |
} | |
protected void MoveTilesLeft() | |
{ | |
StoreColumn(m_Width - 1); | |
for(int x = m_Width - 1; x > 0; --x) | |
{ | |
for(int y = 0; y < m_Height; ++y) | |
MoveTile(x - 1, y, x, y); | |
} | |
RestoreColumn(0); | |
FillTiles(0, 1, 0, m_Height); | |
} | |
protected void MoveTilesRight() | |
{ | |
StoreColumn(0); | |
for(int x = 0; x < m_Width - 1; ++x) | |
{ | |
for(int y = 0; y < m_Height; ++y) | |
MoveTile(x + 1, y, x, y); | |
} | |
RestoreColumn(m_Width - 1); | |
FillTiles(m_Width - 1, m_Width, 0, m_Height); | |
} | |
protected void MoveTilesDown() | |
{ | |
StoreRow(m_Height - 1); | |
for(int y = m_Height - 1; y > 0; --y) | |
{ | |
for(int x = 0; x < m_Width; ++x) | |
MoveTile(x, y - 1, x, y); | |
} | |
RestoreRow(0); | |
FillTiles(0, m_Width, 0, 1); | |
} | |
protected void MoveTilesUp() | |
{ | |
StoreRow(0); | |
for(int y = 0; y < m_Height - 1; ++y) | |
{ | |
for(int x = 0; x < m_Width; ++x) | |
MoveTile(x, y + 1, x, y); | |
} | |
RestoreRow(m_Height - 1); | |
FillTiles(0, m_Width, m_Height - 1, m_Height); | |
} | |
protected void MoveTile(int fromX, int fromY, int toX, int toY) | |
{ | |
// System.Console.WriteLine("{0}, {1} => {2}, {3}", fromX, fromY, toX, toY); | |
var fromTile = m_Tiles[fromX, fromY]; | |
RepositionTile(fromTile, toX - fromX, toY - fromY); | |
m_Tiles[toX, toY] = fromTile; | |
} | |
protected void RepositionTile(Tile tile, int offsetX, int offsetY) | |
{ | |
Vector3 position = tile.transform.localPosition; | |
tile.transform.localPosition = new Vector3((int)(position.x + offsetX), position.y, (int)(position.z + offsetY)); | |
} | |
protected void StoreColumn(int x) | |
{ | |
for(int y = 0; y < m_Height; ++y) | |
m_SpareColumn[y] = m_Tiles[x, y]; | |
} | |
protected void RestoreColumn(int x) | |
{ | |
// Only meant to work on the outermost columns: | |
int offset = (m_Width - 1) * (x == 0 ? -1 : 1); | |
for(int y = 0; y < m_Height; ++y) | |
{ | |
var tile = m_SpareColumn[y]; | |
RepositionTile(tile, offset, 0); | |
m_Tiles[x, y] = tile; | |
} | |
} | |
protected void StoreRow(int y) | |
{ | |
for(int x = 0; x < m_Width; ++x) | |
m_SpareRow[x] = m_Tiles[x, y]; | |
} | |
protected void RestoreRow(int y) | |
{ | |
// Only meant to work on the outermost columns: | |
int offset = (m_Height - 1) * (y == 0 ? -1 : 1); | |
for(int x = 0; x < m_Width; ++x) | |
{ | |
var tile = m_SpareRow[x]; | |
RepositionTile(tile, 0, offset); | |
m_Tiles[x, y] = tile; | |
} | |
} | |
protected void FillTiles(int startX, int endX, int startY, int endY) | |
{ | |
for(int y = startY; y < endY; ++y) | |
{ | |
for(int x = startX; x < endX; ++x) | |
{ | |
var tile = m_Tiles[x, y]; | |
tile.Reset(); | |
} | |
} | |
} | |
public Vector3 Movement {get {return m_Movement;}} | |
public Material[] Materials {get {return m_Materials;}} | |
public Material TouchedMaterial {get {return m_TouchedMaterial;}} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment