mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Add streaming warp volume, make base volume sectored (#787)
## Improvements - Singularities will now pre-load assets for their destination when the player/probe is nearby (if the destination is a vanilla planet)
This commit is contained in:
commit
091f34bdf1
@ -11,6 +11,8 @@ using NewHorizons.Builder.Props;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using NewHorizons.Utility.OuterWilds;
|
||||
using NewHorizons.External.SerializableData;
|
||||
using NewHorizons.Builder.Volumes;
|
||||
using System;
|
||||
|
||||
namespace NewHorizons.Builder.Body
|
||||
{
|
||||
@ -109,31 +111,52 @@ namespace NewHorizons.Builder.Body
|
||||
{
|
||||
foreach (var pair in _pairsToLink)
|
||||
{
|
||||
var (blackHoleID, whiteHoleID) = pair;
|
||||
if (!_singularitiesByID.TryGetValue(blackHoleID, out GameObject blackHole))
|
||||
try
|
||||
{
|
||||
NHLogger.LogWarning($"Black hole [{blackHoleID}] is missing.");
|
||||
continue;
|
||||
var (blackHoleID, whiteHoleID) = pair;
|
||||
if (!_singularitiesByID.TryGetValue(blackHoleID, out GameObject blackHole))
|
||||
{
|
||||
NHLogger.LogWarning($"Black hole [{blackHoleID}] is missing.");
|
||||
continue;
|
||||
}
|
||||
if (!_singularitiesByID.TryGetValue(whiteHoleID, out GameObject whiteHole))
|
||||
{
|
||||
NHLogger.LogWarning($"White hole [{whiteHoleID}] is missing.");
|
||||
continue;
|
||||
}
|
||||
var whiteHoleVolume = whiteHole.GetComponentInChildren<WhiteHoleVolume>();
|
||||
var blackHoleVolume = blackHole.GetComponentInChildren<BlackHoleVolume>();
|
||||
if (whiteHoleVolume == null || blackHoleVolume == null)
|
||||
{
|
||||
NHLogger.LogWarning($"Singularities [{blackHoleID}] and [{whiteHoleID}] do not have compatible polarities.");
|
||||
continue;
|
||||
}
|
||||
if (blackHoleVolume._whiteHole != null && blackHoleVolume._whiteHole != whiteHoleVolume)
|
||||
{
|
||||
NHLogger.LogWarning($"Black hole [{blackHoleID}] has already been linked!");
|
||||
continue;
|
||||
}
|
||||
NHLogger.LogVerbose($"Pairing singularities [{blackHoleID}], [{whiteHoleID}]");
|
||||
blackHoleVolume._whiteHole = whiteHoleVolume;
|
||||
|
||||
// If warping to a vanilla planet, we add a streaming volume to pre-load it
|
||||
var streamingGroup = whiteHoleVolume.GetAttachedOWRigidbody().GetComponentInChildren<StreamingGroup>();
|
||||
if (streamingGroup != null)
|
||||
{
|
||||
var sphereCollider = blackHoleVolume.GetComponent<SphereCollider>();
|
||||
// Shouldn't ever be null but doesn't hurt ig
|
||||
var loadRadius = sphereCollider == null ? 100f : sphereCollider.radius + 50f;
|
||||
var streamingVolume = VolumeBuilder.Make<StreamingWarpVolume>(blackHoleVolume.GetAttachedOWRigidbody().gameObject, blackHoleVolume.GetComponentInParent<Sector>(),
|
||||
new External.Modules.Volumes.VolumeInfos.VolumeInfo() { radius = loadRadius });
|
||||
streamingVolume.streamingGroup = streamingGroup;
|
||||
streamingVolume.transform.parent = blackHoleVolume.transform;
|
||||
streamingVolume.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
}
|
||||
if (!_singularitiesByID.TryGetValue(whiteHoleID, out GameObject whiteHole))
|
||||
catch (Exception e)
|
||||
{
|
||||
NHLogger.LogWarning($"White hole [{whiteHoleID}] is missing.");
|
||||
continue;
|
||||
NHLogger.LogError($"Failed to pair singularities {e}");
|
||||
}
|
||||
var whiteHoleVolume = whiteHole.GetComponentInChildren<WhiteHoleVolume>();
|
||||
var blackHoleVolume = blackHole.GetComponentInChildren<BlackHoleVolume>();
|
||||
if (whiteHoleVolume == null || blackHoleVolume == null)
|
||||
{
|
||||
NHLogger.LogWarning($"Singularities [{blackHoleID}] and [{whiteHoleID}] do not have compatible polarities.");
|
||||
continue;
|
||||
}
|
||||
if (blackHoleVolume._whiteHole != null && blackHoleVolume._whiteHole != whiteHoleVolume)
|
||||
{
|
||||
NHLogger.LogWarning($"Black hole [{blackHoleID}] has already been linked!");
|
||||
continue;
|
||||
}
|
||||
NHLogger.LogVerbose($"Pairing singularities [{blackHoleID}], [{whiteHoleID}]");
|
||||
blackHoleVolume._whiteHole = whiteHoleVolume;
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +190,7 @@ namespace NewHorizons.Builder.Body
|
||||
|
||||
OWAudioSource oneShotOWAudioSource = null;
|
||||
|
||||
var singularityAmbience = Object.Instantiate(_blackHoleAmbience, singularity.transform);
|
||||
var singularityAmbience = GameObject.Instantiate(_blackHoleAmbience, singularity.transform);
|
||||
singularityAmbience.name = polarity ? "BlackHoleAmbience" : "WhiteHoleAmbience";
|
||||
singularityAmbience.SetActive(true);
|
||||
singularityAmbience.GetComponent<SectorAudioGroup>().SetSector(sector);
|
||||
@ -214,7 +237,7 @@ namespace NewHorizons.Builder.Body
|
||||
}
|
||||
else
|
||||
{
|
||||
var blackHoleOneShot = Object.Instantiate(_blackHoleEmissionOneShot, singularity.transform);
|
||||
var blackHoleOneShot = GameObject.Instantiate(_blackHoleEmissionOneShot, singularity.transform);
|
||||
blackHoleOneShot.name = "BlackHoleEmissionOneShot";
|
||||
blackHoleOneShot.SetActive(true);
|
||||
oneShotOWAudioSource = blackHoleOneShot.GetComponent<OWAudioSource>();
|
||||
@ -223,7 +246,7 @@ namespace NewHorizons.Builder.Body
|
||||
oneShotAudioSource.minDistance = horizon;
|
||||
if (sizeController != null) sizeController.oneShotAudioSource = oneShotAudioSource;
|
||||
|
||||
var blackHoleVolume = Object.Instantiate(_blackHoleVolume, singularity.transform);
|
||||
var blackHoleVolume = GameObject.Instantiate(_blackHoleVolume, singularity.transform);
|
||||
blackHoleVolume.name = "BlackHoleVolume";
|
||||
|
||||
// Scale vanish effect to black hole size
|
||||
@ -249,7 +272,7 @@ namespace NewHorizons.Builder.Body
|
||||
{
|
||||
foreach (var renderer in blackHoleVolume.GetComponentsInChildren<ParticleSystemRenderer>(true))
|
||||
{
|
||||
Object.Destroy(renderer);
|
||||
GameObject.Destroy(renderer);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -257,7 +280,7 @@ namespace NewHorizons.Builder.Body
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject whiteHoleVolumeGO = Object.Instantiate(_whiteHoleVolume);
|
||||
GameObject whiteHoleVolumeGO = GameObject.Instantiate(_whiteHoleVolume);
|
||||
whiteHoleVolumeGO.transform.parent = singularity.transform;
|
||||
whiteHoleVolumeGO.transform.localPosition = Vector3.zero;
|
||||
whiteHoleVolumeGO.transform.localScale = Vector3.one;
|
||||
|
||||
@ -3,22 +3,27 @@ using UnityEngine;
|
||||
namespace NewHorizons.Components.Volumes
|
||||
{
|
||||
[RequireComponent(typeof(OWTriggerVolume))]
|
||||
public abstract class BaseVolume : MonoBehaviour
|
||||
public abstract class BaseVolume : SectoredMonoBehaviour
|
||||
{
|
||||
private OWTriggerVolume _triggerVolume;
|
||||
|
||||
public virtual void Awake()
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_triggerVolume = this.GetRequiredComponent<OWTriggerVolume>();
|
||||
_triggerVolume.OnEntry += OnTriggerVolumeEntry;
|
||||
_triggerVolume.OnExit += OnTriggerVolumeExit;
|
||||
}
|
||||
|
||||
public virtual void OnDestroy()
|
||||
public override void OnDestroy()
|
||||
{
|
||||
if (_triggerVolume == null) return;
|
||||
_triggerVolume.OnEntry -= OnTriggerVolumeEntry;
|
||||
_triggerVolume.OnExit -= OnTriggerVolumeExit;
|
||||
base.OnDestroy();
|
||||
|
||||
if (_triggerVolume != null)
|
||||
{
|
||||
_triggerVolume.OnEntry -= OnTriggerVolumeEntry;
|
||||
_triggerVolume.OnExit -= OnTriggerVolumeExit;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void OnTriggerVolumeEntry(GameObject hitObj);
|
||||
|
||||
110
NewHorizons/Components/Volumes/StreamingWarpVolume.cs
Normal file
110
NewHorizons/Components/Volumes/StreamingWarpVolume.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Components.Volumes
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently only relevant for Vanilla planets, which actually have streaming groups
|
||||
/// </summary>
|
||||
internal class StreamingWarpVolume : BaseVolume
|
||||
{
|
||||
public StreamingGroup streamingGroup;
|
||||
private bool _probeInVolume;
|
||||
private bool _playerInVolume;
|
||||
private bool _preloadingRequiredAssets;
|
||||
private bool _preloadingGeneralAssets;
|
||||
|
||||
private SurveyorProbe _probe;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_probe = Locator.GetProbe();
|
||||
base.enabled = false;
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
{
|
||||
bool probeActive = _probe.IsLaunched() && !_probe.IsAnchored();
|
||||
|
||||
bool shouldBeLoadingRequiredAssets = _playerInVolume || (_probeInVolume && probeActive);
|
||||
bool shouldBeLoadingGeneralAssets = _playerInVolume;
|
||||
|
||||
UpdatePreloadingState(shouldBeLoadingRequiredAssets, shouldBeLoadingGeneralAssets);
|
||||
}
|
||||
|
||||
private void UpdatePreloadingState(bool shouldBeLoadingRequiredAssets, bool shouldBeLoadingGeneralAssets)
|
||||
{
|
||||
if (!this._preloadingRequiredAssets && shouldBeLoadingRequiredAssets)
|
||||
{
|
||||
this.streamingGroup.RequestRequiredAssets(0);
|
||||
this._preloadingRequiredAssets = true;
|
||||
}
|
||||
else if (this._preloadingRequiredAssets && !shouldBeLoadingRequiredAssets)
|
||||
{
|
||||
this.streamingGroup.ReleaseRequiredAssets();
|
||||
this._preloadingRequiredAssets = false;
|
||||
}
|
||||
if (!this._preloadingGeneralAssets && shouldBeLoadingGeneralAssets)
|
||||
{
|
||||
this.streamingGroup.RequestGeneralAssets(0);
|
||||
this._preloadingGeneralAssets = true;
|
||||
return;
|
||||
}
|
||||
if (this._preloadingGeneralAssets && !shouldBeLoadingGeneralAssets)
|
||||
{
|
||||
this.streamingGroup.ReleaseGeneralAssets();
|
||||
this._preloadingGeneralAssets = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSectorOccupantsUpdated()
|
||||
{
|
||||
if (this._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe))
|
||||
{
|
||||
if (StreamingManager.isStreamingEnabled && this.streamingGroup != null)
|
||||
{
|
||||
base.enabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.UpdatePreloadingState(false, false);
|
||||
base.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTriggerVolumeEntry(GameObject hitObj)
|
||||
{
|
||||
OWRigidbody attachedOWRigidbody = hitObj.GetAttachedOWRigidbody(false);
|
||||
if (attachedOWRigidbody != null)
|
||||
{
|
||||
if (attachedOWRigidbody.CompareTag("Player"))
|
||||
{
|
||||
this._playerInVolume = true;
|
||||
return;
|
||||
}
|
||||
if (attachedOWRigidbody.CompareTag("Probe"))
|
||||
{
|
||||
this._probeInVolume = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTriggerVolumeExit(GameObject hitObj)
|
||||
{
|
||||
OWRigidbody attachedOWRigidbody = hitObj.GetAttachedOWRigidbody(false);
|
||||
if (attachedOWRigidbody != null)
|
||||
{
|
||||
if (attachedOWRigidbody.CompareTag("Player"))
|
||||
{
|
||||
this._playerInVolume = false;
|
||||
return;
|
||||
}
|
||||
if (attachedOWRigidbody.CompareTag("Probe"))
|
||||
{
|
||||
this._probeInVolume = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user