Adding falling blocks.

This commit is contained in:
Anonymous Raccoon
2018-10-06 21:36:33 +02:00
parent cbb7319a8a
commit 386b276221
909 changed files with 5563 additions and 426 deletions

8
Assets/2d-extras.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 981ff7b6c06bc1c40bed711a2d4f5808
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

36
Assets/2d-extras/.gitignore vendored Normal file
View File

@@ -0,0 +1,36 @@
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/Assets/AssetStoreTools*
/[Pp]ackages/
/[Pp]rojectSettings/
# Visual Studio 2015 cache directory
/.vs/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
# Unity3D generated meta files
*.pidb.meta
# Unity3D Generated File On Crash Reports
sysinfo.txt
# Builds
*.apk
*.unitypackage

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3da55605e07be004f9b051d08fc7203c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: cf9ccd4324df2364db3ac79b01297df5
folderAsset: yes
timeCreated: 1499146935
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 43e293f28d16b1e49a0e7065fabda4f2
folderAsset: yes
timeCreated: 1499149605
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a9fdf071ee2746a4b9db02f10619fe06
folderAsset: yes
timeCreated: 1499149747
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2ea50964d54e5fe4daef60544c57e629
folderAsset: yes
timeCreated: 1499149760
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8b52b57c2118b2f4683f6e203db78e87
folderAsset: yes
timeCreated: 1499149765
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor
{
[CustomGridBrush(true, false, false, "Coordinate Brush")]
[CreateAssetMenu(fileName = "New Coordinate Brush", menuName = "Brushes/Coordinate Brush")]
public class CoordinateBrush : GridBrush {
public int z = 0;
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
var zPosition = new Vector3Int(position.x, position.y, z);
base.Paint(grid, brushTarget, zPosition);
}
public override void Erase(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
var zPosition = new Vector3Int(position.x, position.y, z);
base.Erase(grid, brushTarget, zPosition);
}
public override void FloodFill(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
var zPosition = new Vector3Int(position.x, position.y, z);
base.FloodFill(grid, brushTarget, zPosition);
}
public override void BoxFill(GridLayout gridLayout, GameObject brushTarget, BoundsInt position)
{
var zPosition = new Vector3Int(position.x, position.y, z);
position.position = zPosition;
base.BoxFill(gridLayout, brushTarget, position);
}
}
[CustomEditor(typeof(CoordinateBrush))]
public class CoordinateBrushEditor : GridBrushEditor
{
private CoordinateBrush coordinateBrush { get { return target as CoordinateBrush; } }
public override void PaintPreview(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
var zPosition = new Vector3Int(position.x, position.y, coordinateBrush.z);
base.PaintPreview(grid, brushTarget, zPosition);
}
public override void OnPaintSceneGUI(GridLayout grid, GameObject brushTarget, BoundsInt position, GridBrushBase.Tool tool, bool executing)
{
base.OnPaintSceneGUI(grid, brushTarget, position, tool, executing);
if (coordinateBrush.z != 0)
{
var zPosition = new Vector3Int(position.min.x, position.min.y, coordinateBrush.z);
BoundsInt newPosition = new BoundsInt(zPosition, position.size);
Vector3[] cellLocals = new Vector3[]
{
grid.CellToLocal(new Vector3Int(newPosition.min.x, newPosition.min.y, newPosition.min.z)),
grid.CellToLocal(new Vector3Int(newPosition.max.x, newPosition.min.y, newPosition.min.z)),
grid.CellToLocal(new Vector3Int(newPosition.max.x, newPosition.max.y, newPosition.min.z)),
grid.CellToLocal(new Vector3Int(newPosition.min.x, newPosition.max.y, newPosition.min.z))
};
Handles.color = Color.blue;
int i = 0;
for (int j = cellLocals.Length - 1; i < cellLocals.Length; j = i++)
{
Handles.DrawLine(cellLocals[j], cellLocals[i]);
}
}
var labelText = "Pos: " + new Vector3Int(position.x, position.y, coordinateBrush.z);
if (position.size.x > 1 || position.size.y > 1) {
labelText += " Size: " + new Vector2Int(position.size.x, position.size.y);
}
Handles.Label(grid.CellToWorld(new Vector3Int(position.x, position.y, coordinateBrush.z)), labelText);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d283e353fe1f4c34f8ac458281740fb4
timeCreated: 1499149770
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3664941e71bb62e4b94231620856f1c9
folderAsset: yes
timeCreated: 1501789833
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: becdef7ff3038f844a171e247f575688
folderAsset: yes
timeCreated: 1501789865
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 62c56be364c00f14ba85c5d3f280447c
folderAsset: yes
timeCreated: 1501789982
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,489 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
using Object = UnityEngine.Object;
namespace UnityEditor
{
[CustomGridBrush(true, false, false, "GameObject Brush")]
public class GameObjectBrush : GridBrushBase
{
[SerializeField]
[HideInInspector]
private BrushCell[] m_Cells;
[SerializeField]
[HideInInspector]
private Vector3Int m_Size;
[SerializeField]
[HideInInspector]
private Vector3Int m_Pivot;
public Vector3Int size { get { return m_Size; } set { m_Size = value; SizeUpdated(); } }
public Vector3Int pivot { get { return m_Pivot; } set { m_Pivot = value; } }
public BrushCell[] cells { get { return m_Cells; } }
public int cellCount { get { return m_Cells != null ? m_Cells.Length : 0; } }
public GameObjectBrush()
{
Init(Vector3Int.one, Vector3Int.zero);
SizeUpdated();
}
public void Init(Vector3Int size)
{
Init(size, Vector3Int.zero);
SizeUpdated();
}
public void Init(Vector3Int size, Vector3Int pivot)
{
m_Size = size;
m_Pivot = pivot;
SizeUpdated();
}
public override void Paint(GridLayout gridLayout, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Vector3Int min = position - pivot;
BoundsInt bounds = new BoundsInt(min, m_Size);
BoxFill(gridLayout, brushTarget, bounds);
}
private void PaintCell(GridLayout grid, Vector3Int position, Transform parent, BrushCell cell)
{
if (cell.gameObject != null)
{
SetSceneCell(grid, parent, position, cell.gameObject, cell.offset, cell.scale, cell.orientation);
}
}
public override void Erase(GridLayout gridLayout, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Vector3Int min = position - pivot;
BoundsInt bounds = new BoundsInt(min, m_Size);
BoxErase(gridLayout, brushTarget, bounds);
}
private void EraseCell(GridLayout grid, Vector3Int position, Transform parent)
{
ClearSceneCell(grid, parent, position);
}
public override void BoxFill(GridLayout gridLayout, GameObject brushTarget, BoundsInt position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
if (brushTarget == null)
return;
foreach (Vector3Int location in position.allPositionsWithin)
{
Vector3Int local = location - position.min;
BrushCell cell = m_Cells[GetCellIndexWrapAround(local.x, local.y, local.z)];
PaintCell(gridLayout, location, brushTarget.transform, cell);
}
}
public override void BoxErase(GridLayout gridLayout, GameObject brushTarget, BoundsInt position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
if (brushTarget == null)
return;
foreach (Vector3Int location in position.allPositionsWithin)
{
EraseCell(gridLayout, location, brushTarget.transform);
}
}
public override void FloodFill(GridLayout gridLayout, GameObject brushTarget, Vector3Int position)
{
Debug.LogWarning("FloodFill not supported");
}
public override void Rotate(RotationDirection direction, Grid.CellLayout layout)
{
Vector3Int oldSize = m_Size;
BrushCell[] oldCells = m_Cells.Clone() as BrushCell[];
size = new Vector3Int(oldSize.y, oldSize.x, oldSize.z);
BoundsInt oldBounds = new BoundsInt(Vector3Int.zero, oldSize);
foreach (Vector3Int oldPos in oldBounds.allPositionsWithin)
{
int newX = direction == RotationDirection.Clockwise ? oldSize.y - oldPos.y - 1 : oldPos.y;
int newY = direction == RotationDirection.Clockwise ? oldPos.x : oldSize.x - oldPos.x - 1;
int toIndex = GetCellIndex(newX, newY, oldPos.z);
int fromIndex = GetCellIndex(oldPos.x, oldPos.y, oldPos.z, oldSize.x, oldSize.y, oldSize.z);
m_Cells[toIndex] = oldCells[fromIndex];
}
int newPivotX = direction == RotationDirection.Clockwise ? oldSize.y - pivot.y - 1 : pivot.y;
int newPivotY = direction == RotationDirection.Clockwise ? pivot.x : oldSize.x - pivot.x - 1;
pivot = new Vector3Int(newPivotX, newPivotY, pivot.z);
Matrix4x4 rotation = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, direction == RotationDirection.Clockwise ? 90f : -90f), Vector3.one);
Quaternion orientation = Quaternion.Euler(0f, 0f, direction == RotationDirection.Clockwise ? 90f : -90f);
foreach (BrushCell cell in m_Cells)
{
cell.offset = rotation * cell.offset;
cell.orientation = cell.orientation * orientation;
}
}
public override void Flip(FlipAxis flip, Grid.CellLayout layout)
{
if (flip == FlipAxis.X)
FlipX();
else
FlipY();
}
public override void Pick(GridLayout gridLayout, GameObject brushTarget, BoundsInt position, Vector3Int pickStart)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Reset();
UpdateSizeAndPivot(new Vector3Int(position.size.x, position.size.y, 1), new Vector3Int(pickStart.x, pickStart.y, 0));
foreach (Vector3Int pos in position.allPositionsWithin)
{
Vector3Int brushPosition = new Vector3Int(pos.x - position.x, pos.y - position.y, 0);
PickCell(pos, brushPosition, gridLayout, brushTarget.transform);
}
}
private void PickCell(Vector3Int position, Vector3Int brushPosition, GridLayout grid, Transform parent)
{
if (parent != null)
{
Vector3 cellCenter = grid.LocalToWorld(grid.CellToLocalInterpolated(position + new Vector3(.5f, .5f, .5f)));
GameObject go = GetObjectInCell(grid, parent, position);
if (go != null)
{
Object prefab = PrefabUtility.GetCorrespondingObjectFromSource(go);
if (prefab)
{
SetGameObject(brushPosition, (GameObject) prefab);
}
else
{
GameObject newInstance = Instantiate(go);
newInstance.hideFlags = HideFlags.HideAndDontSave;
SetGameObject(brushPosition, newInstance);
}
SetOffset(brushPosition, go.transform.position - cellCenter);
SetScale(brushPosition, go.transform.localScale);
SetOrientation(brushPosition, go.transform.localRotation);
}
}
}
public override void MoveStart(GridLayout gridLayout, GameObject brushTarget, BoundsInt position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Reset();
UpdateSizeAndPivot(new Vector3Int(position.size.x, position.size.y, 1), Vector3Int.zero);
if (brushTarget != null)
{
foreach (Vector3Int pos in position.allPositionsWithin)
{
Vector3Int brushPosition = new Vector3Int(pos.x - position.x, pos.y - position.y, 0);
PickCell(pos, brushPosition, gridLayout, brushTarget.transform);
ClearSceneCell(gridLayout, brushTarget.transform, brushPosition);
}
}
}
public override void MoveEnd(GridLayout gridLayout, GameObject brushTarget, BoundsInt position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Paint(gridLayout, brushTarget, position.min);
Reset();
}
public void Reset()
{
foreach (var cell in m_Cells)
{
if (cell.gameObject != null && !EditorUtility.IsPersistent(cell.gameObject))
{
DestroyImmediate(cell.gameObject);
}
}
UpdateSizeAndPivot(Vector3Int.one, Vector3Int.zero);
}
private void FlipX()
{
BrushCell[] oldCells = m_Cells.Clone() as BrushCell[];
BoundsInt oldBounds = new BoundsInt(Vector3Int.zero, m_Size);
foreach (Vector3Int oldPos in oldBounds.allPositionsWithin)
{
int newX = m_Size.x - oldPos.x - 1;
int toIndex = GetCellIndex(newX, oldPos.y, oldPos.z);
int fromIndex = GetCellIndex(oldPos);
m_Cells[toIndex] = oldCells[fromIndex];
}
int newPivotX = m_Size.x - pivot.x - 1;
pivot = new Vector3Int(newPivotX, pivot.y, pivot.z);
Matrix4x4 flip = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1f, 1f, 1f));
Quaternion orientation = Quaternion.Euler(0f, 0f, -180f);
foreach (BrushCell cell in m_Cells)
{
Vector3 oldOffset = cell.offset;
cell.offset = flip * oldOffset;
cell.orientation = cell.orientation*orientation;
}
}
private void FlipY()
{
BrushCell[] oldCells = m_Cells.Clone() as BrushCell[];
BoundsInt oldBounds = new BoundsInt(Vector3Int.zero, m_Size);
foreach (Vector3Int oldPos in oldBounds.allPositionsWithin)
{
int newY = m_Size.y - oldPos.y - 1;
int toIndex = GetCellIndex(oldPos.x, newY, oldPos.z);
int fromIndex = GetCellIndex(oldPos);
m_Cells[toIndex] = oldCells[fromIndex];
}
int newPivotY = m_Size.y - pivot.y - 1;
pivot = new Vector3Int(pivot.x, newPivotY, pivot.z);
Matrix4x4 flip = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, -1f, 1f));
Quaternion orientation = Quaternion.Euler(0f, 0f, -180f);
foreach (BrushCell cell in m_Cells)
{
Vector3 oldOffset = cell.offset;
cell.offset = flip * oldOffset;
cell.orientation = cell.orientation * orientation;
}
}
public void UpdateSizeAndPivot(Vector3Int size, Vector3Int pivot)
{
m_Size = size;
m_Pivot = pivot;
SizeUpdated();
}
public void SetGameObject(Vector3Int position, GameObject go)
{
if (ValidateCellPosition(position))
m_Cells[GetCellIndex(position)].gameObject = go;
}
public void SetOffset(Vector3Int position, Vector3 offset)
{
if (ValidateCellPosition(position))
m_Cells[GetCellIndex(position)].offset = offset;
}
public void SetOrientation(Vector3Int position, Quaternion orientation)
{
if (ValidateCellPosition(position))
m_Cells[GetCellIndex(position)].orientation = orientation;
}
public void SetScale(Vector3Int position, Vector3 scale)
{
if (ValidateCellPosition(position))
m_Cells[GetCellIndex(position)].scale = scale;
}
public int GetCellIndex(Vector3Int brushPosition)
{
return GetCellIndex(brushPosition.x, brushPosition.y, brushPosition.z);
}
public int GetCellIndex(int x, int y, int z)
{
return x + m_Size.x * y + m_Size.x * m_Size.y * z;
}
public int GetCellIndex(int x, int y, int z, int sizex, int sizey, int sizez)
{
return x + sizex * y + sizex * sizey * z;
}
public int GetCellIndexWrapAround(int x, int y, int z)
{
return (x % m_Size.x) + m_Size.x * (y % m_Size.y) + m_Size.x * m_Size.y * (z % m_Size.z);
}
private static GameObject GetObjectInCell(GridLayout grid, Transform parent, Vector3Int position)
{
int childCount = parent.childCount;
Vector3 min = grid.LocalToWorld(grid.CellToLocalInterpolated(position));
Vector3 max = grid.LocalToWorld(grid.CellToLocalInterpolated(position + Vector3Int.one));
// Infinite bounds on Z for 2D convenience
min = new Vector3(min.x, min.y, float.MinValue);
max = new Vector3(max.x, max.y, float.MaxValue);
Bounds bounds = new Bounds((max + min) * .5f, max - min);
for (int i = 0; i < childCount; i++)
{
Transform child = parent.GetChild(i);
if (bounds.Contains(child.position))
return child.gameObject;
}
return null;
}
private bool ValidateCellPosition(Vector3Int position)
{
var valid =
position.x >= 0 && position.x < size.x &&
position.y >= 0 && position.y < size.y &&
position.z >= 0 && position.z < size.z;
if (!valid)
throw new ArgumentException(string.Format("Position {0} is an invalid cell position. Valid range is between [{1}, {2}).", position, Vector3Int.zero, size));
return valid;
}
private void SizeUpdated()
{
m_Cells = new BrushCell[m_Size.x * m_Size.y * m_Size.z];
BoundsInt bounds = new BoundsInt(Vector3Int.zero, m_Size);
foreach (Vector3Int pos in bounds.allPositionsWithin)
{
m_Cells[GetCellIndex(pos)] = new BrushCell();
}
}
private static void SetSceneCell(GridLayout grid, Transform parent, Vector3Int position, GameObject go, Vector3 offset, Vector3 scale, Quaternion orientation)
{
if (parent == null || go == null)
return;
GameObject instance = null;
if (PrefabUtility.GetPrefabType(go) == PrefabType.Prefab)
{
instance = (GameObject) PrefabUtility.InstantiatePrefab(go);
}
else
{
instance = Instantiate(go);
instance.hideFlags = HideFlags.None;
instance.name = go.name;
}
Undo.RegisterCreatedObjectUndo(instance, "Paint GameObject");
instance.transform.SetParent(parent);
instance.transform.position = grid.LocalToWorld(grid.CellToLocalInterpolated(new Vector3Int(position.x, position.y, position.z) + new Vector3(.5f, .5f, .5f)));
instance.transform.localRotation = orientation;
instance.transform.localScale = scale;
instance.transform.Translate(offset);
}
private static void ClearSceneCell(GridLayout grid, Transform parent, Vector3Int position)
{
if (parent == null)
return;
GameObject erased = GetObjectInCell(grid, parent, new Vector3Int(position.x, position.y, position.z));
if (erased != null)
Undo.DestroyObjectImmediate(erased);
}
public override int GetHashCode()
{
int hash = 0;
unchecked
{
foreach (var cell in cells)
{
hash = hash * 33 + cell.GetHashCode();
}
}
return hash;
}
[Serializable]
public class BrushCell
{
public GameObject gameObject { get { return m_GameObject; } set { m_GameObject = value; } }
public Vector3 offset { get { return m_Offset; } set { m_Offset = value; } }
public Vector3 scale { get { return m_Scale; } set { m_Scale = value; } }
public Quaternion orientation { get { return m_Orientation; } set { m_Orientation = value; } }
[SerializeField]
private GameObject m_GameObject;
[SerializeField]
Vector3 m_Offset = Vector3.zero;
[SerializeField]
Vector3 m_Scale = Vector3.one;
[SerializeField]
Quaternion m_Orientation = Quaternion.identity;
public override int GetHashCode()
{
int hash = 0;
unchecked
{
hash = gameObject != null ? gameObject.GetInstanceID() : 0;
hash = hash * 33 + m_Offset.GetHashCode();
hash = hash * 33 + m_Scale.GetHashCode();
hash = hash * 33 + m_Orientation.GetHashCode();
}
return hash;
}
}
}
[CustomEditor(typeof(GameObjectBrush))]
public class GameObjectBrushEditor : GridBrushEditorBase
{
public GameObjectBrush brush { get { return target as GameObjectBrush; } }
public override void OnPaintSceneGUI(GridLayout gridLayout, GameObject brushTarget, BoundsInt position, GridBrushBase.Tool tool, bool executing)
{
BoundsInt gizmoRect = position;
if (tool == GridBrushBase.Tool.Paint || tool == GridBrushBase.Tool.Erase)
gizmoRect = new BoundsInt(position.min - brush.pivot, brush.size);
base.OnPaintSceneGUI(gridLayout, brushTarget, gizmoRect, tool, executing);
}
public override void OnPaintInspectorGUI()
{
GUILayout.Label("Pick, paint and erase GameObject(s) in the scene.");
GUILayout.Label("Limited to children of the currently selected GameObject.");
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 0abded712ad706044a53ef292972edbb
timeCreated: 1501700935
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ddf6fb480373a4b4babf2bd106dd48d8
folderAsset: yes
timeCreated: 1499149753
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6a7de8b7c9f16a54abb1f4e4b4dda454
folderAsset: yes
timeCreated: 1499149780
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a4ce1d57936070949bdd366b4d13335f
folderAsset: yes
timeCreated: 1499149785
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,210 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
using System.Linq;
namespace UnityEditor
{
[CustomGridBrush(true, false, false, "Line Brush")]
[CreateAssetMenu(fileName = "New Line Brush", menuName = "Brushes/Line Brush")]
public class LineBrush : GridBrush
{
public bool lineStartActive = false;
public bool fillGaps = false;
public Vector3Int lineStart = Vector3Int.zero;
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
if (lineStartActive)
{
Vector2Int startPos = new Vector2Int(lineStart.x, lineStart.y);
Vector2Int endPos = new Vector2Int(position.x, position.y);
if (startPos == endPos)
base.Paint(grid, brushTarget, position);
else
{
foreach (var point in GetPointsOnLine(startPos, endPos, fillGaps))
{
Vector3Int paintPos = new Vector3Int(point.x, point.y, position.z);
base.Paint(grid, brushTarget, paintPos);
}
}
lineStartActive = false;
}
else
{
lineStart = position;
lineStartActive = true;
}
}
/// <summary>
/// Added option to fill gaps for continuous lines.
/// </summary>
public static IEnumerable<Vector2Int> GetPointsOnLine(Vector2Int startPos, Vector2Int endPos, bool fillGaps)
{
var points = GetPointsOnLine(startPos, endPos);
if (fillGaps)
{
var rise = endPos.y - startPos.y;
var run = endPos.x - startPos.x;
if (rise != 0 || run != 0)
{
var extraStart = startPos;
var extraEnd = endPos;
if (Mathf.Abs(rise) >= Mathf.Abs(run))
{
// up
if (rise > 0)
{
extraStart.y += 1;
extraEnd.y += 1;
}
// down
else // rise < 0
{
extraStart.y -= 1;
extraEnd.y -= 1;
}
}
else // Mathf.Abs(rise) < Mathf.Abs(run)
{
// right
if (run > 0)
{
extraStart.x += 1;
extraEnd.x += 1;
}
// left
else // run < 0
{
extraStart.x -= 1;
extraEnd.x -= 1;
}
}
var extraPoints = GetPointsOnLine(extraStart, extraEnd);
extraPoints = extraPoints.Except(new[] { extraEnd });
points = points.Union(extraPoints);
}
}
return points;
}
// http://ericw.ca/notes/bresenhams-line-algorithm-in-csharp.html
public static IEnumerable<Vector2Int> GetPointsOnLine(Vector2Int p1, Vector2Int p2)
{
int x0 = p1.x;
int y0 = p1.y;
int x1 = p2.x;
int y1 = p2.y;
bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
if (steep)
{
int t;
t = x0; // swap x0 and y0
x0 = y0;
y0 = t;
t = x1; // swap x1 and y1
x1 = y1;
y1 = t;
}
if (x0 > x1)
{
int t;
t = x0; // swap x0 and x1
x0 = x1;
x1 = t;
t = y0; // swap y0 and y1
y0 = y1;
y1 = t;
}
int dx = x1 - x0;
int dy = Math.Abs(y1 - y0);
int error = dx / 2;
int ystep = (y0 < y1) ? 1 : -1;
int y = y0;
for (int x = x0; x <= x1; x++)
{
yield return new Vector2Int((steep ? y : x), (steep ? x : y));
error = error - dy;
if (error < 0)
{
y += ystep;
error += dx;
}
}
yield break;
}
}
[CustomEditor(typeof(LineBrush))]
public class LineBrushEditor : GridBrushEditor
{
private LineBrush lineBrush { get { return target as LineBrush; } }
private Tilemap lastTilemap;
public override void OnPaintSceneGUI(GridLayout grid, GameObject brushTarget, BoundsInt position, GridBrushBase.Tool tool, bool executing)
{
base.OnPaintSceneGUI(grid, brushTarget, position, tool, executing);
if (lineBrush.lineStartActive)
{
Tilemap tilemap = brushTarget.GetComponent<Tilemap>();
if (tilemap != null)
lastTilemap = tilemap;
// Draw preview tiles for tilemap
Vector2Int startPos = new Vector2Int(lineBrush.lineStart.x, lineBrush.lineStart.y);
Vector2Int endPos = new Vector2Int(position.x, position.y);
if (startPos == endPos)
PaintPreview(grid, brushTarget, position.min);
else
{
foreach (var point in LineBrush.GetPointsOnLine(startPos, endPos, lineBrush.fillGaps))
{
Vector3Int paintPos = new Vector3Int(point.x, point.y, position.z);
PaintPreview(grid, brushTarget, paintPos);
}
}
if (Event.current.type == EventType.Repaint)
{
var min = lineBrush.lineStart;
var max = lineBrush.lineStart + position.size;
// Draws a box on the picked starting position
GL.PushMatrix();
GL.MultMatrix(GUI.matrix);
GL.Begin(GL.LINES);
Handles.color = Color.blue;
Handles.DrawLine(new Vector3(min.x, min.y, min.z), new Vector3(max.x, min.y, min.z));
Handles.DrawLine(new Vector3(max.x, min.y, min.z), new Vector3(max.x, max.y, min.z));
Handles.DrawLine(new Vector3(max.x, max.y, min.z), new Vector3(min.x, max.y, min.z));
Handles.DrawLine(new Vector3(min.x, max.y, min.z), new Vector3(min.x, min.y, min.z));
GL.End();
GL.PopMatrix();
}
}
}
public override void ClearPreview()
{
base.ClearPreview();
if (lastTilemap != null)
{
lastTilemap.ClearAllEditorPreviewTiles();
lastTilemap = null;
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 6210598a979f8724a8dac4531c428889
timeCreated: 1499149789
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9b73c833515e70440a2222f774104211
folderAsset: yes
timeCreated: 1501789833
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 090e78558c17f064eae502998e2f22fb
folderAsset: yes
timeCreated: 1501789849
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 642e946f97259c640b3a047a57944ed9
folderAsset: yes
timeCreated: 1501789995
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace UnityEditor
{
[CreateAssetMenu(fileName = "Prefab brush", menuName = "Brushes/Prefab brush")]
[CustomGridBrush(false, true, false, "Prefab Brush")]
public class PrefabBrush : GridBrushBase
{
private const float k_PerlinOffset = 100000f;
public GameObject[] m_Prefabs;
public float m_PerlinScale = 0.5f;
public int m_Z;
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
int index = Mathf.Clamp(Mathf.FloorToInt(GetPerlinValue(position, m_PerlinScale, k_PerlinOffset)*m_Prefabs.Length), 0, m_Prefabs.Length - 1);
GameObject prefab = m_Prefabs[index];
GameObject instance = (GameObject) PrefabUtility.InstantiatePrefab(prefab);
if (instance != null)
{
Undo.MoveGameObjectToScene(instance, brushTarget.scene, "Paint Prefabs");
Undo.RegisterCreatedObjectUndo((Object)instance, "Paint Prefabs");
instance.transform.SetParent(brushTarget.transform);
instance.transform.position = grid.LocalToWorld(grid.CellToLocalInterpolated(new Vector3Int(position.x, position.y, m_Z) + new Vector3(.5f, .5f, .5f)));
}
}
public override void Erase(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Transform erased = GetObjectInCell(grid, brushTarget.transform, new Vector3Int(position.x, position.y, m_Z));
if (erased != null)
Undo.DestroyObjectImmediate(erased.gameObject);
}
private static Transform GetObjectInCell(GridLayout grid, Transform parent, Vector3Int position)
{
int childCount = parent.childCount;
Vector3 min = grid.LocalToWorld(grid.CellToLocalInterpolated(position));
Vector3 max = grid.LocalToWorld(grid.CellToLocalInterpolated(position + Vector3Int.one));
Bounds bounds = new Bounds((max + min)*.5f, max - min);
for (int i = 0; i < childCount; i++)
{
Transform child = parent.GetChild(i);
if (bounds.Contains(child.position))
return child;
}
return null;
}
private static float GetPerlinValue(Vector3Int position, float scale, float offset)
{
return Mathf.PerlinNoise((position.x + offset)*scale, (position.y + offset)*scale);
}
}
[CustomEditor(typeof(PrefabBrush))]
public class PrefabBrushEditor : GridBrushEditorBase
{
private PrefabBrush prefabBrush { get { return target as PrefabBrush; } }
private SerializedProperty m_Prefabs;
private SerializedObject m_SerializedObject;
protected void OnEnable()
{
m_SerializedObject = new SerializedObject(target);
m_Prefabs = m_SerializedObject.FindProperty("m_Prefabs");
}
public override void OnPaintInspectorGUI()
{
m_SerializedObject.UpdateIfRequiredOrScript();
prefabBrush.m_PerlinScale = EditorGUILayout.Slider("Perlin Scale", prefabBrush.m_PerlinScale, 0.001f, 0.999f);
prefabBrush.m_Z = EditorGUILayout.IntField("Position Z", prefabBrush.m_Z);
EditorGUILayout.PropertyField(m_Prefabs, true);
m_SerializedObject.ApplyModifiedPropertiesWithoutUndo();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 2d5751a2c961df945a34295ccf5e576d
timeCreated: 1501681786
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8dee42ba30f712246852f41830cedbef
folderAsset: yes
timeCreated: 1499223176
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d352e5b4c56a76e4d99fc48256bbc67e
folderAsset: yes
timeCreated: 1499223198
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 762d145b6139de6478fcc2998702d839
folderAsset: yes
timeCreated: 1499223228
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
namespace UnityEditor
{
[CustomGridBrush(false, true, false, "Random Brush")]
[CreateAssetMenu(fileName = "New Random Brush", menuName = "Brushes/Random Brush")]
public class RandomBrush : GridBrush
{
public TileBase[] randomTiles;
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
if (randomTiles != null && randomTiles.Length > 0)
{
if (brushTarget == null)
return;
var tilemap = brushTarget.GetComponent<Tilemap>();
if (tilemap == null)
return;
Vector3Int min = position - pivot;
BoundsInt bounds = new BoundsInt(min, size);
foreach (Vector3Int location in bounds.allPositionsWithin)
{
var randomTile = randomTiles[(int) (randomTiles.Length * UnityEngine.Random.value)];
tilemap.SetTile(location, randomTile);
}
}
else
{
base.Paint(grid, brushTarget, position);
}
}
}
[CustomEditor(typeof(RandomBrush))]
public class RandomBrushEditor : GridBrushEditor
{
private RandomBrush randomBrush { get { return target as RandomBrush; } }
private GameObject lastBrushTarget;
public override void PaintPreview(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
if (randomBrush.randomTiles != null && randomBrush.randomTiles.Length > 0)
{
base.PaintPreview(grid, null, position);
if (brushTarget == null)
return;
var tilemap = brushTarget.GetComponent<Tilemap>();
if (tilemap == null)
return;
Vector3Int min = position - randomBrush.pivot;
BoundsInt bounds = new BoundsInt(min, randomBrush.size);
foreach (Vector3Int location in bounds.allPositionsWithin)
{
var randomTile = randomBrush.randomTiles[(int) (randomBrush.randomTiles.Length * UnityEngine.Random.value)];
tilemap.SetEditorPreviewTile(location, randomTile);
}
lastBrushTarget = brushTarget;
}
else
{
base.PaintPreview(grid, brushTarget, position);
}
}
public override void ClearPreview()
{
if (lastBrushTarget != null)
{
var tilemap = lastBrushTarget.GetComponent<Tilemap>();
if (tilemap == null)
return;
tilemap.ClearAllEditorPreviewTiles();
lastBrushTarget = null;
}
else
{
base.ClearPreview();
}
}
public override void OnPaintInspectorGUI()
{
EditorGUI.BeginChangeCheck();
int count = EditorGUILayout.IntField("Number of Tiles", randomBrush.randomTiles != null ? randomBrush.randomTiles.Length : 0);
if (count < 0)
count = 0;
if (randomBrush.randomTiles == null || randomBrush.randomTiles.Length != count)
{
Array.Resize<TileBase>(ref randomBrush.randomTiles, count);
}
if (count == 0)
return;
EditorGUILayout.LabelField("Place random tiles.");
EditorGUILayout.Space();
for (int i = 0; i < count; i++)
{
randomBrush.randomTiles[i] = (TileBase) EditorGUILayout.ObjectField("Tile " + (i+1), randomBrush.randomTiles[i], typeof(TileBase), false, null);
}
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(randomBrush);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d80edd6caba93514eb01722041fe50b4
timeCreated: 1499223220
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 73ffdc5b54c50214e9899760b98f5754
folderAsset: yes
timeCreated: 1502798557
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3d5759c37f6ead941b87383dcb19bff3
folderAsset: yes
timeCreated: 1502798569
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7402f20de7e8fc34c9cfcbc965122710
folderAsset: yes
timeCreated: 1502800377
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,106 @@
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
namespace UnityEditor
{
[CustomGridBrush(false, false, false, "Tint Brush (Smooth)")]
public class TintBrushSmooth : GridBrushBase
{
private TintTextureGenerator generator
{
get
{
TintTextureGenerator generator = FindObjectOfType<TintTextureGenerator>();
if (generator == null)
{
// Note: Code assumes only one grid in scene
Grid grid = FindObjectOfType<Grid>();
if (grid != null)
{
generator = grid.gameObject.AddComponent<TintTextureGenerator>();
}
}
return generator;
}
}
public float m_Blend = 1f;
public Color m_Color = Color.white;
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
TintTextureGenerator generator = GetGenerator(grid);
if (generator != null)
{
var oldColor = generator.GetColor(grid as Grid, position);
var blendColor = oldColor * (1 - m_Blend) + m_Color * m_Blend;
generator.SetColor(grid as Grid, position, blendColor);
}
}
public override void Erase(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
TintTextureGenerator generator = GetGenerator(grid);
if (generator != null)
{
generator.SetColor(grid as Grid, position, Color.white);
}
}
public override void Pick(GridLayout grid, GameObject brushTarget, BoundsInt position, Vector3Int pivot)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
TintTextureGenerator generator = GetGenerator(grid);
if (generator != null)
{
m_Color = generator.GetColor(grid as Grid, position.min);
}
}
private TintTextureGenerator GetGenerator(GridLayout grid)
{
TintTextureGenerator generator = FindObjectOfType<TintTextureGenerator>();
if (generator == null)
{
if (grid != null)
{
generator = grid.gameObject.AddComponent<TintTextureGenerator>();
}
}
return generator;
}
}
[CustomEditor(typeof(TintBrushSmooth))]
public class TintBrushSmoothEditor : GridBrushEditorBase
{
public TintBrushSmooth brush { get { return target as TintBrushSmooth; } }
public override GameObject[] validTargets
{
get
{
return GameObject.FindObjectsOfType<Tilemap>().Select(x => x.gameObject).ToArray();
}
}
public override void OnPaintInspectorGUI()
{
brush.m_Color = EditorGUILayout.ColorField("Color", brush.m_Color);
brush.m_Blend = EditorGUILayout.Slider("Blend", brush.m_Blend, 0f, 1f);
GUILayout.Label("Note: Tilemap needs to use TintedTilemap.shader!");
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ed363ce3b4856fa408111529bc784318
timeCreated: 1502800385
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,102 @@
using System.ComponentModel;
using UnityEngine;
using UnityEngine.Tilemaps;
[ExecuteInEditMode]
public class TintTextureGenerator : MonoBehaviour
{
public int k_TintMapSize = 256;
public void Start()
{
Refresh(GetComponent<Grid>());
}
private Texture2D m_TintTexture;
private Texture2D tintTexture
{
get
{
if (m_TintTexture == null)
{
m_TintTexture = new Texture2D(k_TintMapSize, k_TintMapSize, TextureFormat.ARGB32, false);
m_TintTexture.hideFlags = HideFlags.HideAndDontSave;
m_TintTexture.wrapMode = TextureWrapMode.Clamp;
m_TintTexture.filterMode = FilterMode.Bilinear;
RefreshGlobalShaderValues();
}
return m_TintTexture;
}
}
public void Refresh(Grid grid)
{
if (grid == null)
return;
int w = tintTexture.width;
int h = tintTexture.height;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
Vector3Int world = TextureToWorld(new Vector3Int(x, y, 0));
tintTexture.SetPixel(x, y, GetGridInformation(grid).GetPositionProperty(world, "Tint", Color.white));
}
}
tintTexture.Apply();
}
public void Refresh(Grid grid, Vector3Int position)
{
if (grid == null)
return;
RefreshGlobalShaderValues();
Vector3Int texPosition = WorldToTexture(position);
tintTexture.SetPixel(texPosition.x, texPosition.y, GetGridInformation(grid).GetPositionProperty(position, "Tint", Color.white));
tintTexture.Apply();
}
public Color GetColor(Grid grid, Vector3Int position)
{
if (grid == null)
return Color.white;
return GetGridInformation(grid).GetPositionProperty(position, "Tint", Color.white);
}
public void SetColor(Grid grid, Vector3Int position, Color color)
{
if (grid == null)
return;
GetGridInformation(grid).SetPositionProperty(position, "Tint", color);
Refresh(grid, position);
}
Vector3Int WorldToTexture(Vector3Int world)
{
return new Vector3Int(world.x + tintTexture.width / 2, world.y + tintTexture.height / 2, 0);
}
Vector3Int TextureToWorld(Vector3Int texpos)
{
return new Vector3Int(texpos.x - tintTexture.width / 2, texpos.y - tintTexture.height / 2, 0);
}
GridInformation GetGridInformation(Grid grid)
{
GridInformation gridInformation = grid.GetComponent<GridInformation>();
if (gridInformation == null)
gridInformation = grid.gameObject.AddComponent<GridInformation>();
return gridInformation;
}
void RefreshGlobalShaderValues()
{
Shader.SetGlobalTexture("_TintMap", m_TintTexture);
Shader.SetGlobalFloat("_TintMapSize", k_TintMapSize);
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b41bf0cc11b1c8f419f96e8eb0adea40
timeCreated: 1502798706
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f9a74a0ba597dbd4ebbdc09df032a31c
folderAsset: yes
timeCreated: 1502798946
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
Shader "Custom/TintedTilemap"
{
Properties
{
[PerRendererData]_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "Queue"="Transparent" "Render"="Transparent" "IgnoreProjector"="True"}
LOD 200
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass{
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _TintMap;
float _TintMapSize;
struct v2f {
float4 vertex : SV_POSITION;
float4 uv : TEXCOORD0;
float3 worldPos : float3;
};
v2f vert(appdata v) {
v2f o;
o.worldPos = mul (unity_ObjectToWorld, v.vertex);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = float4(v.texcoord.xy, 0, 0);
return o;
}
fixed4 frag(v2f i) : SV_Target {
fixed4 col = tex2D (_MainTex, i.uv);
fixed4 tint = tex2D(_TintMap, (i.worldPos.xy / _TintMapSize) + .5);
return tint * col;
}
ENDCG
}
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9fcc3b710e7f7ae44bcf65125a08d5ef
timeCreated: 1502805334
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 91dd673b6b5d18845b756aedc65463ad
folderAsset: yes
timeCreated: 1502200654
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0da715375d333a8418105408e081f130
folderAsset: yes
timeCreated: 1502200675
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 27c281d5970a0fd49bfebd8119dc790a
folderAsset: yes
timeCreated: 1502200680
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
namespace UnityEditor
{
[CustomGridBrush(false, false, false, "Tint Brush")]
public class TintBrush : GridBrushBase
{
public Color m_Color = Color.white;
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Tilemap tilemap = brushTarget.GetComponent<Tilemap>();
if (tilemap != null)
{
SetColor(tilemap, position, m_Color);
}
}
public override void Erase(GridLayout grid, GameObject brushTarget, Vector3Int position)
{
// Do not allow editing palettes
if (brushTarget.layer == 31)
return;
Tilemap tilemap = brushTarget.GetComponent<Tilemap>();
if (tilemap != null)
{
SetColor(tilemap, position, Color.white);
}
}
private static void SetColor(Tilemap tilemap, Vector3Int position, Color color)
{
TileBase tile = tilemap.GetTile(position);
if (tile != null)
{
if ((tilemap.GetTileFlags(position) & TileFlags.LockColor) != 0)
{
if (tile is Tile)
{
Debug.LogWarning("Tint brush cancelled, because Tile (" + tile.name + ") has TileFlags.LockColor set. Unlock it from the Tile asset debug inspector.");
}
else
{
Debug.LogWarning("Tint brush cancelled. because Tile (" + tile.name + ") has TileFlags.LockColor set. Unset it in GetTileData().");
}
}
tilemap.SetColor(position, color);
}
}
}
[CustomEditor(typeof(TintBrush))]
public class TintBrushEditor : GridBrushEditorBase
{
public override GameObject[] validTargets
{
get
{
return GameObject.FindObjectsOfType<Tilemap>().Select(x => x.gameObject).ToArray();
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 5461c6f43c33cae4e8367042630017f7
timeCreated: 1502200727
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c93545baa8c686a46a0ec319b747d53f
folderAsset: yes
timeCreated: 1501816804
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: fa5c106bc9eac9844897d7fea5f8328c
folderAsset: yes
timeCreated: 1499412046
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,356 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace UnityEngine.Tilemaps
{
[Serializable]
internal enum GridInformationType
{
Integer,
String,
Float,
Double,
UnityObject,
Color
}
[Serializable]
[AddComponentMenu("Tilemap/Grid Information")]
public class GridInformation : MonoBehaviour, ISerializationCallbackReceiver
{
internal struct GridInformationValue
{
public GridInformationType type;
public object data;
}
[Serializable]
internal struct GridInformationKey
{
public Vector3Int position;
public String name;
}
private Dictionary<GridInformationKey, GridInformationValue> m_PositionProperties = new Dictionary<GridInformationKey, GridInformationValue>();
internal Dictionary<GridInformationKey, GridInformationValue> PositionProperties
{
get { return m_PositionProperties; }
}
[SerializeField]
[HideInInspector]
private List<GridInformationKey> m_PositionIntKeys = new List<GridInformationKey>();
[SerializeField]
[HideInInspector]
private List<int> m_PositionIntValues = new List<int>();
[SerializeField]
[HideInInspector]
private List<GridInformationKey> m_PositionStringKeys = new List<GridInformationKey>();
[SerializeField]
[HideInInspector]
private List<String> m_PositionStringValues = new List<String>();
[SerializeField]
[HideInInspector]
private List<GridInformationKey> m_PositionFloatKeys = new List<GridInformationKey>();
[SerializeField]
[HideInInspector]
private List<float> m_PositionFloatValues = new List<float>();
[SerializeField]
[HideInInspector]
private List<GridInformationKey> m_PositionDoubleKeys = new List<GridInformationKey>();
[SerializeField]
[HideInInspector]
private List<Double> m_PositionDoubleValues = new List<Double>();
[SerializeField]
[HideInInspector]
private List<GridInformationKey> m_PositionObjectKeys = new List<GridInformationKey>();
[SerializeField]
[HideInInspector]
private List<Object> m_PositionObjectValues = new List<Object>();
[SerializeField]
[HideInInspector]
private List<GridInformationKey> m_PositionColorKeys = new List<GridInformationKey>();
[SerializeField]
[HideInInspector]
private List<Color> m_PositionColorValues = new List<Color>();
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
Grid grid = GetComponentInParent<Grid>();
if (grid == null)
return;
m_PositionIntKeys.Clear();
m_PositionIntValues.Clear();
m_PositionStringKeys.Clear();
m_PositionStringValues.Clear();
m_PositionFloatKeys.Clear();
m_PositionFloatValues.Clear();
m_PositionDoubleKeys.Clear();
m_PositionDoubleValues.Clear();
m_PositionObjectKeys.Clear();
m_PositionObjectValues.Clear();
m_PositionColorKeys.Clear();
m_PositionColorValues.Clear();
foreach (var kvp in m_PositionProperties)
{
switch (kvp.Value.type)
{
case GridInformationType.Integer:
m_PositionIntKeys.Add(kvp.Key);
m_PositionIntValues.Add((int)kvp.Value.data);
break;
case GridInformationType.String:
m_PositionStringKeys.Add(kvp.Key);
m_PositionStringValues.Add(kvp.Value.data as String);
break;
case GridInformationType.Float:
m_PositionFloatKeys.Add(kvp.Key);
m_PositionFloatValues.Add((float)kvp.Value.data);
break;
case GridInformationType.Double:
m_PositionDoubleKeys.Add(kvp.Key);
m_PositionDoubleValues.Add((double)kvp.Value.data);
break;
case GridInformationType.Color:
m_PositionColorKeys.Add(kvp.Key);
m_PositionColorValues.Add((Color)kvp.Value.data);
break;
default:
m_PositionObjectKeys.Add(kvp.Key);
m_PositionObjectValues.Add(kvp.Value.data as Object);
break;
}
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
m_PositionProperties.Clear();
for (int i = 0; i != Math.Min(m_PositionIntKeys.Count, m_PositionIntValues.Count); i++)
{
GridInformationValue positionValue;
positionValue.type = GridInformationType.Integer;
positionValue.data = m_PositionIntValues[i];
m_PositionProperties.Add(m_PositionIntKeys[i], positionValue);
}
for (int i = 0; i != Math.Min(m_PositionStringKeys.Count, m_PositionStringValues.Count); i++)
{
GridInformationValue positionValue;
positionValue.type = GridInformationType.String;
positionValue.data = m_PositionStringValues[i];
m_PositionProperties.Add(m_PositionStringKeys[i], positionValue);
}
for (int i = 0; i != Math.Min(m_PositionFloatKeys.Count, m_PositionFloatValues.Count); i++)
{
GridInformationValue positionValue;
positionValue.type = GridInformationType.Float;
positionValue.data = m_PositionFloatValues[i];
m_PositionProperties.Add(m_PositionFloatKeys[i], positionValue);
}
for (int i = 0; i != Math.Min(m_PositionDoubleKeys.Count, m_PositionDoubleValues.Count); i++)
{
GridInformationValue positionValue;
positionValue.type = GridInformationType.Double;
positionValue.data = m_PositionDoubleValues[i];
m_PositionProperties.Add(m_PositionDoubleKeys[i], positionValue);
}
for (int i = 0; i != Math.Min(m_PositionObjectKeys.Count, m_PositionObjectValues.Count); i++)
{
GridInformationValue positionValue;
positionValue.type = GridInformationType.UnityObject;
positionValue.data = m_PositionObjectValues[i];
m_PositionProperties.Add(m_PositionObjectKeys[i], positionValue);
}
for (int i = 0; i != Math.Min(m_PositionColorKeys.Count, m_PositionColorValues.Count); i++)
{
GridInformationValue positionValue;
positionValue.type = GridInformationType.Color;
positionValue.data = m_PositionColorValues[i];
m_PositionProperties.Add(m_PositionColorKeys[i], positionValue);
}
}
public bool SetPositionProperty<T>(Vector3Int position, String name, T positionProperty)
{
throw new NotImplementedException("Storing this type is not accepted in GridInformation");
}
public bool SetPositionProperty(Vector3Int position, String name, int positionProperty)
{
return SetPositionProperty(position, name, GridInformationType.Integer, positionProperty);
}
public bool SetPositionProperty(Vector3Int position, String name, string positionProperty)
{
return SetPositionProperty(position, name, GridInformationType.String, positionProperty);
}
public bool SetPositionProperty(Vector3Int position, String name, float positionProperty)
{
return SetPositionProperty(position, name, GridInformationType.Float, positionProperty);
}
public bool SetPositionProperty(Vector3Int position, String name, double positionProperty)
{
return SetPositionProperty(position, name, GridInformationType.Double, positionProperty);
}
public bool SetPositionProperty(Vector3Int position, String name, UnityEngine.Object positionProperty)
{
return SetPositionProperty(position, name, GridInformationType.UnityObject, positionProperty);
}
public bool SetPositionProperty(Vector3Int position, String name, Color positionProperty)
{
return SetPositionProperty(position, name, GridInformationType.Color, positionProperty);
}
private bool SetPositionProperty(Vector3Int position, String name, GridInformationType dataType, System.Object positionProperty)
{
Grid grid = GetComponentInParent<Grid>();
if (grid != null && positionProperty != null)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
positionValue.type = dataType;
positionValue.data = positionProperty;
m_PositionProperties[positionKey] = positionValue;
return true;
}
return false;
}
public T GetPositionProperty<T>(Vector3Int position, String name, T defaultValue) where T : UnityEngine.Object
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
{
if (positionValue.type != GridInformationType.UnityObject)
throw new InvalidCastException("Value stored in GridInformation is not of the right type");
return positionValue.data as T;
}
return defaultValue;
}
public int GetPositionProperty(Vector3Int position, String name, int defaultValue)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
{
if (positionValue.type != GridInformationType.Integer)
throw new InvalidCastException("Value stored in GridInformation is not of the right type");
return (int)positionValue.data;
}
return defaultValue;
}
public string GetPositionProperty(Vector3Int position, String name, string defaultValue)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
{
if (positionValue.type != GridInformationType.String)
throw new InvalidCastException("Value stored in GridInformation is not of the right type");
return (string)positionValue.data;
}
return defaultValue;
}
public float GetPositionProperty(Vector3Int position, String name, float defaultValue)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
{
if (positionValue.type != GridInformationType.Float)
throw new InvalidCastException("Value stored in GridInformation is not of the right type");
return (float)positionValue.data;
}
return defaultValue;
}
public double GetPositionProperty(Vector3Int position, String name, double defaultValue)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
{
if (positionValue.type != GridInformationType.Double)
throw new InvalidCastException("Value stored in GridInformation is not of the right type");
return (double)positionValue.data;
}
return defaultValue;
}
public Color GetPositionProperty(Vector3Int position, String name, Color defaultValue)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
GridInformationValue positionValue;
if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
{
if (positionValue.type != GridInformationType.Color)
throw new InvalidCastException("Value stored in GridInformation is not of the right type");
return (Color)positionValue.data;
}
return defaultValue;
}
public bool ErasePositionProperty(Vector3Int position, String name)
{
GridInformationKey positionKey;
positionKey.position = position;
positionKey.name = name;
return m_PositionProperties.Remove(positionKey);
}
public virtual void Reset()
{
m_PositionProperties.Clear();
}
public Vector3Int[] GetAllPositions(string propertyName)
{
return m_PositionProperties.Keys.ToList().FindAll(x => x.name == propertyName).Select(x => x.position).ToArray();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: e7bb9acb2cffc5f45abddc238a0ad9b0
timeCreated: 1501815409
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a4b96e08a92a0de42b0c2fd3c56516b4
folderAsset: yes
timeCreated: 1499149591
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 33e8a22612607064dbfaa9d21d1836e8
folderAsset: yes
timeCreated: 1499149327
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d8f0a7d912b6f424aa0e09f8597dd2df
folderAsset: yes
timeCreated: 1499149343
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityEngine.Tilemaps
{
[Serializable]
[CreateAssetMenu(fileName = "New Animated Tile", menuName = "Tiles/Animated Tile")]
public class AnimatedTile : TileBase
{
public Sprite[] m_AnimatedSprites;
public float m_MinSpeed = 1f;
public float m_MaxSpeed = 1f;
public float m_AnimationStartTime;
public Tile.ColliderType m_TileColliderType;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
tileData.transform = Matrix4x4.identity;
tileData.color = Color.white;
if (m_AnimatedSprites != null && m_AnimatedSprites.Length > 0)
{
tileData.sprite = m_AnimatedSprites[m_AnimatedSprites.Length - 1];
tileData.colliderType = m_TileColliderType;
}
}
public override bool GetTileAnimationData(Vector3Int location, ITilemap tileMap, ref TileAnimationData tileAnimationData)
{
if (m_AnimatedSprites.Length > 0)
{
tileAnimationData.animatedSprites = m_AnimatedSprites;
tileAnimationData.animationSpeed = Random.Range(m_MinSpeed, m_MaxSpeed);
tileAnimationData.animationStartTime = m_AnimationStartTime;
return true;
}
return false;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(AnimatedTile))]
public class AnimatedTileEditor : Editor
{
private AnimatedTile tile { get { return (target as AnimatedTile); } }
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
int count = EditorGUILayout.DelayedIntField("Number of Animated Sprites", tile.m_AnimatedSprites != null ? tile.m_AnimatedSprites.Length : 0);
if (count < 0)
count = 0;
if (tile.m_AnimatedSprites == null || tile.m_AnimatedSprites.Length != count)
{
Array.Resize<Sprite>(ref tile.m_AnimatedSprites, count);
}
if (count == 0)
return;
EditorGUILayout.LabelField("Place sprites shown based on the order of animation.");
EditorGUILayout.Space();
for (int i = 0; i < count; i++)
{
tile.m_AnimatedSprites[i] = (Sprite) EditorGUILayout.ObjectField("Sprite " + (i+1), tile.m_AnimatedSprites[i], typeof(Sprite), false, null);
}
float minSpeed = EditorGUILayout.FloatField("Minimum Speed", tile.m_MinSpeed);
float maxSpeed = EditorGUILayout.FloatField("Maximum Speed", tile.m_MaxSpeed);
if (minSpeed < 0.0f)
minSpeed = 0.0f;
if (maxSpeed < 0.0f)
maxSpeed = 0.0f;
if (maxSpeed < minSpeed)
maxSpeed = minSpeed;
tile.m_MinSpeed = minSpeed;
tile.m_MaxSpeed = maxSpeed;
tile.m_AnimationStartTime = EditorGUILayout.FloatField("Start Time", tile.m_AnimationStartTime);
tile.m_TileColliderType=(Tile.ColliderType) EditorGUILayout.EnumPopup("Collider Type", tile.m_TileColliderType);
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(tile);
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 13b75c95f34a00d4e8c04f76b73312e6
timeCreated: 1464531813
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: af0bc89550613a14fa0feadd363358e6
folderAsset: yes
timeCreated: 1499149527
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 64fa95bf1baeb5f4497bd5048a284208
folderAsset: yes
timeCreated: 1499146919
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityEngine.Tilemaps
{
[Serializable]
[CreateAssetMenu(fileName = "New Pipeline Tile", menuName = "Tiles/Pipeline Tile")]
public class PipelineTile : TileBase
{
[SerializeField]
public Sprite[] m_Sprites;
public override void RefreshTile(Vector3Int location, ITilemap tileMap)
{
for (int yd = -1; yd <= 1; yd++)
for (int xd = -1; xd <= 1; xd++)
{
Vector3Int position = new Vector3Int(location.x + xd, location.y + yd, location.z);
if (TileValue(tileMap, position))
tileMap.RefreshTile(position);
}
}
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
UpdateTile(location, tileMap, ref tileData);
}
private void UpdateTile(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
tileData.transform = Matrix4x4.identity;
tileData.color = Color.white;
int mask = TileValue(tileMap, location + new Vector3Int(0, 1, 0)) ? 1 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, 0, 0)) ? 2 : 0;
mask += TileValue(tileMap, location + new Vector3Int(0, -1, 0)) ? 4 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, 0, 0)) ? 8 : 0;
int index = GetIndex((byte)mask);
if (index >= 0 && index < m_Sprites.Length && TileValue(tileMap, location))
{
tileData.sprite = m_Sprites[index];
tileData.transform = GetTransform((byte)mask);
tileData.flags = TileFlags.LockTransform | TileFlags.LockColor;
tileData.colliderType = Tile.ColliderType.Sprite;
}
}
private bool TileValue(ITilemap tileMap, Vector3Int position)
{
TileBase tile = tileMap.GetTile(position);
return (tile != null && tile == this);
}
private int GetIndex(byte mask)
{
switch (mask)
{
case 0: return 0;
case 3:
case 6:
case 9:
case 12: return 1;
case 1:
case 2:
case 4:
case 5:
case 10:
case 8: return 2;
case 7:
case 11:
case 13:
case 14: return 3;
case 15: return 4;
}
return -1;
}
private Matrix4x4 GetTransform(byte mask)
{
switch (mask)
{
case 9:
case 10:
case 7:
case 2:
case 8:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -90f), Vector3.one);
case 3:
case 14:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -180f), Vector3.one);
case 6:
case 13:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -270f), Vector3.one);
}
return Matrix4x4.identity;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(PipelineTile))]
public class PipelineTileEditor : Editor
{
private PipelineTile tile { get { return (target as PipelineTile); } }
public void OnEnable()
{
if (tile.m_Sprites == null || tile.m_Sprites.Length != 5)
tile.m_Sprites = new Sprite[5];
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Place sprites shown based on the number of tiles bordering it.");
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
tile.m_Sprites[0] = (Sprite) EditorGUILayout.ObjectField("None", tile.m_Sprites[0], typeof(Sprite), false, null);
tile.m_Sprites[2] = (Sprite) EditorGUILayout.ObjectField("One", tile.m_Sprites[2], typeof(Sprite), false, null);
tile.m_Sprites[1] = (Sprite) EditorGUILayout.ObjectField("Two", tile.m_Sprites[1], typeof(Sprite), false, null);
tile.m_Sprites[3] = (Sprite) EditorGUILayout.ObjectField("Three", tile.m_Sprites[3], typeof(Sprite), false, null);
tile.m_Sprites[4] = (Sprite) EditorGUILayout.ObjectField("Four", tile.m_Sprites[4], typeof(Sprite), false, null);
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(tile);
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 25192638efa881c469b1ac4d8cfd3f1b
timeCreated: 1464534747
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 47f5287a949e1094191c733949de285a
folderAsset: yes
timeCreated: 1499150037
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0c3034e66d810604680654a1e667fde0
folderAsset: yes
timeCreated: 1499150048
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityEngine.Tilemaps
{
[Serializable]
[CreateAssetMenu(fileName = "New Random Tile", menuName = "Tiles/Random Tile")]
public class RandomTile : Tile
{
[SerializeField]
public Sprite[] m_Sprites;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
base.GetTileData(location, tileMap, ref tileData);
if ((m_Sprites != null) && (m_Sprites.Length > 0))
{
long hash = location.x;
hash = (hash + 0xabcd1234) + (hash << 15);
hash = (hash + 0x0987efab) ^ (hash >> 11);
hash ^= location.y;
hash = (hash + 0x46ac12fd) + (hash << 7);
hash = (hash + 0xbe9730af) ^ (hash << 11);
Random.InitState((int)hash);
tileData.sprite = m_Sprites[(int) (m_Sprites.Length * Random.value)];
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(RandomTile))]
public class RandomTileEditor : Editor
{
private RandomTile tile { get { return (target as RandomTile); } }
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
int count = EditorGUILayout.DelayedIntField("Number of Sprites", tile.m_Sprites != null ? tile.m_Sprites.Length : 0);
if (count < 0)
count = 0;
if (tile.m_Sprites == null || tile.m_Sprites.Length != count)
{
Array.Resize<Sprite>(ref tile.m_Sprites, count);
}
if (count == 0)
return;
EditorGUILayout.LabelField("Place random sprites.");
EditorGUILayout.Space();
for (int i = 0; i < count; i++)
{
tile.m_Sprites[i] = (Sprite) EditorGUILayout.ObjectField("Sprite " + (i+1), tile.m_Sprites[i], typeof(Sprite), false, null);
}
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(tile);
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 535f8e525ff367c4ba67961e201a05ed
timeCreated: 1445235751
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fbcacf945e7001e4396ca2ca8573ae6c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1e5614e4b96700843ba104987c4f190e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1263d004036ee7f42aeed98348b5e8cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,350 @@
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEditor;
using UnityEditorInternal;
using System;
using System.Collections.Generic;
namespace UnityEditor
{
[CustomEditor(typeof(RuleOverrideTile))]
internal class RuleOverrideTileEditor : Editor
{
public RuleOverrideTile overrideTile { get { return (target as RuleOverrideTile); } }
private List<KeyValuePair<Sprite, Sprite>> m_Sprites;
private List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>> m_Rules;
ReorderableList m_SpriteList;
ReorderableList m_RuleList;
private float k_DefaultElementHeight { get { return RuleTileEditor.k_DefaultElementHeight; } }
private float k_PaddingBetweenRules { get { return RuleTileEditor.k_PaddingBetweenRules; } }
private float k_SingleLineHeight { get { return RuleTileEditor.k_SingleLineHeight; } }
private float k_LabelWidth { get { return RuleTileEditor.k_LabelWidth; } }
void OnEnable()
{
if (m_Sprites == null)
m_Sprites = new List<KeyValuePair<Sprite, Sprite>>();
if (m_Rules == null)
m_Rules = new List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>>();
if (m_SpriteList == null)
{
overrideTile.GetOverrides(m_Sprites);
m_SpriteList = new ReorderableList(m_Sprites, typeof(KeyValuePair<Sprite, Sprite>), false, true, false, false);
m_SpriteList.drawHeaderCallback = DrawSpriteHeader;
m_SpriteList.drawElementCallback = DrawSpriteElement;
m_SpriteList.elementHeight = k_DefaultElementHeight + k_PaddingBetweenRules;
}
if (m_RuleList == null)
{
overrideTile.GetOverrides(m_Rules);
m_RuleList = new ReorderableList(m_Rules, typeof(KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>), false, true, false, false);
m_RuleList.drawHeaderCallback = DrawRuleHeader;
m_RuleList.drawElementCallback = DrawRuleElement;
m_RuleList.elementHeightCallback = GetRuleElementHeight;
}
}
public override void OnInspectorGUI()
{
serializedObject.UpdateIfRequiredOrScript();
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Tile"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Advanced"));
serializedObject.ApplyModifiedProperties();
if (!overrideTile.m_Advanced)
{
using (new EditorGUI.DisabledScope(overrideTile.m_Tile == null))
{
EditorGUI.BeginChangeCheck();
overrideTile.GetOverrides(m_Sprites);
m_SpriteList.list = m_Sprites;
m_SpriteList.DoLayoutList();
if (EditorGUI.EndChangeCheck())
{
for (int i = 0; i < targets.Length; i++)
{
RuleOverrideTile tile = targets[i] as RuleOverrideTile;
tile.ApplyOverrides(m_Sprites);
}
}
}
}
else
{
using (new EditorGUI.DisabledScope(overrideTile.m_Tile == null))
{
overrideTile.GetOverrides(m_Rules);
m_RuleList.list = m_Rules;
m_RuleList.DoLayoutList();
}
}
}
private void SaveTile()
{
EditorUtility.SetDirty(target);
SceneView.RepaintAll();
}
private void DrawSpriteElement(Rect rect, int index, bool selected, bool focused)
{
Sprite originalSprite = m_Sprites[index].Key;
Sprite overrideSprite = m_Sprites[index].Value;
rect.y += 2;
rect.height -= k_PaddingBetweenRules;
rect.xMax = rect.xMax / 2.0f;
using (new EditorGUI.DisabledScope(true))
EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.height, rect.height), originalSprite, typeof(Sprite), false);
rect.xMin = rect.xMax;
rect.xMax *= 2.0f;
EditorGUI.BeginChangeCheck();
overrideSprite = EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.height, rect.height), overrideSprite, typeof(Sprite), false) as Sprite;
if (EditorGUI.EndChangeCheck())
{
m_Sprites[index] = new KeyValuePair<Sprite, Sprite>(originalSprite, overrideSprite);
SaveTile();
}
}
private void DrawSpriteHeader(Rect rect)
{
float xMax = rect.xMax;
rect.xMax = rect.xMax / 2.0f;
GUI.Label(rect, "Original", EditorStyles.label);
rect.xMin = rect.xMax;
rect.xMax = xMax;
GUI.Label(rect, "Override", EditorStyles.label);
}
private void DrawRuleElement(Rect rect, int index, bool selected, bool focused)
{
RuleTile.TilingRule originalRule = m_Rules[index].Key;
RuleTile.TilingRule overrideRule = m_Rules[index].Value;
float matrixWidth = k_DefaultElementHeight;
float xMax = rect.xMax;
rect.xMax = rect.xMax / 2.0f + matrixWidth - 10f;
if (index != overrideTile.m_Tile.m_TilingRules.Count)
DrawOriginalRuleElement(rect, originalRule);
else
DrawOriginalRuleElement(rect, originalRule, true);
rect.xMin = rect.xMax;
rect.xMax = xMax;
EditorGUI.BeginChangeCheck();
if (index != overrideTile.m_Tile.m_TilingRules.Count)
DrawOverrideElement(rect, originalRule);
else
DrawOverrideDefaultElement(rect, overrideRule);
if (EditorGUI.EndChangeCheck())
SaveTile();
}
public void DrawOriginalRuleElement(Rect rect, RuleTile.TilingRule originalRule, bool isDefault = false)
{
using (new EditorGUI.DisabledScope(true))
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
Rect matrixRect = new Rect(rect.xMax - matrixWidth * 2f - 10f, yPos, matrixWidth, k_DefaultElementHeight);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
if (!isDefault)
RuleTileEditor.RuleInspectorOnGUI(inspectorRect, originalRule);
else
RuleOriginalDefaultInspectorOnGUI(inspectorRect, originalRule);
RuleTileEditor.RuleMatrixOnGUI(overrideTile.m_Tile, matrixRect, originalRule);
RuleTileEditor.SpriteOnGUI(spriteRect, originalRule);
}
}
private void DrawOverrideElement(Rect rect, RuleTile.TilingRule originalRule)
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth - 10f, height);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
RuleOverrideInspectorOnGUI(inspectorRect, originalRule);
RuleTile.TilingRule overrideRule = overrideTile[originalRule];
if (overrideRule != null)
RuleTileEditor.SpriteOnGUI(spriteRect, overrideRule);
}
private void RuleOriginalDefaultInspectorOnGUI(Rect rect, RuleTile.TilingRule originalRule)
{
float y = rect.yMin;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Rule");
EditorGUI.LabelField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), "Default");
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), originalRule.m_ColliderType);
y += k_SingleLineHeight;
}
private void RuleOverrideInspectorOnGUI(Rect rect, RuleTile.TilingRule originalRule)
{
RuleTile.TilingRule overrideRule = overrideTile[originalRule];
float y = rect.yMin;
EditorGUI.BeginChangeCheck();
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Enabled");
bool enabled = EditorGUI.Toggle(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule != null);
y += k_SingleLineHeight;
if (EditorGUI.EndChangeCheck())
{
if (enabled)
overrideTile[originalRule] = originalRule;
else
overrideTile[originalRule] = null;
overrideRule = overrideTile[originalRule];
}
if (overrideRule == null)
return;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
overrideRule.m_ColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_ColliderType);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Output");
overrideRule.m_Output = (RuleTile.TilingRule.OutputSprite)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_Output);
y += k_SingleLineHeight;
if (overrideRule.m_Output == RuleTile.TilingRule.OutputSprite.Animation)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Speed");
overrideRule.m_AnimationSpeed = EditorGUI.FloatField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_AnimationSpeed);
y += k_SingleLineHeight;
}
if (overrideRule.m_Output == RuleTile.TilingRule.OutputSprite.Random)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Noise");
overrideRule.m_PerlinScale = EditorGUI.Slider(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_PerlinScale, 0.001f, 0.999f);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Shuffle");
overrideRule.m_RandomTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_RandomTransform);
y += k_SingleLineHeight;
}
if (overrideRule.m_Output != RuleTile.TilingRule.OutputSprite.Single)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Size");
EditorGUI.BeginChangeCheck();
int newLength = EditorGUI.DelayedIntField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_Sprites.Length);
if (EditorGUI.EndChangeCheck())
Array.Resize(ref overrideRule.m_Sprites, Math.Max(newLength, 1));
y += k_SingleLineHeight;
for (int i = 0; i < overrideRule.m_Sprites.Length; i++)
{
overrideRule.m_Sprites[i] = EditorGUI.ObjectField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_Sprites[i], typeof(Sprite), false) as Sprite;
y += k_SingleLineHeight;
}
}
}
private void DrawOverrideDefaultElement(Rect rect, RuleTile.TilingRule originalRule)
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth - 10f, height);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
RuleOverrideDefaultInspectorOnGUI(inspectorRect, originalRule);
if (overrideTile.m_OverrideDefault.m_Enabled)
RuleTileEditor.SpriteOnGUI(spriteRect, overrideTile.m_OverrideDefault.m_TilingRule);
}
private void RuleOverrideDefaultInspectorOnGUI(Rect rect, RuleTile.TilingRule overrideRule)
{
float y = rect.yMin;
EditorGUI.BeginChangeCheck();
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Enabled");
bool enabled = EditorGUI.Toggle(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideTile.m_OverrideDefault.m_Enabled);
y += k_SingleLineHeight;
if (EditorGUI.EndChangeCheck())
{
overrideTile.m_OverrideDefault.m_Enabled = enabled;
overrideTile.m_OverrideDefault.m_TilingRule = overrideTile.m_OriginalDefault;
}
if (!enabled)
return;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
overrideRule.m_ColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_ColliderType);
y += k_SingleLineHeight;
}
private void DrawRuleHeader(Rect rect)
{
overrideTile.Override();
float matrixWidth = k_DefaultElementHeight;
float xMax = rect.xMax;
rect.xMax = rect.xMax / 2.0f + matrixWidth - 10f;
GUI.Label(rect, "Original", EditorStyles.label);
rect.xMin = rect.xMax;
rect.xMax = xMax;
GUI.Label(rect, "Override", EditorStyles.label);
}
private float GetRuleElementHeight(int index)
{
if (index != overrideTile.m_Tile.m_TilingRules.Count)
{
var overrideRule = overrideTile[overrideTile.m_Tile.m_TilingRules[index]];
float overrideHeight = GetRuleElementHeight(overrideRule);
float originalHeight = GetRuleElementHeight(overrideTile.m_Tile.m_TilingRules[index]);
return Mathf.Max(overrideHeight, originalHeight);
}
else
{
var overrideRule = overrideTile.m_OverrideDefault.m_Enabled ? overrideTile.m_OverrideDefault.m_TilingRule : null;
float overrideHeight = GetRuleElementHeight(overrideRule);
float originalHeight = GetRuleElementHeight(new RuleTile.TilingRule());
return Mathf.Max(overrideHeight, originalHeight);
}
}
private float GetRuleElementHeight(RuleTile.TilingRule rule)
{
float height = k_DefaultElementHeight + k_PaddingBetweenRules;
if (rule != null)
{
switch (rule.m_Output)
{
case RuleTile.TilingRule.OutputSprite.Random:
height = k_DefaultElementHeight + k_SingleLineHeight * (rule.m_Sprites.Length + 3) + k_PaddingBetweenRules;
break;
case RuleTile.TilingRule.OutputSprite.Animation:
height = k_DefaultElementHeight + k_SingleLineHeight * (rule.m_Sprites.Length + 2) + k_PaddingBetweenRules;
break;
}
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dd977390416471341b10fd1278290da0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,259 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Tilemaps;
namespace UnityEngine
{
[Serializable]
[CreateAssetMenu(fileName = "New Rule Override Tile", menuName = "Tiles/Rule Override Tile")]
public class RuleOverrideTile : TileBase
{
[Serializable]
public class TileSpritePair
{
public Sprite m_OriginalSprite;
public Sprite m_OverrideSprite;
}
[Serializable]
public class OverrideTilingRule
{
public bool m_Enabled;
public RuleTile.TilingRule m_TilingRule = new RuleTile.TilingRule();
}
public Sprite this[Sprite originalSprite]
{
get
{
foreach (TileSpritePair spritePair in m_Sprites)
{
if (spritePair.m_OriginalSprite == originalSprite)
{
return spritePair.m_OverrideSprite;
}
}
return null;
}
set
{
if (value == null)
{
m_Sprites = m_Sprites.Where(spritePair => spritePair.m_OriginalSprite != originalSprite).ToList();
}
else
{
foreach (TileSpritePair spritePair in m_Sprites)
{
if (spritePair.m_OriginalSprite == originalSprite)
{
spritePair.m_OverrideSprite = value;
return;
}
}
m_Sprites.Add(new TileSpritePair()
{
m_OriginalSprite = originalSprite,
m_OverrideSprite = value,
});
}
}
}
public RuleTile.TilingRule this[RuleTile.TilingRule originalRule]
{
get
{
if (!m_Tile)
return null;
int index = m_Tile.m_TilingRules.IndexOf(originalRule);
if (index == -1)
return null;
if (m_OverrideTilingRules.Count < index + 1)
return null;
return m_OverrideTilingRules[index].m_Enabled ? m_OverrideTilingRules[index].m_TilingRule : null;
}
set
{
if (!m_Tile)
return;
int index = m_Tile.m_TilingRules.IndexOf(originalRule);
if (index == -1)
return;
if (value == null)
{
if (m_OverrideTilingRules.Count < index + 1)
return;
m_OverrideTilingRules[index].m_Enabled = false;
while (m_OverrideTilingRules.Count > 0 && !m_OverrideTilingRules[m_OverrideTilingRules.Count - 1].m_Enabled)
m_OverrideTilingRules.RemoveAt(m_OverrideTilingRules.Count - 1);
}
else
{
while (m_OverrideTilingRules.Count < index + 1)
m_OverrideTilingRules.Add(new OverrideTilingRule());
m_OverrideTilingRules[index].m_Enabled = true;
m_OverrideTilingRules[index].m_TilingRule = CloneTilingRule(value);
m_OverrideTilingRules[index].m_TilingRule.m_Neighbors = null;
}
}
}
public RuleTile m_Tile;
public bool m_Advanced;
public List<TileSpritePair> m_Sprites = new List<TileSpritePair>();
public List<OverrideTilingRule> m_OverrideTilingRules = new List<OverrideTilingRule>();
public OverrideTilingRule m_OverrideDefault = new OverrideTilingRule();
public RuleTile.TilingRule m_OriginalDefault
{
get
{
return new RuleTile.TilingRule()
{
m_Sprites = new Sprite[] { m_Tile != null ? m_Tile.m_DefaultSprite : null },
m_ColliderType = m_Tile != null ? m_Tile.m_DefaultColliderType : Tile.ColliderType.None,
};
}
}
private RuleTile m_RuntimeTile;
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
if (!m_RuntimeTile)
Override();
return m_RuntimeTile.GetTileAnimationData(position, tilemap, ref tileAnimationData);
}
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
if (!m_RuntimeTile)
Override();
m_RuntimeTile.GetTileData(position, tilemap, ref tileData);
}
public override void RefreshTile(Vector3Int position, ITilemap tilemap)
{
if (!m_RuntimeTile)
Override();
m_RuntimeTile.RefreshTile(position, tilemap);
}
public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject go)
{
Override();
return m_RuntimeTile.StartUp(position, tilemap, go);
}
public void ApplyOverrides(IList<KeyValuePair<Sprite, Sprite>> overrides)
{
if (overrides == null)
throw new System.ArgumentNullException("overrides");
for (int i = 0; i < overrides.Count; i++)
this[overrides[i].Key] = overrides[i].Value;
}
public void GetOverrides(List<KeyValuePair<Sprite, Sprite>> overrides)
{
if (overrides == null)
throw new System.ArgumentNullException("overrides");
overrides.Clear();
if (!m_Tile)
return;
List<Sprite> originalSprites = new List<Sprite>();
if (m_Tile.m_DefaultSprite)
originalSprites.Add(m_Tile.m_DefaultSprite);
foreach (RuleTile.TilingRule rule in m_Tile.m_TilingRules)
foreach (Sprite sprite in rule.m_Sprites)
if (sprite && !originalSprites.Contains(sprite))
originalSprites.Add(sprite);
foreach (Sprite sprite in originalSprites)
overrides.Add(new KeyValuePair<Sprite, Sprite>(sprite, this[sprite]));
}
public void ApplyOverrides(IList<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>> overrides)
{
if (overrides == null)
throw new System.ArgumentNullException("overrides");
for (int i = 0; i < overrides.Count; i++)
this[overrides[i].Key] = overrides[i].Value;
}
public void GetOverrides(List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>> overrides)
{
if (overrides == null)
throw new System.ArgumentNullException("overrides");
overrides.Clear();
if (!m_Tile)
return;
foreach (var originalRule in m_Tile.m_TilingRules)
{
RuleTile.TilingRule overrideRule = this[originalRule];
overrides.Add(new KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>(originalRule, overrideRule));
}
overrides.Add(new KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>(m_OriginalDefault, m_OverrideDefault.m_TilingRule));
}
public void Override()
{
m_RuntimeTile = m_Tile ? Instantiate(m_Tile) : new RuleTile();
m_RuntimeTile.m_Self = this;
if (!m_Advanced)
{
if (m_RuntimeTile.m_DefaultSprite)
m_RuntimeTile.m_DefaultSprite = this[m_RuntimeTile.m_DefaultSprite];
if (m_RuntimeTile.m_TilingRules != null)
foreach (RuleTile.TilingRule rule in m_RuntimeTile.m_TilingRules)
for (int i = 0; i < rule.m_Sprites.Length; i++)
if (rule.m_Sprites[i])
rule.m_Sprites[i] = this[rule.m_Sprites[i]];
}
else
{
if (m_OverrideDefault.m_Enabled)
{
m_RuntimeTile.m_DefaultSprite = m_OverrideDefault.m_TilingRule.m_Sprites.Length > 0 ? m_OverrideDefault.m_TilingRule.m_Sprites[0] : null;
m_RuntimeTile.m_DefaultColliderType = m_OverrideDefault.m_TilingRule.m_ColliderType;
}
if (m_RuntimeTile.m_TilingRules != null) {
for (int i = 0; i < m_RuntimeTile.m_TilingRules.Count; i++)
{
RuleTile.TilingRule originalRule = m_RuntimeTile.m_TilingRules[i];
RuleTile.TilingRule overrideRule = this[m_Tile.m_TilingRules[i]];
if (overrideRule == null)
continue;
CopyTilingRule(overrideRule, originalRule, false);
}
}
}
}
public RuleTile.TilingRule CloneTilingRule(RuleTile.TilingRule from)
{
var clone = new RuleTile.TilingRule();
CopyTilingRule(from, clone, true);
return clone;
}
public void CopyTilingRule(RuleTile.TilingRule from, RuleTile.TilingRule to, bool copyRule)
{
if (copyRule)
{
to.m_Neighbors = from.m_Neighbors;
to.m_RuleTransform = from.m_RuleTransform;
}
to.m_Sprites = from.m_Sprites.Clone() as Sprite[];
to.m_AnimationSpeed = from.m_AnimationSpeed;
to.m_PerlinScale = from.m_PerlinScale;
to.m_Output = from.m_Output;
to.m_ColliderType = from.m_ColliderType;
to.m_RandomTransform = from.m_RandomTransform;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c779848d9dd029409ca676b49e10a18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8f0e4a19192261d448b776e63139448e
folderAsset: yes
timeCreated: 1501789590
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c19b34cefe86ca041af273c422ce286e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
[CreateAssetMenu]
public class #SCRIPTNAME# : RuleTile<#SCRIPTNAME#.Neighbor> {
public bool customField;
public class Neighbor : RuleTile.TilingRule.Neighbor {
public const int Null = 3;
public const int NotNull = 4;
}
public override bool RuleMatch(int neighbor, TileBase tile) {
switch (neighbor) {
case Neighbor.Null: return tile == null;
case Neighbor.NotNull: return tile != null;
}
return base.RuleMatch(neighbor, tile);
}
#if UNITY_EDITOR
public override void RuleOnGUI(Rect rect, Vector2Int pos, int neighbor) {
base.RuleOnGUI(rect, pos, neighbor);
}
#endif
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 186e43c057806e545b5fa3fe8dc394c1
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6d62b55c63b75aa468f7dc342717b87f
folderAsset: yes
timeCreated: 1501789661
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 32b801acc992cb24298d963cc554c0a2
folderAsset: yes
timeCreated: 1501789682
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
namespace UnityEditor
{
static class CustomRuleTileMenu
{
[MenuItem("Assets/Create/Custom Rule Tile Script", false, 89)]
static void CreateCustomRuleTile()
{
CreateScriptAsset("Assets/Tilemap/Tiles/Rule Tile/ScriptTemplates/NewCustomRuleTile.cs.txt", "NewCustomRuleTile.cs");
}
static void CreateScriptAsset(string templatePath, string destName)
{
typeof(ProjectWindowUtil)
.GetMethod("CreateScriptAsset", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.Invoke(null, new object[] { templatePath, destName });
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a641ca7aea56f8428c8c6efc8e618cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,377 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using UnityEditor.Sprites;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Tilemaps;
using Object = UnityEngine.Object;
namespace UnityEditor
{
[CustomEditor(typeof(RuleTile), true)]
[CanEditMultipleObjects]
internal class RuleTileEditor : Editor
{
private const string s_MirrorX = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAG1JREFUOE+lj9ENwCAIRB2IFdyRfRiuDSaXAF4MrR9P5eRhHGb2Gxp2oaEjIovTXSrAnPNx6hlgyCZ7o6omOdYOldGIZhAziEmOTSfigLV0RYAB9y9f/7kO8L3WUaQyhCgz0dmCL9CwCw172HgBeyG6oloC8fAAAAAASUVORK5CYII=";
private const string s_MirrorY = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAG9JREFUOE+djckNACEMAykoLdAjHbPyw1IOJ0L7mAejjFlm9hspyd77Kk+kBAjPOXcakJIh6QaKyOE0EB5dSPJAiUmOiL8PMVGxugsP/0OOib8vsY8yYwy6gRyC8CB5QIWgCMKBLgRSkikEUr5h6wOPWfMoCYILdgAAAABJRU5ErkJggg==";
private const string s_Rotated = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAHdJREFUOE+djssNwCAMQxmIFdgx+2S4Vj4YxWlQgcOT8nuG5u5C732Sd3lfLlmPMR4QhXgrTQaimUlA3EtD+CJlBuQ7aUAUMjEAv9gWCQNEPhHJUkYfZ1kEpcxDzioRzGIlr0Qwi0r+Q5rTgM+AAVcygHgt7+HtBZs/2QVWP8ahAAAAAElFTkSuQmCC";
private static Texture2D[] s_AutoTransforms;
public static Texture2D[] autoTransforms
{
get
{
if (s_AutoTransforms == null)
{
s_AutoTransforms = new Texture2D[3];
s_AutoTransforms[0] = RuleTile.Base64ToTexture(s_Rotated);
s_AutoTransforms[1] = RuleTile.Base64ToTexture(s_MirrorX);
s_AutoTransforms[2] = RuleTile.Base64ToTexture(s_MirrorY);
}
return s_AutoTransforms;
}
}
private ReorderableList m_ReorderableList;
public RuleTile tile { get { return (target as RuleTile); } }
private Rect m_ListRect;
internal const float k_DefaultElementHeight = 48f;
internal const float k_PaddingBetweenRules = 26f;
internal const float k_SingleLineHeight = 16f;
internal const float k_ObjectFieldLineHeight = 20f;
internal const float k_LabelWidth = 80f;
public void OnEnable()
{
if (tile.m_TilingRules == null)
tile.m_TilingRules = new List<RuleTile.TilingRule>();
m_ReorderableList = new ReorderableList(tile.m_TilingRules, typeof(RuleTile.TilingRule), true, true, true, true);
m_ReorderableList.drawHeaderCallback = OnDrawHeader;
m_ReorderableList.drawElementCallback = OnDrawElement;
m_ReorderableList.elementHeightCallback = GetElementHeight;
m_ReorderableList.onReorderCallback = ListUpdated;
m_ReorderableList.onAddCallback = OnAddElement;
}
private void ListUpdated(ReorderableList list)
{
SaveTile();
}
private float GetElementHeight(int index)
{
if (tile.m_TilingRules != null && tile.m_TilingRules.Count > 0)
{
switch (tile.m_TilingRules[index].m_Output)
{
case RuleTile.TilingRule.OutputSprite.Random:
return k_DefaultElementHeight + k_SingleLineHeight*(tile.m_TilingRules[index].m_Sprites.Length + 3) + k_PaddingBetweenRules;
case RuleTile.TilingRule.OutputSprite.Animation:
return k_DefaultElementHeight + k_SingleLineHeight*(tile.m_TilingRules[index].m_Sprites.Length + 2) + k_PaddingBetweenRules;
}
}
return k_DefaultElementHeight + k_PaddingBetweenRules;
}
private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused)
{
RuleTile.TilingRule rule = tile.m_TilingRules[index];
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
Rect matrixRect = new Rect(rect.xMax - matrixWidth * 2f - 10f, yPos, matrixWidth, k_DefaultElementHeight);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
EditorGUI.BeginChangeCheck();
RuleInspectorOnGUI(inspectorRect, rule);
RuleMatrixOnGUI(tile, matrixRect, rule);
SpriteOnGUI(spriteRect, rule);
if (EditorGUI.EndChangeCheck())
SaveTile();
}
private void OnAddElement(ReorderableList list)
{
RuleTile.TilingRule rule = new RuleTile.TilingRule();
rule.m_Output = RuleTile.TilingRule.OutputSprite.Single;
rule.m_Sprites[0] = tile.m_DefaultSprite;
rule.m_GameObject = tile.m_DefaultGameObject;
rule.m_ColliderType = tile.m_DefaultColliderType;
tile.m_TilingRules.Add(rule);
}
private void SaveTile()
{
EditorUtility.SetDirty(target);
SceneView.RepaintAll();
}
private void OnDrawHeader(Rect rect)
{
GUI.Label(rect, "Tiling Rules");
}
public override void OnInspectorGUI()
{
tile.m_DefaultSprite = EditorGUILayout.ObjectField("Default Sprite", tile.m_DefaultSprite, typeof(Sprite), false) as Sprite;
tile.m_DefaultGameObject = EditorGUILayout.ObjectField("Default Game Object", tile.m_DefaultGameObject, typeof(GameObject), false) as GameObject;
tile.m_DefaultColliderType = (Tile.ColliderType)EditorGUILayout.EnumPopup("Default Collider", tile.m_DefaultColliderType);
var baseFields = typeof(RuleTile).GetFields().Select(field => field.Name);
var fields = target.GetType().GetFields().Select(field => field.Name).Where(field => !baseFields.Contains(field));
foreach (var field in fields)
EditorGUILayout.PropertyField(serializedObject.FindProperty(field), true);
EditorGUILayout.Space();
if (m_ReorderableList != null && tile.m_TilingRules != null)
m_ReorderableList.DoLayoutList();
}
internal static void RuleMatrixOnGUI(RuleTile tile, Rect rect, RuleTile.TilingRule tilingRule)
{
Handles.color = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.2f) : new Color(0f, 0f, 0f, 0.2f);
int index = 0;
float w = rect.width / 3f;
float h = rect.height / 3f;
for (int y = 0; y <= 3; y++)
{
float top = rect.yMin + y * h;
Handles.DrawLine(new Vector3(rect.xMin, top), new Vector3(rect.xMax, top));
}
for (int x = 0; x <= 3; x++)
{
float left = rect.xMin + x * w;
Handles.DrawLine(new Vector3(left, rect.yMin), new Vector3(left, rect.yMax));
}
Handles.color = Color.white;
for (int y = 0; y <= 2; y++)
{
for (int x = 0; x <= 2; x++)
{
Rect r = new Rect(rect.xMin + x * w, rect.yMin + y * h, w - 1, h - 1);
if (x != 1 || y != 1)
{
tile.RuleOnGUI(r, new Vector2Int(x, y), tilingRule.m_Neighbors[index]);
if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition))
{
int change = 1;
if (Event.current.button == 1)
change = -1;
var allConsts = tile.m_NeighborType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
var neighbors = allConsts.Select(c => (int)c.GetValue(null)).ToList();
neighbors.Sort();
int oldIndex = neighbors.IndexOf(tilingRule.m_Neighbors[index]);
int newIndex = (int)Mathf.Repeat(oldIndex + change, neighbors.Count);
tilingRule.m_Neighbors[index] = neighbors[newIndex];
GUI.changed = true;
Event.current.Use();
}
index++;
}
else
{
switch (tilingRule.m_RuleTransform)
{
case RuleTile.TilingRule.Transform.Rotated:
GUI.DrawTexture(r, autoTransforms[0]);
break;
case RuleTile.TilingRule.Transform.MirrorX:
GUI.DrawTexture(r, autoTransforms[1]);
break;
case RuleTile.TilingRule.Transform.MirrorY:
GUI.DrawTexture(r, autoTransforms[2]);
break;
}
if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition))
{
tilingRule.m_RuleTransform = (RuleTile.TilingRule.Transform)(((int)tilingRule.m_RuleTransform + 1) % 4);
GUI.changed = true;
Event.current.Use();
}
}
}
}
}
private static void OnSelect(object userdata)
{
MenuItemData data = (MenuItemData) userdata;
data.m_Rule.m_RuleTransform = data.m_NewValue;
}
private class MenuItemData
{
public RuleTile.TilingRule m_Rule;
public RuleTile.TilingRule.Transform m_NewValue;
public MenuItemData(RuleTile.TilingRule mRule, RuleTile.TilingRule.Transform mNewValue)
{
this.m_Rule = mRule;
this.m_NewValue = mNewValue;
}
}
internal static void SpriteOnGUI(Rect rect, RuleTile.TilingRule tilingRule)
{
tilingRule.m_Sprites[0] = EditorGUI.ObjectField(new Rect(rect.xMax - rect.height, rect.yMin, rect.height, rect.height), tilingRule.m_Sprites[0], typeof (Sprite), false) as Sprite;
}
internal static void RuleInspectorOnGUI(Rect rect, RuleTile.TilingRule tilingRule)
{
float y = rect.yMin;
EditorGUI.BeginChangeCheck();
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Game Object");
tilingRule.m_GameObject = (GameObject)EditorGUI.ObjectField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), "", tilingRule.m_GameObject, typeof(GameObject), true);
y += k_ObjectFieldLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Rule");
tilingRule.m_RuleTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_RuleTransform);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
tilingRule.m_ColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_ColliderType);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Output");
tilingRule.m_Output = (RuleTile.TilingRule.OutputSprite)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Output);
y += k_SingleLineHeight;
if (tilingRule.m_Output == RuleTile.TilingRule.OutputSprite.Animation)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Speed");
tilingRule.m_AnimationSpeed = EditorGUI.FloatField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_AnimationSpeed);
y += k_SingleLineHeight;
}
if (tilingRule.m_Output == RuleTile.TilingRule.OutputSprite.Random)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Noise");
tilingRule.m_PerlinScale = EditorGUI.Slider(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_PerlinScale, 0.001f, 0.999f);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Shuffle");
tilingRule.m_RandomTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_RandomTransform);
y += k_SingleLineHeight;
}
if (tilingRule.m_Output != RuleTile.TilingRule.OutputSprite.Single)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Size");
EditorGUI.BeginChangeCheck();
int newLength = EditorGUI.DelayedIntField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Sprites.Length);
if (EditorGUI.EndChangeCheck())
Array.Resize(ref tilingRule.m_Sprites, Math.Max(newLength, 1));
y += k_SingleLineHeight;
for (int i = 0; i < tilingRule.m_Sprites.Length; i++)
{
tilingRule.m_Sprites[i] = EditorGUI.ObjectField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Sprites[i], typeof(Sprite), false) as Sprite;
y += k_SingleLineHeight;
}
}
}
public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
{
if (tile.m_DefaultSprite != null)
{
Type t = GetType("UnityEditor.SpriteUtility");
if (t != null)
{
MethodInfo method = t.GetMethod("RenderStaticPreview", new Type[] {typeof (Sprite), typeof (Color), typeof (int), typeof (int)});
if (method != null)
{
object ret = method.Invoke("RenderStaticPreview", new object[] {tile.m_DefaultSprite, Color.white, width, height});
if (ret is Texture2D)
return ret as Texture2D;
}
}
}
return base.RenderStaticPreview(assetPath, subAssets, width, height);
}
private static Type GetType(string TypeName)
{
var type = Type.GetType(TypeName);
if (type != null)
return type;
if (TypeName.Contains("."))
{
var assemblyName = TypeName.Substring(0, TypeName.IndexOf('.'));
var assembly = Assembly.Load(assemblyName);
if (assembly == null)
return null;
type = assembly.GetType(TypeName);
if (type != null)
return type;
}
var currentAssembly = Assembly.GetExecutingAssembly();
var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
foreach (var assemblyName in referencedAssemblies)
{
var assembly = Assembly.Load(assemblyName);
if (assembly != null)
{
type = assembly.GetType(TypeName);
if (type != null)
return type;
}
}
return null;
}
[Serializable]
class RuleTileRuleWrapper
{
[SerializeField]
public List<RuleTile.TilingRule> rules = new List<RuleTile.TilingRule>();
}
[MenuItem("CONTEXT/RuleTile/Copy All Rules")]
private static void CopyAllRules(MenuCommand item)
{
RuleTile tile = item.context as RuleTile;
if (tile == null)
return;
RuleTileRuleWrapper rulesWrapper = new RuleTileRuleWrapper();
rulesWrapper.rules = tile.m_TilingRules;
var rulesJson = EditorJsonUtility.ToJson(rulesWrapper);
EditorGUIUtility.systemCopyBuffer = rulesJson;
}
[MenuItem("CONTEXT/RuleTile/Paste Rules")]
private static void PasteRules(MenuCommand item)
{
RuleTile tile = item.context as RuleTile;
if (tile == null)
return;
try
{
RuleTileRuleWrapper rulesWrapper = new RuleTileRuleWrapper();
EditorJsonUtility.FromJsonOverwrite(EditorGUIUtility.systemCopyBuffer, rulesWrapper);
tile.m_TilingRules.AddRange(rulesWrapper.rules);
}
catch (Exception)
{
Debug.LogError("Unable to paste rules from system copy buffer");
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 139f9377103555b49b8dcd62686df3bf
timeCreated: 1501789622
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,415 @@
using System;
using System.Collections.Generic;
using UnityEngine.Tilemaps;
namespace UnityEngine
{
public class RuleTile<T> : RuleTile
{
public sealed override Type m_NeighborType { get { return typeof(T); } }
}
[Serializable]
[CreateAssetMenu(fileName = "New Rule Tile", menuName = "Tiles/Rule Tile")]
public class RuleTile : TileBase
{
#if UNITY_EDITOR
private const string s_XIconString = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABoSURBVDhPnY3BDcAgDAOZhS14dP1O0x2C/LBEgiNSHvfwyZabmV0jZRUpq2zi6f0DJwdcQOEdwwDLypF0zHLMa9+NQRxkQ+ACOT2STVw/q8eY1346ZlE54sYAhVhSDrjwFymrSFnD2gTZpls2OvFUHAAAAABJRU5ErkJggg==";
private const string s_Arrow0 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACYSURBVDhPzZExDoQwDATzE4oU4QXXcgUFj+YxtETwgpMwXuFcwMFSRMVKKwzZcWzhiMg91jtg34XIntkre5EaT7yjjhI9pOD5Mw5k2X/DdUwFr3cQ7Pu23E/BiwXyWSOxrNqx+ewnsayam5OLBtbOGPUM/r93YZL4/dhpR/amwByGFBz170gNChA6w5bQQMqramBTgJ+Z3A58WuWejPCaHQAAAABJRU5ErkJggg==";
private const string s_Arrow1 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABqSURBVDhPxYzBDYAgEATpxYcd+PVr0fZ2siZrjmMhFz6STIiDs8XMlpEyi5RkO/d66TcgJUB43JfNBqRkSEYDnYjhbKD5GIUkDqRDwoH3+NgTAw+bL/aoOP4DOgH+iwECEt+IlFmkzGHlAYKAWF9R8zUnAAAAAElFTkSuQmCC";
private const string s_Arrow2 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAC0SURBVDhPjVE5EsIwDMxPKFKYF9CagoJH8xhaMskLmEGsjOSRkBzYmU2s9a58TUQUmCH1BWEHweuKP+D8tphrWcAHuIGrjPnPNY8X2+DzEWE+FzrdrkNyg2YGNNfRGlyOaZDJOxBrDhgOowaYW8UW0Vau5ZkFmXbbDr+CzOHKmLinAXMEePyZ9dZkZR+s5QX2O8DY3zZ/sgYcdDqeEVp8516o0QQV1qeMwg6C91toYoLoo+kNt/tpKQEVvFQAAAAASUVORK5CYII=";
private const string s_Arrow3 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAB2SURBVDhPzY1LCoAwEEPnLi48gW5d6p31bH5SMhp0Cq0g+CCLxrzRPqMZ2pRqKG4IqzJc7JepTlbRZXYpWTg4RZE1XAso8VHFKNhQuTjKtZvHUNCEMogO4K3BhvMn9wP4EzoPZ3n0AGTW5fiBVzLAAYTP32C2Ay3agtu9V/9PAAAAAElFTkSuQmCC";
private const string s_Arrow5 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABqSURBVDhPnY3BCYBADASvFx924NevRdvbyoLBmNuDJQMDGjNxAFhK1DyUQ9fvobCdO+j7+sOKj/uSB+xYHZAxl7IR1wNTXJeVcaAVU+614uWfCT9mVUhknMlxDokd15BYsQrJFHeUQ0+MB5ErsPi/6hO1AAAAAElFTkSuQmCC";
private const string s_Arrow6 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACaSURBVDhPxZExEkAwEEVzE4UiTqClUDi0w2hlOIEZsV82xCZmQuPPfFn8t1mirLWf7S5flQOXjd64vCuEKWTKVt+6AayH3tIa7yLg6Qh2FcKFB72jBgJeziA1CMHzeaNHjkfwnAK86f3KUafU2ClHIJSzs/8HHLv09M3SaMCxS7ljw/IYJWzQABOQZ66x4h614ahTCL/WT7BSO51b5Z5hSx88AAAAAElFTkSuQmCC";
private const string s_Arrow7 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABQSURBVDhPYxh8QNle/T8U/4MKEQdAmsz2eICx6W530gygr2aQBmSMphkZYxqErAEXxusKfAYQ7XyyNMIAsgEkaYQBkAFkaYQBsjXSGDAwAAD193z4luKPrAAAAABJRU5ErkJggg==";
private const string s_Arrow8 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACYSURBVDhPxZE9DoAwCIW9iUOHegJXHRw8tIdx1egJTMSHAeMPaHSR5KVQ+KCkCRF91mdz4VDEWVzXTBgg5U1N5wahjHzXS3iFFVRxAygNVaZxJ6VHGIl2D6oUXP0ijlJuTp724FnID1Lq7uw2QM5+thoKth0N+GGyA7IA3+yM77Ag1e2zkey5gCdAg/h8csy+/89v7E+YkgUntOWeVt2SfAAAAABJRU5ErkJggg==";
private static Texture2D[] s_Arrows;
public static Texture2D[] arrows
{
get
{
if (s_Arrows == null)
{
s_Arrows = new Texture2D[10];
s_Arrows[0] = Base64ToTexture(s_Arrow0);
s_Arrows[1] = Base64ToTexture(s_Arrow1);
s_Arrows[2] = Base64ToTexture(s_Arrow2);
s_Arrows[3] = Base64ToTexture(s_Arrow3);
s_Arrows[5] = Base64ToTexture(s_Arrow5);
s_Arrows[6] = Base64ToTexture(s_Arrow6);
s_Arrows[7] = Base64ToTexture(s_Arrow7);
s_Arrows[8] = Base64ToTexture(s_Arrow8);
s_Arrows[9] = Base64ToTexture(s_XIconString);
}
return s_Arrows;
}
}
public static Texture2D Base64ToTexture(string base64)
{
Texture2D t = new Texture2D(1, 1);
t.hideFlags = HideFlags.HideAndDontSave;
t.LoadImage(System.Convert.FromBase64String(base64));
return t;
}
public virtual void RuleOnGUI(Rect rect, Vector2Int pos, int neighbor)
{
switch (neighbor)
{
case RuleTile.TilingRule.Neighbor.DontCare:
break;
case RuleTile.TilingRule.Neighbor.This:
GUI.DrawTexture(rect, arrows[pos.y * 3 + pos.x]);
break;
case RuleTile.TilingRule.Neighbor.NotThis:
GUI.DrawTexture(rect, arrows[9]);
break;
default:
var style = new GUIStyle();
style.alignment = TextAnchor.MiddleCenter;
style.fontSize = 10;
GUI.Label(rect, neighbor.ToString(), style);
break;
}
var allConsts = m_NeighborType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
foreach (var c in allConsts)
{
if ((int)c.GetValue(null) == neighbor)
{
GUI.Label(rect, new GUIContent("", c.Name));
break;
}
}
}
#endif
public virtual Type m_NeighborType { get { return typeof(TilingRule.Neighbor); } }
private static readonly int[,] RotatedOrMirroredIndexes =
{
{2, 4, 7, 1, 6, 0, 3, 5}, // 90
{7, 6, 5, 4, 3, 2, 1, 0}, // 180, XY
{5, 3, 0, 6, 1, 7, 4, 2}, // 270
{2, 1, 0, 4, 3, 7, 6, 5}, // X
{5, 6, 7, 3, 4, 0, 1, 2}, // Y
};
private static readonly int NeighborCount = 8;
public Sprite m_DefaultSprite;
public GameObject m_DefaultGameObject;
public Tile.ColliderType m_DefaultColliderType = Tile.ColliderType.Sprite;
public TileBase m_Self
{
get { return m_OverrideSelf ? m_OverrideSelf : this; }
set { m_OverrideSelf = value; }
}
private TileBase[] m_CachedNeighboringTiles = new TileBase[NeighborCount];
private TileBase m_OverrideSelf;
private Quaternion m_GameObjectQuaternion;
[Serializable]
public class TilingRule
{
public int[] m_Neighbors;
public Sprite[] m_Sprites;
public GameObject m_GameObject;
public float m_AnimationSpeed;
public float m_PerlinScale;
public Transform m_RuleTransform;
public OutputSprite m_Output;
public Tile.ColliderType m_ColliderType;
public Transform m_RandomTransform;
public TilingRule()
{
m_Output = OutputSprite.Single;
m_Neighbors = new int[NeighborCount];
m_Sprites = new Sprite[1];
m_GameObject = null;
m_AnimationSpeed = 1f;
m_PerlinScale = 0.5f;
m_ColliderType = Tile.ColliderType.Sprite;
for (int i = 0; i < m_Neighbors.Length; i++)
m_Neighbors[i] = Neighbor.DontCare;
}
public class Neighbor
{
public const int DontCare = 0;
public const int This = 1;
public const int NotThis = 2;
}
public enum Transform { Fixed, Rotated, MirrorX, MirrorY }
public enum OutputSprite { Single, Random, Animation }
}
[HideInInspector] public List<TilingRule> m_TilingRules;
public override bool StartUp(Vector3Int location, ITilemap tilemap, GameObject instantiateedGameObject)
{
if (instantiateedGameObject != null)
{
instantiateedGameObject.transform.position = location + new Vector3(0.5f,0.5f,0);
instantiateedGameObject.transform.rotation = m_GameObjectQuaternion;
}
return true;
}
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
TileBase[] neighboringTiles = null;
GetMatchingNeighboringTiles(tilemap, position, ref neighboringTiles);
var iden = Matrix4x4.identity;
tileData.sprite = m_DefaultSprite;
tileData.gameObject = m_DefaultGameObject;
tileData.colliderType = m_DefaultColliderType;
tileData.flags = TileFlags.LockTransform;
tileData.transform = iden;
foreach (TilingRule rule in m_TilingRules)
{
Matrix4x4 transform = iden;
if (RuleMatches(rule, ref neighboringTiles, ref transform))
{
switch (rule.m_Output)
{
case TilingRule.OutputSprite.Single:
case TilingRule.OutputSprite.Animation:
tileData.sprite = rule.m_Sprites[0];
break;
case TilingRule.OutputSprite.Random:
int index = Mathf.Clamp(Mathf.FloorToInt(GetPerlinValue(position, rule.m_PerlinScale, 100000f) * rule.m_Sprites.Length), 0, rule.m_Sprites.Length - 1);
tileData.sprite = rule.m_Sprites[index];
if (rule.m_RandomTransform != TilingRule.Transform.Fixed)
transform = ApplyRandomTransform(rule.m_RandomTransform, transform, rule.m_PerlinScale, position);
break;
}
tileData.transform = transform;
tileData.gameObject = rule.m_GameObject;
tileData.colliderType = rule.m_ColliderType;
// Converts the tile's rotation matrix to a quaternion to be used by the instantiated Game Object
m_GameObjectQuaternion = Quaternion.LookRotation(new Vector3(transform.m02, transform.m12, transform.m22), new Vector3(transform.m01, transform.m11, transform.m21));
break;
}
}
}
private static float GetPerlinValue(Vector3Int position, float scale, float offset)
{
return Mathf.PerlinNoise((position.x + offset) * scale, (position.y + offset) * scale);
}
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
TileBase[] neighboringTiles = null;
var iden = Matrix4x4.identity;
foreach (TilingRule rule in m_TilingRules)
{
if (rule.m_Output == TilingRule.OutputSprite.Animation)
{
Matrix4x4 transform = iden;
GetMatchingNeighboringTiles(tilemap, position, ref neighboringTiles);
if (RuleMatches(rule, ref neighboringTiles, ref transform))
{
tileAnimationData.animatedSprites = rule.m_Sprites;
tileAnimationData.animationSpeed = rule.m_AnimationSpeed;
return true;
}
}
}
return false;
}
public override void RefreshTile(Vector3Int location, ITilemap tileMap)
{
if (m_TilingRules != null && m_TilingRules.Count > 0)
{
for (int y = -1; y <= 1; y++)
{
for (int x = -1; x <= 1; x++)
{
base.RefreshTile(location + new Vector3Int(x, y, 0), tileMap);
}
}
}
else
{
base.RefreshTile(location, tileMap);
}
}
public bool RuleMatches(TilingRule rule, ref TileBase[] neighboringTiles, ref Matrix4x4 transform)
{
// Check rule against rotations of 0, 90, 180, 270
for (int angle = 0; angle <= (rule.m_RuleTransform == TilingRule.Transform.Rotated ? 270 : 0); angle += 90)
{
if (RuleMatches(rule, ref neighboringTiles, angle))
{
transform = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -angle), Vector3.one);
return true;
}
}
// Check rule against x-axis mirror
if ((rule.m_RuleTransform == TilingRule.Transform.MirrorX) && RuleMatches(rule, ref neighboringTiles, true, false))
{
transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1f, 1f, 1f));
return true;
}
// Check rule against y-axis mirror
if ((rule.m_RuleTransform == TilingRule.Transform.MirrorY) && RuleMatches(rule, ref neighboringTiles, false, true))
{
transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, -1f, 1f));
return true;
}
return false;
}
private static Matrix4x4 ApplyRandomTransform(TilingRule.Transform type, Matrix4x4 original, float perlinScale, Vector3Int position)
{
float perlin = GetPerlinValue(position, perlinScale, 200000f);
switch (type)
{
case TilingRule.Transform.MirrorX:
return original * Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(perlin < 0.5 ? 1f : -1f, 1f, 1f));
case TilingRule.Transform.MirrorY:
return original * Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, perlin < 0.5 ? 1f : -1f, 1f));
case TilingRule.Transform.Rotated:
int angle = Mathf.Clamp(Mathf.FloorToInt(perlin * 4), 0, 3) * 90;
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -angle), Vector3.one);
}
return original;
}
public virtual bool RuleMatch(int neighbor, TileBase tile)
{
switch (neighbor)
{
case TilingRule.Neighbor.This: return tile == m_Self;
case TilingRule.Neighbor.NotThis: return tile != m_Self;
}
return true;
}
public bool RuleMatches(TilingRule rule, ref TileBase[] neighboringTiles, int angle)
{
for (int i = 0; i < NeighborCount; ++i)
{
int index = GetRotatedIndex(i, angle);
TileBase tile = neighboringTiles[index];
if (!RuleMatch(rule.m_Neighbors[i], tile))
{
return false;
}
}
return true;
}
public bool RuleMatches(TilingRule rule, ref TileBase[] neighboringTiles, bool mirrorX, bool mirrorY)
{
for (int i = 0; i < NeighborCount; ++i)
{
int index = GetMirroredIndex(i, mirrorX, mirrorY);
TileBase tile = neighboringTiles[index];
if (!RuleMatch(rule.m_Neighbors[i], tile))
{
return false;
}
}
return true;
}
private void GetMatchingNeighboringTiles(ITilemap tilemap, Vector3Int position, ref TileBase[] neighboringTiles)
{
if (neighboringTiles != null)
return;
if (m_CachedNeighboringTiles == null || m_CachedNeighboringTiles.Length < NeighborCount)
m_CachedNeighboringTiles = new TileBase[NeighborCount];
int index = 0;
for (int y = 1; y >= -1; y--)
{
for (int x = -1; x <= 1; x++)
{
if (x != 0 || y != 0)
{
Vector3Int tilePosition = new Vector3Int(position.x + x, position.y + y, position.z);
m_CachedNeighboringTiles[index++] = tilemap.GetTile(tilePosition);
}
}
}
neighboringTiles = m_CachedNeighboringTiles;
}
private int GetRotatedIndex(int original, int rotation)
{
switch (rotation)
{
case 0:
return original;
case 90:
return RotatedOrMirroredIndexes[0, original];
case 180:
return RotatedOrMirroredIndexes[1, original];
case 270:
return RotatedOrMirroredIndexes[2, original];
}
return original;
}
private int GetMirroredIndex(int original, bool mirrorX, bool mirrorY)
{
if (mirrorX && mirrorY)
{
return RotatedOrMirroredIndexes[1, original];
}
if (mirrorX)
{
return RotatedOrMirroredIndexes[3, original];
}
if (mirrorY)
{
return RotatedOrMirroredIndexes[4, original];
}
return original;
}
private int GetIndexOfOffset(Vector3Int offset)
{
int result = offset.x + 1 + (-offset.y + 1) * 3;
if (result >= 4)
result--;
return result;
}
public Vector3Int GetRotatedPos(Vector3Int original, int rotation)
{
switch (rotation)
{
case 0:
return original;
case 90:
return new Vector3Int(-original.y, original.x, original.z);
case 180:
return new Vector3Int(-original.x, -original.y, original.z);
case 270:
return new Vector3Int(original.y, -original.x, original.z);
}
return original;
}
public Vector3Int GetMirroredPos(Vector3Int original, bool mirrorX, bool mirrorY)
{
return new Vector3Int(original.x * (mirrorX ? -1 : 1), original.y * (mirrorY ? -1 : 1), original.z);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 9d1514134bc4fbd41bb739b1b9a49231
timeCreated: 1501789622
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7f83a174d475ee842aaea9ee552fa506
folderAsset: yes
timeCreated: 1499149439
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 14fc4c2dd67018d41b00db847f45f5dd
folderAsset: yes
timeCreated: 1499149468
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,220 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityEngine.Tilemaps
{
[Serializable]
[CreateAssetMenu(fileName = "New Terrain Tile", menuName = "Tiles/Terrain Tile")]
public class TerrainTile : TileBase
{
[SerializeField]
public Sprite[] m_Sprites;
public override void RefreshTile(Vector3Int location, ITilemap tileMap)
{
for (int yd = -1; yd <= 1; yd++)
for (int xd = -1; xd <= 1; xd++)
{
Vector3Int position = new Vector3Int(location.x + xd, location.y + yd, location.z);
if (TileValue(tileMap, position))
tileMap.RefreshTile(position);
}
}
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
UpdateTile(location, tileMap, ref tileData);
}
private void UpdateTile(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
tileData.transform = Matrix4x4.identity;
tileData.color = Color.white;
int mask = TileValue(tileMap, location + new Vector3Int(0, 1, 0)) ? 1 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, 1, 0)) ? 2 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, 0, 0)) ? 4 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, -1, 0)) ? 8 : 0;
mask += TileValue(tileMap, location + new Vector3Int(0, -1, 0)) ? 16 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, -1, 0)) ? 32 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, 0, 0)) ? 64 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, 1, 0)) ? 128 : 0;
byte original = (byte)mask;
if ((original | 254) < 255) { mask = mask & 125; }
if ((original | 251) < 255) { mask = mask & 245; }
if ((original | 239) < 255) { mask = mask & 215; }
if ((original | 191) < 255) { mask = mask & 95; }
int index = GetIndex((byte)mask);
if (index >= 0 && index < m_Sprites.Length && TileValue(tileMap, location))
{
tileData.sprite = m_Sprites[index];
tileData.transform = GetTransform((byte)mask);
tileData.color = Color.white;
tileData.flags = TileFlags.LockTransform | TileFlags.LockColor;
tileData.colliderType = Tile.ColliderType.Sprite;
}
}
private bool TileValue(ITilemap tileMap, Vector3Int position)
{
TileBase tile = tileMap.GetTile(position);
return (tile != null && tile == this);
}
private int GetIndex(byte mask)
{
switch (mask)
{
case 0: return 0;
case 1:
case 4:
case 16:
case 64: return 1;
case 5:
case 20:
case 80:
case 65: return 2;
case 7:
case 28:
case 112:
case 193: return 3;
case 17:
case 68: return 4;
case 21:
case 84:
case 81:
case 69: return 5;
case 23:
case 92:
case 113:
case 197: return 6;
case 29:
case 116:
case 209:
case 71: return 7;
case 31:
case 124:
case 241:
case 199: return 8;
case 85: return 9;
case 87:
case 93:
case 117:
case 213: return 10;
case 95:
case 125:
case 245:
case 215: return 11;
case 119:
case 221: return 12;
case 127:
case 253:
case 247:
case 223: return 13;
case 255: return 14;
}
return -1;
}
private Matrix4x4 GetTransform(byte mask)
{
switch (mask)
{
case 4:
case 20:
case 28:
case 68:
case 84:
case 92:
case 116:
case 124:
case 93:
case 125:
case 221:
case 253:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -90f), Vector3.one);
case 16:
case 80:
case 112:
case 81:
case 113:
case 209:
case 241:
case 117:
case 245:
case 247:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -180f), Vector3.one);
case 64:
case 65:
case 193:
case 69:
case 197:
case 71:
case 199:
case 213:
case 215:
case 223:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -270f), Vector3.one);
}
return Matrix4x4.identity;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(TerrainTile))]
public class TerrainTileEditor : Editor
{
private TerrainTile tile { get { return (target as TerrainTile); } }
public void OnEnable()
{
if (tile.m_Sprites == null || tile.m_Sprites.Length != 15)
{
tile.m_Sprites = new Sprite[15];
EditorUtility.SetDirty(tile);
}
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Place sprites shown based on the contents of the sprite.");
EditorGUILayout.Space();
float oldLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 210;
EditorGUI.BeginChangeCheck();
tile.m_Sprites[0] = (Sprite) EditorGUILayout.ObjectField("Filled", tile.m_Sprites[0], typeof(Sprite), false, null);
tile.m_Sprites[1] = (Sprite) EditorGUILayout.ObjectField("Three Sides", tile.m_Sprites[1], typeof(Sprite), false, null);
tile.m_Sprites[2] = (Sprite) EditorGUILayout.ObjectField("Two Sides and One Corner", tile.m_Sprites[2], typeof(Sprite), false, null);
tile.m_Sprites[3] = (Sprite) EditorGUILayout.ObjectField("Two Adjacent Sides", tile.m_Sprites[3], typeof(Sprite), false, null);
tile.m_Sprites[4] = (Sprite) EditorGUILayout.ObjectField("Two Opposite Sides", tile.m_Sprites[4], typeof(Sprite), false, null);
tile.m_Sprites[5] = (Sprite) EditorGUILayout.ObjectField("One Side and Two Corners", tile.m_Sprites[5], typeof(Sprite), false, null);
tile.m_Sprites[6] = (Sprite) EditorGUILayout.ObjectField("One Side and One Lower Corner", tile.m_Sprites[6], typeof(Sprite), false, null);
tile.m_Sprites[7] = (Sprite) EditorGUILayout.ObjectField("One Side and One Upper Corner", tile.m_Sprites[7], typeof(Sprite), false, null);
tile.m_Sprites[8] = (Sprite) EditorGUILayout.ObjectField("One Side", tile.m_Sprites[8], typeof(Sprite), false, null);
tile.m_Sprites[9] = (Sprite) EditorGUILayout.ObjectField("Four Corners", tile.m_Sprites[9], typeof(Sprite), false, null);
tile.m_Sprites[10] = (Sprite) EditorGUILayout.ObjectField("Three Corners", tile.m_Sprites[10], typeof(Sprite), false, null);
tile.m_Sprites[11] = (Sprite) EditorGUILayout.ObjectField("Two Adjacent Corners", tile.m_Sprites[11], typeof(Sprite), false, null);
tile.m_Sprites[12] = (Sprite) EditorGUILayout.ObjectField("Two Opposite Corners", tile.m_Sprites[12], typeof(Sprite), false, null);
tile.m_Sprites[13] = (Sprite) EditorGUILayout.ObjectField("One Corner", tile.m_Sprites[13], typeof(Sprite), false, null);
tile.m_Sprites[14] = (Sprite) EditorGUILayout.ObjectField("Empty", tile.m_Sprites[14], typeof(Sprite), false, null);
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(tile);
EditorGUIUtility.labelWidth = oldLabelWidth;
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f6e4e4fc705376343a3e65b25d94f0e2
timeCreated: 1464534739
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44062ec43d1b331468b33c9af1033cf8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Tilemaps {
[Serializable]
public struct WeightedSprite {
public Sprite Sprite;
public int Weight;
}
[Serializable]
[CreateAssetMenu(fileName = "New Weighted Random Tile", menuName = "Tiles/Weighted Random Tile")]
public class WeightedRandomTile : Tile {
[SerializeField] public WeightedSprite[] Sprites;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData) {
base.GetTileData(location, tileMap, ref tileData);
if (Sprites == null || Sprites.Length <= 0) return;
long hash = location.x;
hash = hash + 0xabcd1234 + (hash << 15);
hash = hash + 0x0987efab ^ (hash >> 11);
hash ^= location.y;
hash = hash + 0x46ac12fd + (hash << 7);
hash = hash + 0xbe9730af ^ (hash << 11);
Random.InitState((int) hash);
// Get the cumulative weight of the sprites
var cumulativeWeight = 0;
foreach (var spriteInfo in Sprites) cumulativeWeight += spriteInfo.Weight;
// Pick a random weight and choose a sprite depending on it
var randomWeight = Random.Range(0, cumulativeWeight);
foreach (var spriteInfo in Sprites) {
randomWeight -= spriteInfo.Weight;
if (randomWeight < 0) {
tileData.sprite = spriteInfo.Sprite;
break;
}
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(WeightedRandomTile))]
public class WeightedRandomTileEditor : Editor {
private WeightedRandomTile Tile {
get { return target as WeightedRandomTile; }
}
public override void OnInspectorGUI() {
EditorGUI.BeginChangeCheck();
int count = EditorGUILayout.DelayedIntField("Number of Sprites", Tile.Sprites != null ? Tile.Sprites.Length : 0);
if (count < 0) count = 0;
if (Tile.Sprites == null || Tile.Sprites.Length != count) {
Array.Resize(ref Tile.Sprites, count);
}
if (count == 0) return;
EditorGUILayout.LabelField("Place random sprites.");
EditorGUILayout.Space();
for (int i = 0; i < count; i++) {
Tile.Sprites[i].Sprite = (Sprite) EditorGUILayout.ObjectField("Sprite " + (i + 1), Tile.Sprites[i].Sprite, typeof(Sprite), false, null);
Tile.Sprites[i].Weight = EditorGUILayout.IntField("Weight " + (i + 1), Tile.Sprites[i].Weight);
}
if (EditorGUI.EndChangeCheck()) EditorUtility.SetDirty(Tile);
}
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 916c2519c5cedc1449e322d62fd3ceda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Unity Technologies
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0049037926a2f894ab963148ec99b2e1
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
# 2d-extras
2d-extras is a repository containing helpful reusable scripts which you can use to make your games, with a slant towards 2D. Feel free to customise the behavior of the scripts to create new tools for your use case!
Implemented examples using these scripts can be found in the sister repository [2d-techdemos](https://github.com/Unity-Technologies/2d-techdemos "2d-techdemos: Examples for 2d features").
All items in the repository are grouped by use for a feature and are listed below.
### Tilemap
For use with Unity 2018.2.0f2 onwards. Please use the 2017 branch for earlier versions of Unity (up to 2017.2).
##### Brushes
- **Coordinate**: This Brush displays the cell coordinates it is targeting in the SceneView. Use this as an example to create brushes which have extra visualization features when painting onto a Tilemap.
- **Line**: This Brush helps draw lines of Tiles onto a Tilemap. The first click of the mouse sets the starting point of the line and the second click sets the ending point of the line and draws the lines of Tiles. Use this as an example to modify brush painting behaviour to making painting quicker with less actions.
- **Random**: This Brush helps to place random Tiles onto a Tilemap. Use this as an example to create brushes which store specific data per brush and to make brushes which randomize behaviour.
- **Prefab**: This Brush instances and places a randomly selected Prefabs onto the targeted location and parents the instanced object to the paint target. Use this as an example to quickly place an assorted type of GameObjects onto structured locations.
- **GameObject**: This Brush instances, places and manipulates GameObjects onto the scene. Use this as an example to create brushes which targets objects other than tiles for manipulation.
- **TintBrush**: Brush to edit Tilemap per-cell tint colors.
- **TintBrushSmooth**: Advanced tint brush for interpolated tint color per-cell. Requires the use of custom shader (see TintedTilemap.shader) and helper component TileTextureGenerator.
##### Tiles
- **Animated**: Animated Tiles are tiles which run through and display a list of sprites in sequence.
- **Pipeline**: Pipeline Tiles are tiles which take into consideration its orthogonal neighboring tiles and displays a sprite depending on whether the neighboring tile is the same tile.
- **Random**: Random Tiles are tiles which pseudo-randomly pick a sprite from a given list of sprites and a target location, and displays that sprite.
- **Terrain**: Terrain Tiles, similar to Pipeline Tiles, are tiles which take into consideration its orthogonal and diagonal neighboring tiles and displays a sprite depending on whether the neighboring tile is the same tile.
- **RuleTile**: Generic visual tile for creating different tilesets like terrain, pipeline, random or animated tiles.
- **RuleOverrideTile**: Rule Override Tiles are Tiles which can override a subset of Rules for a given Rule Tile to provide specialised behaviour while keeping most of the Rules originally set in the Rule Tile.
- **Weighted Random**: Weighted Random Tiles are tiles which randomly pick a sprite from a given list of sprites and a target location, and displays that sprite. The sprites can be weighted with a value to change its probability of appearing.
##### Other
- **GridInformation**: A simple MonoBehaviour that stores and provides information based on Grid positions and keywords.
- **Custom Rules for RuleTile**: This helps to create new custom Rules for the Rule Tile. Check the [Wiki](https://github.com/Unity-Technologies/2d-extras/wiki) for more information on how to use this.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 26f08706aa17d1646ae1c238c81e5943
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Prefabs.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7d121e3cdc87910488ff139bd707e0d7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,147 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_SourcePrefab: {fileID: 0}
m_RootGameObject: {fileID: 1400916412662404}
m_IsPrefabAsset: 1
--- !u!1 &1400916412662404
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 6
m_Component:
- component: {fileID: 4816062612851216}
- component: {fileID: 212601370762509522}
- component: {fileID: 50547850849535880}
- component: {fileID: 61082912475822452}
- component: {fileID: 114843954174791342}
m_Layer: 0
m_Name: Falling Dirt
m_TagString: FallingBlock
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4816062612851216
Transform:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1400916412662404}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 5, y: 5, z: 5}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!50 &50547850849535880
Rigidbody2D:
serializedVersion: 4
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1400916412662404}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDrag: 0
m_AngularDrag: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 5
--- !u!61 &61082912475822452
BoxCollider2D:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1400916412662404}
m_Enabled: 1
m_Density: 1
m_Material: {fileID: 0}
m_IsTrigger: 0
m_UsedByEffector: 0
m_UsedByComposite: 0
m_Offset: {x: 0, y: 0}
m_SpriteTilingProperty:
border: {x: 0.049999997, y: 0.049999997, z: 0.049999997, w: 0.049999997}
pivot: {x: 0.5, y: 0.5}
oldSize: {x: 0.16, y: 0.16}
newSize: {x: 0.16, y: 0.16}
adaptiveTilingThreshold: 0.5
drawMode: 0
adaptiveTiling: 0
m_AutoTiling: 0
serializedVersion: 2
m_Size: {x: 0.16, y: 0.16}
m_EdgeRadius: 0
--- !u!114 &114843954174791342
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1400916412662404}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 46bda74c4a1e5524a923babddbcd28b7, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!212 &212601370762509522
SpriteRenderer:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1400916412662404}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 0.16, y: 0.16}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e39e9213b04aede49a12e77bc88f11a4
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
using System;
using UnityEditor;
using UnityEditor;
using UnityEngine;
using UnityEngine.Tilemaps;
@@ -29,7 +28,7 @@ public class TileTexturer : EditorWindow
{
BoundsInt bounds = tilemap.cellBounds;
string tilePrefix = "Assets/Tiles/" + tileType.ToString() + "/" + tileType.ToString() + "_";
string tilePrefix = "Assets/Tiles/" + tileType.ToString() + "/Resources/" + tileType.ToString() + "_";
for (int x = 0; x < (int)tileType; x++)
{
@@ -47,9 +46,3 @@ public class TileTexturer : EditorWindow
}
}
}
[Flags]
public enum ITileType
{
Dirt = 19
}

