using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
|
[RequireComponent(typeof(SpriteRenderer))]
|
public class Tiling : MonoBehaviour
|
{
|
[System.Serializable]
|
public class HeightSpritePair
|
{
|
public float minHeight;
|
public float maxHeight;
|
public Sprite sprite;
|
}
|
|
public int offsetX = 2;
|
public int offsetY = 2;
|
public HeightSpritePair[] heightSprites;
|
|
public bool hasRightBuddy = false;
|
public bool hasLeftBuddy = false;
|
public bool hasTopBuddy = false;
|
public bool hasBottomBuddy = false;
|
|
public bool reverseScale = false;
|
|
private float spriteWidth = 0f;
|
private float spriteHeight = 0f;
|
private Camera cam;
|
private Transform myTransform;
|
private SpriteRenderer spriteRenderer;
|
|
private void Awake()
|
{
|
cam = Camera.main;
|
myTransform = transform;
|
spriteRenderer = GetComponent<SpriteRenderer>();
|
}
|
|
void Start()
|
{
|
UpdateSpriteForHeight();
|
spriteWidth = spriteRenderer.sprite.bounds.size.x;
|
spriteHeight = spriteRenderer.sprite.bounds.size.y;
|
}
|
|
void Update()
|
{
|
if (CheckOffscreenAndDestroy()) return; // Return early if destroyed
|
CheckHorizontalTiling();
|
CheckVerticalTiling();
|
}
|
|
private void UpdateSpriteForHeight()
|
{
|
if (heightSprites == null || heightSprites.Length == 0) return;
|
|
float worldY = transform.position.y;
|
Sprite oldSprite = spriteRenderer.sprite;
|
|
foreach (HeightSpritePair pair in heightSprites)
|
{
|
if (pair.sprite == null) continue; // Skip invalid sprites
|
|
if ((pair.minHeight == 0 && pair.maxHeight == 0) ||
|
(worldY >= pair.minHeight && worldY <= pair.maxHeight))
|
{
|
if (oldSprite != pair.sprite)
|
{
|
spriteRenderer.sprite = pair.sprite;
|
// Update sprite dimensions if sprite changed
|
spriteWidth = spriteRenderer.sprite.bounds.size.x;
|
spriteHeight = spriteRenderer.sprite.bounds.size.y;
|
}
|
break;
|
}
|
}
|
}
|
|
private void CheckHorizontalTiling()
|
{
|
if (!hasLeftBuddy || !hasRightBuddy)
|
{
|
float camHorizontalExtend = cam.orthographicSize * Screen.width / Screen.height;
|
float edgeVisiblePositionRight = (transform.position.x + spriteWidth / 2) - camHorizontalExtend;
|
float edgeVisiblePositionLeft = (transform.position.x - spriteWidth / 2) + camHorizontalExtend;
|
|
if (cam.transform.position.x >= edgeVisiblePositionRight - offsetX && !hasRightBuddy)
|
{
|
MakeNewBuddy(1, 0);
|
hasRightBuddy = true;
|
}
|
else if (cam.transform.position.x <= edgeVisiblePositionLeft + offsetX && !hasLeftBuddy)
|
{
|
MakeNewBuddy(-1, 0);
|
hasLeftBuddy = true;
|
}
|
}
|
}
|
|
private void CheckVerticalTiling()
|
{
|
if (!hasTopBuddy || !hasBottomBuddy)
|
{
|
float camVerticalExtend = cam.orthographicSize;
|
float edgeVisiblePositionTop = (transform.position.y + spriteHeight / 2) - camVerticalExtend;
|
float edgeVisiblePositionBottom = (transform.position.y - spriteHeight / 2) + camVerticalExtend;
|
|
if (cam.transform.position.y >= edgeVisiblePositionTop - offsetY && !hasTopBuddy)
|
{
|
MakeNewBuddy(0, 1);
|
hasTopBuddy = true;
|
}
|
else if (cam.transform.position.y <= edgeVisiblePositionBottom + offsetY && !hasBottomBuddy)
|
{
|
MakeNewBuddy(0, -1);
|
hasBottomBuddy = true;
|
}
|
}
|
}
|
|
private void MakeNewBuddy(int rightOrLeft, int topOrBottom)
|
{
|
Vector3 newPosition = new Vector3(
|
myTransform.position.x + spriteWidth * rightOrLeft,
|
myTransform.position.y + spriteHeight * topOrBottom,
|
myTransform.position.z
|
);
|
|
Transform newBuddy = Instantiate(myTransform, newPosition, myTransform.rotation);
|
Tiling buddyTiling = newBuddy.GetComponent<Tiling>();
|
|
if (reverseScale)
|
{
|
newBuddy.localScale = new Vector3(
|
rightOrLeft != 0 ? newBuddy.localScale.x * -1 : newBuddy.localScale.x,
|
topOrBottom != 0 ? newBuddy.localScale.y * -1 : newBuddy.localScale.y,
|
newBuddy.localScale.z
|
);
|
}
|
|
newBuddy.parent = myTransform.parent;
|
newBuddy.name = myTransform.name;
|
|
if (rightOrLeft > 0) buddyTiling.hasLeftBuddy = true;
|
else if (rightOrLeft < 0) buddyTiling.hasRightBuddy = true;
|
if (topOrBottom > 0) buddyTiling.hasBottomBuddy = true;
|
else if (topOrBottom < 0) buddyTiling.hasTopBuddy = true;
|
|
buddyTiling.UpdateSpriteForHeight();
|
}
|
|
private bool CheckOffscreenAndDestroy()
|
{
|
Vector3 viewportPosition = cam.WorldToViewportPoint(transform.position);
|
float buffer = 1.5f;
|
|
if (viewportPosition.x < -buffer || viewportPosition.x > 1 + buffer ||
|
viewportPosition.y < -buffer || viewportPosition.y > 1 + buffer)
|
{
|
NotifyNeighbors();
|
Destroy(gameObject);
|
return true;
|
}
|
return false;
|
}
|
private void NotifyNeighbors()
|
{
|
// Use a slightly smaller size than the sprite to ensure we only hit immediate neighbors
|
Vector2 checkSize = new Vector2(spriteWidth * 0.9f, spriteHeight * 0.9f);
|
Vector2 position = transform.position;
|
ContactFilter2D filter = new ContactFilter2D().NoFilter();
|
Collider2D[] results = new Collider2D[1];
|
|
// Check each direction using OverlapBox
|
// Right neighbor
|
if (Physics2D.OverlapBox(position + new Vector2(spriteWidth, 0),
|
checkSize, 0f,
|
filter, results) > 0)
|
{
|
Tiling rightTile = results[0].GetComponent<Tiling>();
|
if (rightTile != null) rightTile.hasLeftBuddy = false;
|
}
|
|
// Left neighbor
|
if (Physics2D.OverlapBox(position + new Vector2(-spriteWidth, 0),
|
checkSize, 0f,
|
filter, results) > 0)
|
{
|
Tiling leftTile = results[0].GetComponent<Tiling>();
|
if (leftTile != null) leftTile.hasRightBuddy = false;
|
}
|
|
// Top neighbor
|
if (Physics2D.OverlapBox(position + new Vector2(0, spriteHeight),
|
checkSize, 0f,
|
filter, results) > 0)
|
{
|
Tiling topTile = results[0].GetComponent<Tiling>();
|
if (topTile != null) topTile.hasBottomBuddy = false;
|
}
|
|
// Bottom neighbor
|
if (Physics2D.OverlapBox(position + new Vector2(0, -spriteHeight),
|
checkSize, 0f,
|
filter, results) > 0)
|
{
|
Tiling bottomTile = results[0].GetComponent<Tiling>();
|
if (bottomTile != null) bottomTile.hasTopBuddy = false;
|
}
|
}
|
//private void OnDrawGizmos()
|
//{
|
// if (!Application.isPlaying) return;
|
|
// Vector2 checkSize = new Vector2(spriteWidth * 0.9f, spriteHeight * 0.9f);
|
// Gizmos.color = Color.yellow;
|
|
// // Draw detection boxes for each direction
|
// Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(spriteWidth, 0), checkSize);
|
// Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(-spriteWidth, 0), checkSize);
|
// Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(0, spriteHeight), checkSize);
|
// Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(0, -spriteHeight), checkSize);
|
//}
|
}
|