100 lines
3.2 KiB
C#
100 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Cysharp.Threading.Tasks;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
public class RoadVisualizationManager : GameSystem, IInitializable, IDisposable
|
|
{
|
|
[InjectService]
|
|
private GameConfig _config;
|
|
|
|
[InjectService]
|
|
private IScene _scene;
|
|
|
|
[InjectService]
|
|
private ISignalBus _signalBus;
|
|
|
|
[InjectService]
|
|
private ITileSpace _tileSpace;
|
|
|
|
[InjectService]
|
|
private World _world;
|
|
|
|
private readonly List<GameObject> _prefabs = new();
|
|
|
|
private readonly Dictionary<int2, GameObject> _visualizations = new();
|
|
|
|
private GameObject _placementVfxPrefab;
|
|
|
|
public RoadVisualizationManager(IServiceLocator serviceLocator) : base(serviceLocator)
|
|
{
|
|
}
|
|
|
|
public async UniTask InitializeAsync()
|
|
{
|
|
var tilePrefabTasks = _config.Roads.Tiles.Select(tilePrefabRef => tilePrefabRef.LoadAssetAsync().ToUniTask()).ToArray();
|
|
var placementVfxTask = _config.Roads.PlacementVfxPrefab.LoadAssetAsync().ToUniTask();
|
|
|
|
var tilePrefabs = await UniTask.WhenAll(tilePrefabTasks);
|
|
_prefabs.AddRange(tilePrefabs);
|
|
_placementVfxPrefab = await placementVfxTask;
|
|
|
|
_signalBus.Subscribe<RoadTileUpdatedSignal>(OnRoadTileChanged);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
foreach (var tilePrefabRef in _config.Roads.Tiles) tilePrefabRef.ReleaseAsset();
|
|
|
|
_config.Roads.PlacementVfxPrefab.ReleaseAsset();
|
|
|
|
_signalBus.Unsubscribe<RoadTileUpdatedSignal>(OnRoadTileChanged);
|
|
}
|
|
|
|
private void OnRoadTileChanged(RoadTileUpdatedSignal signal)
|
|
{
|
|
var tile = signal.Tile;
|
|
|
|
UpdateTile(tile);
|
|
if (tile.x > 0) UpdateTile(tile + new int2(-1, 0));
|
|
if (tile.x < _world.Size.x - 1) UpdateTile(tile + new int2(1, 0));
|
|
if (tile.y > 0) UpdateTile(tile + new int2(0, -1));
|
|
if (tile.y < _world.Size.y - 1) UpdateTile(tile + new int2(0, 1));
|
|
|
|
if (signal.RoadTileAdded) SpawnPlacementVfx(tile);
|
|
}
|
|
|
|
private void UpdateTile(int2 tile)
|
|
{
|
|
if (_visualizations.TryGetValue(tile, out var visualization))
|
|
{
|
|
Object.Destroy(visualization);
|
|
_visualizations.Remove(tile);
|
|
}
|
|
|
|
if (!_world.RoadNetwork.IsRoadTile(tile)) return;
|
|
|
|
visualization = Object.Instantiate(GetRoadTilePrefab(tile), _scene.SceneFolders.RoadTiles);
|
|
visualization.transform.position = _tileSpace.TileToWorld(tile) + new Vector3(0, 0.001f, 0);
|
|
|
|
_visualizations.Add(tile, visualization);
|
|
}
|
|
|
|
private GameObject GetRoadTilePrefab(int2 tile)
|
|
{
|
|
var connectivity = _world.RoadNetwork.GetConnectivity(tile);
|
|
return _prefabs[(int)connectivity];
|
|
}
|
|
|
|
private void SpawnPlacementVfx(int2 tile)
|
|
{
|
|
var position = _tileSpace.TileToWorld(tile);
|
|
Object.Instantiate(_placementVfxPrefab, position, Quaternion.identity);
|
|
}
|
|
}
|
|
} |