Untitled
unknown
plain_text
10 months ago
6.5 kB
4
Indexable
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class DraggyRoad : MonoBehaviour
{
[SerializeField] private GameObject straightTemplate;
[SerializeField] private GameObject cornerTemplate;
[SerializeField] private float gridScale = 1.5f;
[SerializeField] private ToastManager toastManager;
[Header("UI Controls")]
[SerializeField] private Button upButton;
[SerializeField] private Button downButton;
[SerializeField] private Button leftButton;
[SerializeField] private Button rightButton;
[Header("Sound Effects")]
[SerializeField] private AudioClip roadPlaceSound;
[Header("Animation Settings")]
[SerializeField] private float placementDuration = 0.3f;
[SerializeField] private Ease placementEase = Ease.OutBack;
private AudioSource audioSource;
private bool soundEnabled = true;
private Vector3Int lastPosition;
private float lastAngle;
private GameObject lastPlacedSection;
private Dictionary<Vector3Int, GameObject> roadTiles = new();
private GameObject[] roadTilesLoop = new GameObject[30];
private int loopStoreIndex = 0;
private int loopRetrieveIndex = 0;
private int lastLoopStoreIndex = 0;
void Start()
{
audioSource = gameObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
soundEnabled = false;
InitializeRoad();
soundEnabled = true;
upButton.onClick.AddListener(() =>{PlaceRoad(Vector3Int.up, 90f);});
downButton.onClick.AddListener(() =>{PlaceRoad(Vector3Int.down, -90f);});
leftButton.onClick.AddListener(() =>{PlaceRoad(Vector3Int.left, 180f);});
rightButton.onClick.AddListener(() =>{PlaceRoad(Vector3Int.right, 0f);});
}
private void InitializeRoad()
{
Vector3Int startingPosition = new(-7, 0, 0);
Vector3 worldStartPosition = (Vector3)startingPosition * gridScale;
lastPlacedSection = Instantiate(straightTemplate, worldStartPosition, Quaternion.Euler(0, 0, 0));
roadTiles.Add(startingPosition, lastPlacedSection);
roadTilesLoop[0] = lastPlacedSection;
loopStoreIndex = 1;
loopRetrieveIndex = 0;
lastLoopStoreIndex = 0;
lastPosition = startingPosition;
lastAngle = 0;
for (int i = 0; i < 6; i++)
{
TryPlaceRoad(Vector3Int.right, straightTemplate, 0f);
}
}
private void PlaceRoad(Vector3Int direction, float angle)
{
TryPlaceRoad(direction, straightTemplate, angle);
}
void TryPlaceRoad(Vector3Int direction, GameObject template, float angle)
{
Vector3Int newPosition = lastPosition + direction;
Vector3 worldPosition = (Vector3)newPosition * gridScale;
if (CanPlaceRoad(newPosition) && IsWithinCameraBounds(worldPosition))
{
GameObject newRoad = Instantiate(template, worldPosition, Quaternion.Euler(0, 0, angle));
newRoad.transform.localScale = Vector3.zero;
newRoad.transform.DOScale(Vector3.one, placementDuration)
.SetEase(placementEase);
roadTiles[newPosition] = newRoad;
if (roadTilesLoop[loopStoreIndex] != null)
{
Destroy(roadTilesLoop[loopStoreIndex]);
}
roadTilesLoop[loopStoreIndex] = newRoad;
if (angle != lastAngle)
{
Vector3 cornerPosition = (Vector3)lastPosition * gridScale;
Destroy(lastPlacedSection);
GameObject cornerPiece = null;
switch (angle - lastAngle)
{
case 90:
case -270:
cornerPiece = Instantiate(cornerTemplate, cornerPosition, Quaternion.Euler(0, 0, lastAngle));
break;
case -90:
case 270:
cornerPiece = Instantiate(cornerTemplate, cornerPosition, Quaternion.Euler(0, 0, lastAngle + 90));
break;
}
if (cornerPiece != null)
{
lastPlacedSection = cornerPiece;
roadTiles[lastPosition] = cornerPiece;
roadTilesLoop[lastLoopStoreIndex] = cornerPiece;
}
}
lastLoopStoreIndex = loopStoreIndex;
loopStoreIndex = (loopStoreIndex + 1) % roadTilesLoop.Length;
lastAngle = angle;
lastPlacedSection = newRoad;
lastPosition += direction;
if (soundEnabled)
{
PlayRoadPlaceSound();
}
}
else
{
if (!IsWithinCameraBounds(worldPosition))
{
toastManager.ShowToast("Road out of bounds!");
}
else
{
toastManager.ShowToast("Cannot place road here!");
}
}
}
private void PlayRoadPlaceSound()
{
if (audioSource != null && roadPlaceSound != null)
{
audioSource.PlayOneShot(roadPlaceSound);
}
}
bool IsWithinCameraBounds(Vector3 position)
{
Camera mainCamera = Camera.main;
if (mainCamera == null) return false;
Vector3 viewportPoint = mainCamera.WorldToViewportPoint(position);
return viewportPoint.x >= 0 && viewportPoint.x <= 1 && viewportPoint.y >= 0 && viewportPoint.y <= 1;
}
bool CanPlaceRoad(Vector3Int position)
{
if (roadTiles.TryGetValue(position, out GameObject result) && result != null)
{
return false;
}
Vector3 worldPosition = (Vector3)position * gridScale;
Collider2D obstacle = Physics2D.OverlapPoint(worldPosition, LayerMask.GetMask("Obstacle"));
if (obstacle != null)
{
return false;
}
return true;
}
public GameObject GetNextSection()
{
if (loopRetrieveIndex == loopStoreIndex)
{
return null;
}
GameObject nextSection = roadTilesLoop[loopRetrieveIndex];
loopRetrieveIndex = (loopRetrieveIndex + 1) % roadTilesLoop.Length;
return nextSection;
}
}Editor is loading...
Leave a Comment