mirror of
https://github.com/zoriya/Goulag-Prototype.git
synced 2025-12-06 06:36:29 +00:00
Adding falling blocks.
This commit is contained in:
8
Assets/2d-extras.meta
Normal file
8
Assets/2d-extras.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 981ff7b6c06bc1c40bed711a2d4f5808
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/2d-extras/.gitignore
vendored
Normal file
36
Assets/2d-extras/.gitignore
vendored
Normal 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
|
||||
8
Assets/2d-extras/Assets.meta
Normal file
8
Assets/2d-extras/Assets.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3da55605e07be004f9b051d08fc7203c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf9ccd4324df2364db3ac79b01297df5
|
||||
folderAsset: yes
|
||||
timeCreated: 1499146935
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Brushes.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Brushes.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43e293f28d16b1e49a0e7065fabda4f2
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149605
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9fdf071ee2746a4b9db02f10619fe06
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149747
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ea50964d54e5fe4daef60544c57e629
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149760
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b52b57c2118b2f4683f6e203db78e87
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149765
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3664941e71bb62e4b94231620856f1c9
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789833
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: becdef7ff3038f844a171e247f575688
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789865
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62c56be364c00f14ba85c5d3f280447c
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789982
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Brushes/Line Brush.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Brushes/Line Brush.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddf6fb480373a4b4babf2bd106dd48d8
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149753
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a7de8b7c9f16a54abb1f4e4b4dda454
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149780
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4ce1d57936070949bdd366b4d13335f
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149785
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Brushes/Prefab Brush.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Brushes/Prefab Brush.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b73c833515e70440a2222f774104211
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789833
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 090e78558c17f064eae502998e2f22fb
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789849
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 642e946f97259c640b3a047a57944ed9
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789995
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Brushes/Random Brush.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Brushes/Random Brush.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8dee42ba30f712246852f41830cedbef
|
||||
folderAsset: yes
|
||||
timeCreated: 1499223176
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d352e5b4c56a76e4d99fc48256bbc67e
|
||||
folderAsset: yes
|
||||
timeCreated: 1499223198
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 762d145b6139de6478fcc2998702d839
|
||||
folderAsset: yes
|
||||
timeCreated: 1499223228
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73ffdc5b54c50214e9899760b98f5754
|
||||
folderAsset: yes
|
||||
timeCreated: 1502798557
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d5759c37f6ead941b87383dcb19bff3
|
||||
folderAsset: yes
|
||||
timeCreated: 1502798569
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7402f20de7e8fc34c9cfcbc965122710
|
||||
folderAsset: yes
|
||||
timeCreated: 1502800377
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9a74a0ba597dbd4ebbdc09df032a31c
|
||||
folderAsset: yes
|
||||
timeCreated: 1502798946
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fcc3b710e7f7ae44bcf65125a08d5ef
|
||||
timeCreated: 1502805334
|
||||
licenseType: Pro
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Brushes/Tint Brush.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Brushes/Tint Brush.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91dd673b6b5d18845b756aedc65463ad
|
||||
folderAsset: yes
|
||||
timeCreated: 1502200654
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0da715375d333a8418105408e081f130
|
||||
folderAsset: yes
|
||||
timeCreated: 1502200675
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27c281d5970a0fd49bfebd8119dc790a
|
||||
folderAsset: yes
|
||||
timeCreated: 1502200680
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
10
Assets/2d-extras/Assets/Tilemap/GridInformation.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/GridInformation.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c93545baa8c686a46a0ec319b747d53f
|
||||
folderAsset: yes
|
||||
timeCreated: 1501816804
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/GridInformation/Scripts.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/GridInformation/Scripts.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa5c106bc9eac9844897d7fea5f8328c
|
||||
folderAsset: yes
|
||||
timeCreated: 1499412046
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4b96e08a92a0de42b0c2fd3c56516b4
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149591
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles/Animated Tile.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles/Animated Tile.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33e8a22612607064dbfaa9d21d1836e8
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149327
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8f0a7d912b6f424aa0e09f8597dd2df
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149343
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13b75c95f34a00d4e8c04f76b73312e6
|
||||
timeCreated: 1464531813
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles/Pipeline Tile.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles/Pipeline Tile.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af0bc89550613a14fa0feadd363358e6
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149527
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64fa95bf1baeb5f4497bd5048a284208
|
||||
folderAsset: yes
|
||||
timeCreated: 1499146919
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25192638efa881c469b1ac4d8cfd3f1b
|
||||
timeCreated: 1464534747
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles/Random Tile.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles/Random Tile.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47f5287a949e1094191c733949de285a
|
||||
folderAsset: yes
|
||||
timeCreated: 1499150037
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c3034e66d810604680654a1e667fde0
|
||||
folderAsset: yes
|
||||
timeCreated: 1499150048
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 535f8e525ff367c4ba67961e201a05ed
|
||||
timeCreated: 1445235751
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbcacf945e7001e4396ca2ca8573ae6c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e5614e4b96700843ba104987c4f190e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1263d004036ee7f42aeed98348b5e8cf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd977390416471341b10fd1278290da0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c779848d9dd029409ca676b49e10a18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles/Rule Tile.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles/Rule Tile.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f0e4a19192261d448b776e63139448e
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789590
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c19b34cefe86ca041af273c422ce286e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 186e43c057806e545b5fa3fe8dc394c1
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles/Rule Tile/Scripts.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles/Rule Tile/Scripts.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d62b55c63b75aa468f7dc342717b87f
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789661
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32b801acc992cb24298d963cc554c0a2
|
||||
folderAsset: yes
|
||||
timeCreated: 1501789682
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a641ca7aea56f8428c8c6efc8e618cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
10
Assets/2d-extras/Assets/Tilemap/Tiles/Terrain Tile.meta
Normal file
10
Assets/2d-extras/Assets/Tilemap/Tiles/Terrain Tile.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f83a174d475ee842aaea9ee552fa506
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149439
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14fc4c2dd67018d41b00db847f45f5dd
|
||||
folderAsset: yes
|
||||
timeCreated: 1499149468
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6e4e4fc705376343a3e65b25d94f0e2
|
||||
timeCreated: 1464534739
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44062ec43d1b331468b33c9af1033cf8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 916c2519c5cedc1449e322d62fd3ceda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21
Assets/2d-extras/LICENSE.md
Normal file
21
Assets/2d-extras/LICENSE.md
Normal 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.
|
||||
7
Assets/2d-extras/LICENSE.md.meta
Normal file
7
Assets/2d-extras/LICENSE.md.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0049037926a2f894ab963148ec99b2e1
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/2d-extras/README.md
Normal file
36
Assets/2d-extras/README.md
Normal 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.
|
||||
7
Assets/2d-extras/README.md.meta
Normal file
7
Assets/2d-extras/README.md.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26f08706aa17d1646ae1c238c81e5943
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Prefabs.meta
Normal file
8
Assets/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d121e3cdc87910488ff139bd707e0d7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
147
Assets/Prefabs/Falling Dirt.prefab
Normal file
147
Assets/Prefabs/Falling Dirt.prefab
Normal 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
|
||||
8
Assets/Prefabs/Falling Dirt.prefab.meta
Normal file
8
Assets/Prefabs/Falling Dirt.prefab.meta
Normal 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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
Assets/Script/FallingBlock.cs
Normal file
21
Assets/Script/FallingBlock.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Script/FallingBlock.cs.meta
Normal file
11
Assets/Script/FallingBlock.cs.meta
Normal 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
Reference in New Issue
Block a user