216 lines
4.5 KiB
C#
216 lines
4.5 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
[ExecuteInEditMode]
|
|
[AddComponentMenu("Destructible 2D/D2D Edge Colliders")]
|
|
public class D2D_EdgeColliders : D2D_Collider
|
|
{
|
|
[System.Serializable]
|
|
public class Cell
|
|
{
|
|
public List<EdgeCollider2D> EdgeCollider2Ds = new List<EdgeCollider2D>();
|
|
|
|
public void Destroy()
|
|
{
|
|
foreach (var edgeCollider2D in EdgeCollider2Ds)
|
|
{
|
|
D2D_Helper.Destroy(edgeCollider2D);
|
|
}
|
|
|
|
EdgeCollider2Ds.Clear();
|
|
}
|
|
|
|
public void ReplaceColliders(List<EdgeCollider2D> newEdgeCollider2Ds)
|
|
{
|
|
Destroy();
|
|
|
|
EdgeCollider2Ds.AddRange(newEdgeCollider2Ds);
|
|
}
|
|
|
|
public void UpdateColliderSettings(bool isTrigger, PhysicsMaterial2D material)
|
|
{
|
|
foreach (var edgeCollider2D in EdgeCollider2Ds)
|
|
{
|
|
if (edgeCollider2D != null)
|
|
{
|
|
edgeCollider2D.isTrigger = isTrigger;
|
|
edgeCollider2D.sharedMaterial = material;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[D2D_PopupAttribute(8, 16, 32, 64, 128, 256)]
|
|
public int CellSize = 64;
|
|
|
|
[D2D_RangeAttribute(0.0f, 0.3f)]
|
|
public float Tolerance = 0.01f;
|
|
|
|
[SerializeField]
|
|
private List<Cell> cells = new List<Cell>();
|
|
|
|
[SerializeField]
|
|
private int cellsX;
|
|
|
|
[SerializeField]
|
|
private int cellsY;
|
|
|
|
[SerializeField]
|
|
private int cellsXY;
|
|
|
|
[SerializeField]
|
|
private int width;
|
|
|
|
[SerializeField]
|
|
private int height;
|
|
|
|
public void RebuildAllColliders(Texture2D alphaTex)
|
|
{
|
|
if (alphaTex != null)
|
|
{
|
|
RebuildColliders(alphaTex, 0, alphaTex.width, 0, alphaTex.height);
|
|
}
|
|
else
|
|
{
|
|
DestroyAllCells();
|
|
}
|
|
}
|
|
|
|
public void RebuildColliders(Texture2D alphaTex, int xMin, int xMax, int yMin, int yMax)
|
|
{
|
|
UpdateColliders(alphaTex);
|
|
|
|
if (cells.Count > 0)
|
|
{
|
|
//var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
|
|
|
xMin = Mathf.Clamp(xMin - 1, 0, alphaTex.width - 1);
|
|
yMin = Mathf.Clamp(yMin - 1, 0, alphaTex.height - 1);
|
|
|
|
var cellXMin = xMin / CellSize;
|
|
var cellYMin = yMin / CellSize;
|
|
var cellXMax = (xMax + CellSize - 1) / CellSize;
|
|
var cellYMax = (yMax + CellSize - 1) / CellSize;
|
|
|
|
for (var cellY = cellYMin; cellY <= cellYMax; cellY++)
|
|
{
|
|
for (var cellX = cellXMin; cellX <= cellXMax; cellX++)
|
|
{
|
|
if (cellX >= 0 && cellX < cellsX && cellY >= 0 && cellY < cellsY)
|
|
{
|
|
xMin = CellSize * cellX;
|
|
yMin = CellSize * cellY;
|
|
xMax = Mathf.Min(CellSize + xMin, alphaTex.width);
|
|
yMax = Mathf.Min(CellSize + yMin, alphaTex.height);
|
|
|
|
var cell = cells[cellX + cellY * cellsX];
|
|
var newEdgeCollider2Ds = D2D_EdgeCalculator.Generate(gameObject, alphaTex, xMin, xMax, yMin, yMax, Tolerance);
|
|
|
|
cell.ReplaceColliders(newEdgeCollider2Ds);
|
|
cell.UpdateColliderSettings(IsTrigger, Material);
|
|
}
|
|
}
|
|
}
|
|
|
|
//stopwatch.Stop(); Debug.Log("RebuildColliders took " + stopwatch.ElapsedMilliseconds + " ms");
|
|
}
|
|
}
|
|
|
|
public override void UpdateColliderSettings()
|
|
{
|
|
foreach (var cell in cells)
|
|
{
|
|
if (cell != null)
|
|
{
|
|
cell.UpdateColliderSettings(IsTrigger, Material);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateColliders(Texture2D alphaTex)
|
|
{
|
|
if (alphaTex != null && alphaTex.width > 0 && alphaTex.height > 0 && CellSize > 0 && Tolerance >= 0.0f)
|
|
{
|
|
cellsX = (alphaTex.width + CellSize - 1) / CellSize;
|
|
cellsY = (alphaTex.height + CellSize - 1) / CellSize;
|
|
cellsXY = cellsX * cellsY;
|
|
|
|
if (cells.Count > 0)
|
|
{
|
|
if (cells.Count != cellsXY)
|
|
{
|
|
DestroyAllCells();
|
|
}
|
|
|
|
if (alphaTex.width != width || alphaTex.height != height)
|
|
{
|
|
DestroyAllCells();
|
|
}
|
|
}
|
|
|
|
// Rebuild all cells?
|
|
if (cells.Count == 0 && cellsXY > 0)
|
|
{
|
|
width = alphaTex.width;
|
|
height = alphaTex.height;
|
|
|
|
for (var i = 0; i < cellsXY; i++)
|
|
{
|
|
cells.Add(new Cell());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DestroyAllCells();
|
|
}
|
|
}
|
|
|
|
protected virtual void OnDestroy()
|
|
{
|
|
D2D_Helper.DestroyManaged(DestroyAllCells);
|
|
}
|
|
|
|
protected override void RebuildAll()
|
|
{
|
|
var destructible = D2D_Helper.GetComponentUpwards<D2D_Destructible>(transform);
|
|
|
|
if (destructible != null)
|
|
{
|
|
RebuildAllColliders(destructible.AlphaTex);
|
|
}
|
|
}
|
|
|
|
private void DestroyAllCells()
|
|
{
|
|
if (cells.Count > 0)
|
|
{
|
|
foreach (var cell in cells)
|
|
{
|
|
cell.Destroy();
|
|
}
|
|
|
|
cells.Clear();
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
protected override void SetHideFlags(HideFlags hideFlags)
|
|
{
|
|
foreach (var cell in cells)
|
|
{
|
|
foreach (var edgeCollider2D in cell.EdgeCollider2Ds)
|
|
{
|
|
if (edgeCollider2D != null)
|
|
{
|
|
edgeCollider2D.hideFlags = hideFlags;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
protected override void SetHideFlags(HideFlags hideFlags)
|
|
{
|
|
}
|
|
#endif
|
|
} |