129 lines
4.4 KiB
C#
129 lines
4.4 KiB
C#
using UnityEngine;
|
|
using GatherAndDefend.LevelEditor;
|
|
using System.Collections;
|
|
using UnityEngine.Tilemaps;
|
|
using System.Threading.Tasks;
|
|
using System;
|
|
using GatherAndDefend.Events;
|
|
using static LevelManager;
|
|
/// <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(GatherAndDefend.LevelEditor.TileData tileData, Action tilePlacement, Func<bool> shouldKillTask);
|
|
public class LevelManagerScript : SingletonBehaviour<LevelManagerScript>
|
|
{
|
|
private Action updateAction = null;
|
|
public bool loadOnStart = false;
|
|
public Level firstLevel;
|
|
|
|
[SerializeField] private SpriteRenderer _worldBackgroundSpriteRenderer;
|
|
[SerializeField] private Sprite[] _worldBackgrounds;
|
|
|
|
async void Start()
|
|
{
|
|
//only when the level is loaded do we start updating
|
|
EventAggregator.Instance.GetEvent<LevelLoadedEvent>().Attach(Instance_LevelLoaded);
|
|
EventAggregator.Instance.GetEvent<ExitingLevelEvent>().Attach(KillLoading);
|
|
|
|
if (PlayerPrefs.GetInt(LoadingManager.LevelToLoad) >= 12)
|
|
{
|
|
_worldBackgroundSpriteRenderer.sprite = _worldBackgrounds[1];
|
|
}
|
|
|
|
if (loadOnStart && firstLevel)
|
|
{
|
|
await LevelManager.Instance.LoadLevel(firstLevel, PlacementAnimation);
|
|
}
|
|
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
EventAggregator.Instance.GetEvent<ExitingLevelEvent>().Detach(KillLoading);
|
|
updateAction = null;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
updateAction?.Invoke();
|
|
|
|
// Gala hack to win level instantly
|
|
if (Input.GetKeyDown(KeyCode.Alpha0))
|
|
{
|
|
EventAggregator.Instance.GetEvent<LastWaveCompletedEvent>().Invoke();
|
|
}
|
|
}
|
|
|
|
private void Instance_LevelLoaded(Level level)
|
|
{
|
|
//only when the level is loaded do we start updating
|
|
updateAction = LevelManager.Instance.UpdateLevel;
|
|
LevelManager.Instance.LevelTransform = transform;
|
|
}
|
|
|
|
/// <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(GatherAndDefend.LevelEditor.TileData tile, Action putTileOnTilemap, Func<bool> shouldKillTask)
|
|
{
|
|
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");
|
|
tilePlaceholder.transform.SetParent(Instance.transform);
|
|
var rend = tilePlaceholder.AddComponent<SpriteRenderer>();
|
|
rend.sortingOrder = 10;
|
|
rend.sortingLayerName = layer;
|
|
|
|
if (tile.Tile is LevelTile)
|
|
{
|
|
rend.sprite = (tile.Tile as LevelTile).Sprite;
|
|
}
|
|
else
|
|
{
|
|
rend.sprite = (tile.Tile as Tile).sprite;
|
|
}
|
|
|
|
//position the tile over the board (past the camera's FOV)
|
|
tilePlaceholder.transform.position = tile.Position + Vector3.up * Camera.main.orthographicSize * 2;
|
|
|
|
var delta = tilePlaceholder.transform.position - tile.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 - tile.Position;
|
|
var newSign = newDelta.y / Mathf.Abs(newDelta.y);
|
|
|
|
if (newSign != signY) break;
|
|
|
|
if (shouldKillTask())
|
|
{
|
|
return;
|
|
}
|
|
await Task.Yield();
|
|
}
|
|
|
|
//place the tile and destroy the placeholder
|
|
putTileOnTilemap.Invoke();
|
|
Destroy(tilePlaceholder);
|
|
}
|
|
void KillLoading()
|
|
{
|
|
LevelManager.Instance.KillLoading();
|
|
}
|
|
} |