99 lines
3.3 KiB
C#
99 lines
3.3 KiB
C#
using UnityEngine;
|
|
using GatherAndDefend.LevelEditor;
|
|
using System.Collections;
|
|
using UnityEngine.Tilemaps;
|
|
using System.Threading.Tasks;
|
|
using System;
|
|
|
|
/// <param name="position">The position the tile should be placed on</param>
|
|
/// <param name="tile">the tile we should place</param>
|
|
/// <param name="tilePlacement">the action of placing the tile on the tilemap</param>
|
|
/// <returns></returns>
|
|
public delegate Task PlacementAnimationHandler(Vector3 position, TileBase tile, Action tilePlacement);
|
|
public class LevelManagerScript : SingletonBehaviour<LevelManagerScript>
|
|
{
|
|
private Action updateAction = null;
|
|
public bool loadOnStart = false;
|
|
public Level firstLevel;
|
|
async void Start()
|
|
{
|
|
//only when the level is loaded do we start updating
|
|
LevelManager.Instance.LevelLoaded += Instance_LevelLoaded;
|
|
if (loadOnStart && firstLevel)
|
|
{
|
|
await LevelManager.Instance.LoadLevel(firstLevel, placementAnimation: PlacementAnimation);
|
|
}
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
updateAction = null;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
updateAction?.Invoke();
|
|
}
|
|
|
|
private void Instance_LevelLoaded(Level level)
|
|
{
|
|
//only when the level is loaded do we start updating
|
|
updateAction = LevelManager.Instance.UpdateLevel;
|
|
}
|
|
|
|
/// <summary>
|
|
/// the tile falls from the top of the screen, up to it's position on the tilemap
|
|
/// </summary>
|
|
/// <param name="position">where it should land</param>
|
|
/// <param name="tile">what the tile represents</param>
|
|
/// <param name="putTileOnTilemap">the action of actually placing the tile</param>
|
|
/// <returns></returns>
|
|
public static async Task PlacementAnimation(Vector3 position, TileBase tile, System.Action putTileOnTilemap)
|
|
{
|
|
const string layer = "Unit";
|
|
float speed = 0;
|
|
float acceleration = -9.81f;
|
|
|
|
//create the falling GameObject that will placehold for the tile
|
|
var tilePlaceholder = new GameObject("tile");
|
|
var rend = tilePlaceholder.AddComponent<SpriteRenderer>();
|
|
rend.sortingOrder = 10;
|
|
rend.sortingLayerName = layer;
|
|
|
|
if (tile is LevelTile)
|
|
{
|
|
rend.sprite = (tile as LevelTile).Sprite;
|
|
}
|
|
else
|
|
{
|
|
rend.sprite = (tile as Tile).sprite;
|
|
}
|
|
|
|
//position the tile over the board (past the camera's FOV)
|
|
tilePlaceholder.transform.position = position + Vector3.up * Camera.main.orthographicSize * 2;
|
|
|
|
var delta = tilePlaceholder.transform.position - position;
|
|
var direction = delta.normalized;
|
|
var signY = delta.y / Mathf.Abs(delta.y);
|
|
|
|
while (true)
|
|
{
|
|
//if the placeholder was destroyed, stop
|
|
if (!tilePlaceholder) break;
|
|
|
|
//make the placeholder fall and check if we went past the target position
|
|
speed += acceleration * Time.deltaTime;
|
|
tilePlaceholder.transform.position += speed * Time.deltaTime * direction;
|
|
var newDelta = tilePlaceholder.transform.position - position;
|
|
var newSign = newDelta.y / Mathf.Abs(newDelta.y);
|
|
|
|
if (newSign != signY) break;
|
|
|
|
await Task.Yield();
|
|
}
|
|
|
|
//place the tile and destroy the placeholder
|
|
putTileOnTilemap.Invoke();
|
|
Destroy(tilePlaceholder);
|
|
}
|
|
} |