riversong code showcase

This commit is contained in:
Daniele Marotta
2026-05-21 15:52:18 +02:00
commit 4c9eea1c02
462 changed files with 23406 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Pool;
using Object = UnityEngine.Object;
using Random = UnityEngine.Random;
namespace DanieleMarotta.RiversongCodeShowcase
{
[Service(typeof(IRawResourceVisualizationCollection))]
public class RawResourceRenderingSystem : GameSystem, IInitializable, IDisposable, IRawResourceVisualizationCollection, IOnWorldGenerationCompletedCallback
{
private const int MaxCreatedPerUpdate = 16;
[InjectService]
private IScene _scene;
[InjectService]
private IGameDatabase _gameDatabase;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private World _world;
[InjectService]
private GameConfig _config;
private Dictionary<int, GameObject> _visualizationsById = new();
public RawResourceRenderingSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public UniTask InitializeAsync()
{
_signalBus.Subscribe<WorldGenerationCompletedSignal>(OnWorldGenerationCompleted);
_signalBus.Subscribe<CollectDeletedGameObjectsSignal>(OnCollectDeletedGameObjects);
_signalBus.Subscribe<RawResourcesRemovedSignal>(OnRawResourcesRemoved);
return UniTask.CompletedTask;
}
public void Dispose()
{
_signalBus.Unsubscribe<WorldGenerationCompletedSignal>(OnWorldGenerationCompleted);
_signalBus.Unsubscribe<CollectDeletedGameObjectsSignal>(OnCollectDeletedGameObjects);
_signalBus.Unsubscribe<RawResourcesRemovedSignal>(OnRawResourcesRemoved);
}
private void OnWorldGenerationCompleted(WorldGenerationCompletedSignal signal)
{
signal.Callbacks.Add(this);
}
public async UniTask OnWorldGenerationCompletedAsync(World world)
{
await CreateVisualizationsAsync();
}
private async UniTask CreateVisualizationsAsync()
{
var visualizationCount = 0;
foreach (var resourceNode in _world.RawResources)
{
var definition = _gameDatabase.WithId<ResourceNodeDefinition>(resourceNode.DefinitionId);
var rotation = definition.RandomRotation ? Quaternion.Euler(0, Random.Range(0, 360), 0) : resourceNode.Orientation.ToQuaternion();
var scale = Vector3.one * Random.Range(definition.ScaleRange.x, definition.ScaleRange.y);
GameObject prefab;
if (definition.Prefab.IsValid())
prefab = (GameObject)definition.Prefab.Asset;
else
prefab = await definition.Prefab.LoadAssetAsync<GameObject>();
var visualization = Object.Instantiate(prefab, _scene.SceneFolders.RawResources);
visualization.transform.SetPositionAndRotation(resourceNode.Position, rotation);
visualization.transform.localScale = Vector3.Scale(visualization.transform.localScale, scale);
_visualizationsById.Add(resourceNode.Id, visualization);
if (++visualizationCount % MaxCreatedPerUpdate == 0) await UniTask.NextFrame();
}
}
private void OnCollectDeletedGameObjects(CollectDeletedGameObjectsSignal signal)
{
if ((signal.Filter & DeletedGameObjectsFilter.RawResources) == 0) return;
using var resourceNodesScope = ListPool<(int, bool)>.Get(out var resourceNodeIds);
_world.RawResources.GetResourceNodes(signal.Rect, _config.GeneralSettings.BaseElevation, resourceNodeIds);
foreach (var (id, canBeDeleted) in resourceNodeIds)
{
if (!canBeDeleted) continue;
var visualization = _visualizationsById[id];
signal.GameObjects.Add(visualization.gameObject);
}
}
private void OnRawResourcesRemoved(RawResourcesRemovedSignal signal)
{
foreach (var resourceNode in signal.ResourceNodes)
{
if (!_visualizationsById.Remove(resourceNode.Id, out var visualization)) return;
_ = DestroyVisualizationAsync(visualization);
}
}
private async UniTask DestroyVisualizationAsync(GameObject visualization)
{
if (visualization.TryGetComponent<IDestroyRawResourceAnimation>(out var animation)) await animation.PlayAsync();
Object.Destroy(visualization);
}
public bool TryGetVisualization(int id, out GameObject visualization)
{
return _visualizationsById.TryGetValue(id, out visualization);
}
}
}