View File

@@ -1,6 +1,112 @@
using UnityEngine;
using UnityEngine.Tilemaps;
public class EnvironementManager : MonoBehaviour
{
public Camera cam;
public Tilemap tilemap;
public TileBase imuable;
public GameObject FalllingDirt;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
BreakTile(tilemap.WorldToCell(pos));
}
}
void BreakTile(Vector3Int pos)
{
tilemap.SetTile(pos, null);
if (tilemap.GetTile(new Vector3Int(pos.x - 1, pos.y, pos.z)) != null && !BlockIsStable(new Vector3Int(pos.x - 1, pos.y, pos.z)))
{
tilemap.SetTile(new Vector3Int(pos.x - 1, pos.y, pos.z), null);
SpawnFallingBlock(new Vector3Int(pos.x - 1, pos.y, pos.z));
}
if (tilemap.GetTile(new Vector3Int(pos.x + 1, pos.y, pos.z)) != null && !BlockIsStable(new Vector3Int(pos.x + 1, pos.y, pos.z)))
{
tilemap.SetTile(new Vector3Int(pos.x + 1, pos.y, pos.z), null);
SpawnFallingBlock(new Vector3Int(pos.x - 1, pos.y, pos.z));
}
if (tilemap.GetTile(new Vector3Int(pos.x, pos.y + 1, pos.z)) != null && !BlockIsStable(new Vector3Int(pos.x, pos.y + 1, pos.z)))
{
tilemap.SetTile(new Vector3Int(pos.x, pos.y + 1, pos.z), null);
SpawnFallingBlock(new Vector3Int(pos.x - 1, pos.y, pos.z));
}
}
bool BlockIsStable(Vector3Int pos, int loopUnder = 0)
{
if (BlockStableUnder(pos, loopUnder))
return true;
if (BlockStableLeft(pos))
return true;
if (BlockStableRight(pos))
return true;
return false;
}
bool BlockStableUnder(Vector3Int pos, int loop)
{
if (tilemap.GetTile(pos) == imuable)
return true;
if (tilemap.GetTile(new Vector3Int(pos.x, pos.y - 1, pos.z)) != null && (loop > 0 || BlockIsStable(new Vector3Int(pos.x, pos.y - 1, pos.z), loop + 1)))
return true;
return false;
}
bool BlockStableLeft(Vector3Int pos)
{
if (tilemap.GetTile(pos) == imuable)
return true;
if (tilemap.GetTile(new Vector3Int(pos.x - 1, pos.y, pos.z)) != null && BlockIsStable(new Vector3Int(pos.x - 1, pos.y, pos.z)))
return true;
return false;
}
bool BlockStableRight(Vector3Int pos)
{
if (tilemap.GetTile(pos) == imuable)
return true;
if (tilemap.GetTile(new Vector3Int(pos.x + 1, pos.y, pos.z)) != null && BlockIsStable(new Vector3Int(pos.x + 1, pos.y, pos.z)))
return true;
return false;
}
void SpawnFallingBlock(Vector3Int pos)
{
Vector3 position = tilemap.CellToWorld(pos);
position.x += .5f;
position.y -= .5f;
Instantiate(FalllingDirt, position, Quaternion.identity);
}
public TileBase GetDirtTile(Vector3Int pos)
{
TileBase tile = tilemap.GetTile(new Vector3Int(pos.x, pos.y - 1, pos.z));
if(tile != imuable)
{
int index = int.Parse(tile.name.Substring(5)) - ((int)ITileType.Dirt + 1);
return (TileBase)Resources.Load("Dirt_" + index);
}
else
{
tile = tilemap.GetTile(new Vector3Int(pos.x, pos.y + 1, pos.z));
int index = int.Parse(tile.name.Substring(5)) + ((int)ITileType.Dirt + 1);
return (TileBase)Resources.Load("Dirt_" + index);
}
}
}

View File

@@ -0,0 +1,21 @@
using UnityEngine;
using UnityEngine.Tilemaps;
public class FallingBlock : MonoBehaviour
{
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.transform.tag == "FallingBlock")
return;
if (collision.transform.tag == "Player")
{
return;
}
EnvironementManager environement = GameObject.Find("GameManager").GetComponent<EnvironementManager>();
Tilemap tilemap = environement.tilemap;
environement.tilemap.SetTile(tilemap.WorldToCell(transform.position), environement.GetDirtTile(tilemap.WorldToCell(transform.position)));
Destroy(gameObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 46bda74c4a1e5524a923babddbcd28b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More