SanAndreasUnity/Assets/Scripts/Behaviours/World/FocusPointManager.cs

155 lines
5.4 KiB
C#
Raw Normal View History

2021-09-08 14:26:11 +00:00
using System;
using System.Collections.Generic;
2021-09-08 18:27:30 +00:00
using SanAndreasUnity.Behaviours.WorldSystem;
2021-09-08 14:26:11 +00:00
using UnityEngine;
namespace SanAndreasUnity.Behaviours.World
{
[Serializable]
public struct FocusPointParameters
{
public bool hasRevealRadius;
public float revealRadius;
public float timeToKeepRevealingAfterRemoved;
public FocusPointParameters(bool hasRevealRadius, float revealRadius, float timeToKeepRevealingAfterRemoved)
{
this.hasRevealRadius = hasRevealRadius;
this.revealRadius = revealRadius;
this.timeToKeepRevealingAfterRemoved = timeToKeepRevealingAfterRemoved;
}
public static FocusPointParameters Default => new FocusPointParameters(true, 150f, 3f);
}
/// <summary>
/// Handles registration, unregistration, and updating of focus points for a world system.
/// </summary>
public class FocusPointManager<T>
{
2021-09-08 18:27:30 +00:00
private IWorldSystem<T> _worldSystem;
2021-09-08 14:26:11 +00:00
private float _defaultRevealRadius;
public struct FocusPointInfo
{
2021-09-08 18:27:30 +00:00
public WorldSystem.FocusPoint focusPoint;
2021-09-08 14:26:11 +00:00
public Transform transform;
public float timeToKeepRevealingAfterRemoved;
public float timeWhenRemoved;
public bool hasRevealRadius;
}
private List<FocusPointInfo> _focusPoints = new List<FocusPointInfo>();
public IReadOnlyList<FocusPointInfo> FocusPoints => _focusPoints;
private List<FocusPointInfo> _focusPointsToRemoveAfterTimeout = new List<FocusPointInfo>();
public FocusPointManager(
2021-09-08 18:27:30 +00:00
IWorldSystem<T> worldSystem,
2021-09-08 14:26:11 +00:00
float defaultRevealRadius)
{
_worldSystem = worldSystem;
_defaultRevealRadius = defaultRevealRadius;
}
public void RegisterFocusPoint(Transform tr, FocusPointParameters parameters)
{
if (!_focusPoints.Exists(f => f.transform == tr))
{
float revealRadius = parameters.hasRevealRadius ? parameters.revealRadius : _defaultRevealRadius;
2021-09-08 18:27:30 +00:00
var registeredFocusPoint = _worldSystem.RegisterFocusPoint(revealRadius, tr.position);
2021-09-08 14:26:11 +00:00
_focusPoints.Add(new FocusPointInfo
{
2021-09-08 18:27:30 +00:00
focusPoint = registeredFocusPoint,
2021-09-08 14:26:11 +00:00
transform = tr,
timeToKeepRevealingAfterRemoved = parameters.timeToKeepRevealingAfterRemoved,
hasRevealRadius = parameters.hasRevealRadius,
});
}
}
public void UnRegisterFocusPoint(Transform tr)
{
int index = _focusPoints.FindIndex(f => f.transform == tr);
if (index < 0)
return;
// maybe we could just set transform to null, so it gets removed during next update ?
var focusPoint = _focusPoints[index];
if (focusPoint.timeToKeepRevealingAfterRemoved > 0)
{
focusPoint.timeWhenRemoved = Time.time;
_focusPointsToRemoveAfterTimeout.Add(focusPoint);
_focusPoints.RemoveAt(index);
return;
}
2021-09-08 18:27:30 +00:00
_worldSystem.UnRegisterFocusPoint(focusPoint.focusPoint);
2021-09-08 14:26:11 +00:00
_focusPoints.RemoveAt(index);
}
public void Update()
{
float timeNow = Time.time;
UnityEngine.Profiling.Profiler.BeginSample("Update focus points");
this._focusPoints.RemoveAll(f =>
{
if (null == f.transform)
{
if (f.timeToKeepRevealingAfterRemoved > 0f)
{
f.timeWhenRemoved = timeNow;
_focusPointsToRemoveAfterTimeout.Add(f);
return true;
}
UnityEngine.Profiling.Profiler.BeginSample("WorldSystem.UnRegisterFocusPoint()");
2021-09-08 18:27:30 +00:00
_worldSystem.UnRegisterFocusPoint(f.focusPoint);
2021-09-08 14:26:11 +00:00
UnityEngine.Profiling.Profiler.EndSample();
return true;
}
2021-09-08 18:27:30 +00:00
_worldSystem.FocusPointChangedPosition(f.focusPoint, f.transform.position);
2021-09-08 14:26:11 +00:00
return false;
});
UnityEngine.Profiling.Profiler.EndSample();
bool hasElementToRemove = false;
_focusPointsToRemoveAfterTimeout.ForEach(_ =>
{
if (timeNow - _.timeWhenRemoved > _.timeToKeepRevealingAfterRemoved)
{
hasElementToRemove = true;
UnityEngine.Profiling.Profiler.BeginSample("WorldSystem.UnRegisterFocusPoint()");
2021-09-08 18:27:30 +00:00
_worldSystem.UnRegisterFocusPoint(_.focusPoint);
2021-09-08 14:26:11 +00:00
UnityEngine.Profiling.Profiler.EndSample();
}
});
if (hasElementToRemove)
_focusPointsToRemoveAfterTimeout.RemoveAll(_ => timeNow - _.timeWhenRemoved > _.timeToKeepRevealingAfterRemoved);
}
public void ChangeDefaultRevealRadius(float newDefaultRevealRadius)
{
_defaultRevealRadius = newDefaultRevealRadius;
for (int i = 0; i < _focusPoints.Count; i++)
{
var focusPoint = _focusPoints[i];
if (!focusPoint.hasRevealRadius)
{
2021-09-08 18:27:30 +00:00
_worldSystem.FocusPointChangedRadius(focusPoint.focusPoint, newDefaultRevealRadius);
2021-09-08 14:26:11 +00:00
}
}
}
}
}