1
using System
.Collections
.Generic
;
3 using UnityEngine
.Tilemaps
;
5 public class CrumblingTerrain
: MonoBehaviour
7 private class TileToRemove
9 private static Dictionary
<Vector3Int
, bool> s_tilesRemoved
= new Dictionary
<Vector3Int
, bool>();
11 public TileBase m_tile
;
12 public Vector3Int m_position
;
13 public float m_lifeTimer
;
14 public float m_flashTimer
;
16 public TileToRemove(TileBase tile
, Vector3Int position
)
18 s_tilesRemoved
.Add(position
, true);
21 m_position
= position
;
26 public void Update(float deltaTime
)
28 UpdateTimers(deltaTime
);
31 void UpdateTimers(float deltaTime
)
33 m_lifeTimer
+= deltaTime
;
34 m_flashTimer
+= deltaTime
;
37 public static void RemoveReference(Vector3Int position
)
39 s_tilesRemoved
.Remove(position
);
42 public static bool IsInList(List
<TileToRemove
> list
, Vector3Int position
)
44 foreach (TileToRemove tile
in list
)
46 if (tile
.m_position
== position
)
56 private Tilemap m_tilemap
;
57 private List
<TileToRemove
> m_tilesToRemove
= new List
<TileToRemove
>();
59 public Color m_tileFlashColor
= Color
.red
;
60 public float m_tileLifeTime
= 1.0f
;
62 private float m_tileFlashInterval
;
66 m_tilemap
= GetComponent
<Tilemap
>();
68 m_tileFlashInterval
= m_tileLifeTime
/ 6.0f
;
73 foreach (TileToRemove tile
in m_tilesToRemove
.ToArray())
75 tile
.Update(Time
.deltaTime
);
81 void Crumble(TileToRemove tile
)
83 if (tile
.m_lifeTimer
>= m_tileLifeTime
)
85 m_tilemap
.SetTile(tile
.m_position
, null);
86 m_tilesToRemove
.Remove(tile
);
87 TileToRemove
.RemoveReference(tile
.m_position
);
91 void Flash(TileToRemove tile
)
93 if (tile
.m_flashTimer
>= m_tileFlashInterval
)
95 tile
.m_flashTimer
= 0.0f
;
96 Color currentColor
= m_tilemap
.GetColor(tile
.m_position
);
97 m_tilemap
.SetColor(tile
.m_position
, (currentColor
== Color
.white
? m_tileFlashColor
: Color
.white
));
101 private void OnCollisionStay2D(Collision2D collision
)
103 if (collision
.gameObject
.CompareTag("YarnPhysics"))
105 ContactPoint2D
[] contact
= new ContactPoint2D
[1];
106 GetComponent
<CompositeCollider2D
>().GetContacts(contact
);
108 // Totally a hack; because it's very hard to get a world-to-grid-cell conversion,
109 // the contact position is artificially incremented to find one viable location.
110 // This also prevents the yarn from getting stuck.
111 Vector2
[] possibleContacts
= new Vector2
[9]
114 contact
[0].point
+ Vector2
.up
,
115 contact
[0].point
+ Vector2
.down
,
116 contact
[0].point
+ Vector2
.left
,
117 contact
[0].point
+ Vector2
.right
,
118 contact
[0].point
+ Vector2
.up
+ Vector2
.left
,
119 contact
[0].point
+ Vector2
.up
+ Vector2
.right
,
120 contact
[0].point
+ Vector2
.down
+ Vector2
.left
,
121 contact
[0].point
+ Vector2
.down
+ Vector2
.right
,
124 TileBase tile
= null;
125 Vector3Int tilePosition
= Vector3Int
.zero
;
127 for (uint i
= 0; i
!= possibleContacts
.Length
; ++i
)
129 tilePosition
= m_tilemap
.WorldToCell(possibleContacts
[i
]);
131 if ((tile
= m_tilemap
.GetTile(tilePosition
)) != null)
137 if (tile
!= null && !TileToRemove
.IsInList(m_tilesToRemove
, tilePosition
))
139 m_tilesToRemove
.Add(new TileToRemove(tile
, tilePosition
));