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,126 @@
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Pool;
using Object = UnityEngine.Object;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class BuildToolPreview
{
private readonly GameConfig.UIConfig.BuildToolConfig _config;
private readonly ITileSpace _tileSpace;
private BuildingDefinition _building;
private Vector3 _tilt;
private Vector3 _tiltVelocity;
private float _yaw;
private float _yawVelocity;
public BuildToolPreview(GameConfig.UIConfig.BuildToolConfig config, ITileSpace tileSpace)
{
_config = config;
_tileSpace = tileSpace;
}
public GameObject PreviewObject { get; private set; }
public bool IsVisible => PreviewObject && PreviewObject.activeSelf;
public float3 Position => PreviewObject ? PreviewObject.transform.position : Vector3.zero;
public void PrepareForBuilding(BuildingDefinition building)
{
_building = building;
}
public void Release()
{
ClearPreviewObject();
}
public void Update(bool isValid, Vector3 pointer, Directions orientation)
{
if (!PreviewObject)
{
if (_building.Visualization.IsDone)
CreatePreviewObject();
else
return;
}
var snap = !PreviewObject.activeSelf && isValid;
if (snap)
{
_tilt = Vector3.zero;
_tiltVelocity = Vector3.zero;
}
PreviewObject.SetActive(isValid);
if (!isValid) return;
var rect = TileMath.GetBuildingRect(_tileSpace.WorldToTile(pointer), orientation, _building.Width, _building.Height);
var position = _tileSpace.GetRectWorldCenter(rect);
position.y += _config.Height;
var dt = Time.unscaledDeltaTime;
position = snap ? position : Vector3.Lerp(PreviewObject.transform.position, position, _config.LerpFactor * dt);
var yaw = orientation.ToQuaternion().eulerAngles.y;
_yaw = snap ? yaw : Mathf.SmoothDampAngle(_yaw, yaw, ref _yawVelocity, 0.1f, Mathf.Infinity, dt);
var rotation = Quaternion.Euler(0, _yaw, 0);
if (!snap) rotation = SimulateSpring(position, dt) * rotation;
PreviewObject.transform.SetPositionAndRotation(position, rotation);
}
private Quaternion SimulateSpring(Vector3 targetPosition, float dt)
{
var positionDelta = targetPosition - PreviewObject.transform.position;
_tilt -= positionDelta * _config.ImpulseScale;
_tilt = _tilt.normalized * Mathf.Min(_tilt.magnitude, _config.MaxTilt);
_tiltVelocity -= _tilt * (_config.Elasticity * dt);
_tiltVelocity *= Mathf.Pow(1 - _config.Damping, dt);
_tilt += _tiltVelocity * dt;
if (_tilt.sqrMagnitude > 0.001f)
{
var axis = Vector3.Cross(Vector3.down, _tilt.normalized);
var angle = _tilt.magnitude / _config.MaxTilt * _config.MaxTiltAngle;
return Quaternion.AngleAxis(angle, axis);
}
return Quaternion.identity;
}
private void CreatePreviewObject()
{
PreviewObject = Object.Instantiate((GameObject)_building.Visualization.Asset);
PreviewObject.SetLayerRecursively<Renderer>(GameObjectLayers.IgnoreAoE);
using var _ = ListPool<HideOnBuildingPreview>.Get(out var hide);
PreviewObject.GetComponentsInChildren(hide);
foreach (var obj in hide) obj.gameObject.SetActive(false);
// Start the preview in the disabled state, causes the position to be snapped when enabled
PreviewObject.SetActive(false);
}
public void ClearPreviewObject()
{
if (PreviewObject)
{
Object.Destroy(PreviewObject);
PreviewObject = null;
}
}
}
}