Files
ADOFAIRenderer/Patch/Game/scrPortalParticlesPatch.cs
T
2026-10-15 16:17:13 +09:00

44 lines
1.9 KiB
C#

using ADOFAIRenderer.Core;
using HarmonyLib;
using UnityEngine;
namespace ADOFAIRenderer.Patch.Game;
/// <summary>
/// Makes the end portal particle systems run on scaled game time during a render.
/// <para>
/// Patched member: <c>scrPortalParticles.Start()</c> (the animated portal spawned by <c>scrFloor.SpawnPortalParticles</c>;
/// Start pre-simulates its particle system for 1 second and plays it).
/// </para>
/// <para>
/// Active from stage Load. RenderManager sets <c>Time.captureDeltaTime</c> to 1 / RenderFPS, which advances scaled time by a
/// fixed step per frame; unscaled time is not affected by captureDeltaTime and follows real time. A particle system with
/// <c>main.useUnscaledTime</c> would therefore play at the real (slower or faster) frame rate of the offline render, so the
/// postfix sets it to false on every particle system under the portal (including inactive children).
/// Reference: https://docs.unity3d.com/ScriptReference/Time-captureDeltaTime.html
/// </para>
/// </summary>
[HarmonyPatch(typeof(scrPortalParticles))]
// ReSharper disable once InconsistentNaming
public static class scrPortalParticlesPatch
{
/// <summary>Postfix of <c>scrPortalParticles.Start</c>: sets <c>useUnscaledTime = false</c> on all child particle systems.</summary>
/// <param name="__instance">The portal that started.</param>
[HarmonyPostfix]
[HarmonyPatch("Start")]
// ReSharper disable once InconsistentNaming
public static void ForceScaledTime(scrPortalParticles __instance)
{
if (!RenderManager.Instance || RenderManager.Instance.stage < RenderStage.Load) return;
if (__instance == null) return;
var particleSystems = __instance.GetComponentsInChildren<ParticleSystem>(true);
foreach (var ps in particleSystems)
{
if (ps == null) continue;
var main = ps.main;
main.useUnscaledTime = false;
}
}
}