mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-01 11:12:49 +08:00
114 lines
3.4 KiB
C#
114 lines
3.4 KiB
C#
using HarmonyLib;
|
|
using UniverseLib.UI;
|
|
using UniverseLib.UI.Models;
|
|
#if UNHOLLOWER
|
|
using IL2CPPUtils = UnhollowerBaseLib.UnhollowerUtils;
|
|
#endif
|
|
#if INTEROP
|
|
using IL2CPPUtils = Il2CppInterop.Common.Il2CppInteropUtils;
|
|
#endif
|
|
|
|
namespace UnityExplorer.UI.Widgets
|
|
{
|
|
internal class TimeScaleWidget
|
|
{
|
|
public TimeScaleWidget(GameObject parent)
|
|
{
|
|
Instance = this;
|
|
|
|
ConstructUI(parent);
|
|
|
|
InitPatch();
|
|
}
|
|
|
|
static TimeScaleWidget Instance;
|
|
|
|
ButtonRef lockBtn;
|
|
bool locked;
|
|
InputFieldRef timeInput;
|
|
float desiredTime;
|
|
bool settingTimeScale;
|
|
|
|
public void Update()
|
|
{
|
|
// Fallback in case Time.timeScale patch failed for whatever reason
|
|
if (locked)
|
|
SetTimeScale(desiredTime);
|
|
|
|
if (!timeInput.Component.isFocused)
|
|
timeInput.Text = Time.timeScale.ToString("F2");
|
|
}
|
|
|
|
void SetTimeScale(float time)
|
|
{
|
|
settingTimeScale = true;
|
|
Time.timeScale = time;
|
|
settingTimeScale = false;
|
|
}
|
|
|
|
// UI event listeners
|
|
|
|
void OnTimeInputEndEdit(string val)
|
|
{
|
|
if (float.TryParse(val, out float f))
|
|
{
|
|
SetTimeScale(f);
|
|
desiredTime = f;
|
|
}
|
|
}
|
|
|
|
void OnPauseButtonClicked()
|
|
{
|
|
OnTimeInputEndEdit(timeInput.Text);
|
|
|
|
locked = !locked;
|
|
|
|
Color color = locked ? new Color(0.3f, 0.3f, 0.2f) : new Color(0.2f, 0.2f, 0.2f);
|
|
RuntimeHelper.SetColorBlock(lockBtn.Component, color, color * 1.2f, color * 0.7f);
|
|
lockBtn.ButtonText.text = locked ? "Unlock" : "Lock";
|
|
}
|
|
|
|
// UI Construction
|
|
|
|
void ConstructUI(GameObject parent)
|
|
{
|
|
Text timeLabel = UIFactory.CreateLabel(parent, "TimeLabel", "Time:", TextAnchor.MiddleRight, Color.grey);
|
|
UIFactory.SetLayoutElement(timeLabel.gameObject, minHeight: 25, minWidth: 35);
|
|
|
|
timeInput = UIFactory.CreateInputField(parent, "TimeInput", "timeScale");
|
|
UIFactory.SetLayoutElement(timeInput.Component.gameObject, minHeight: 25, minWidth: 40);
|
|
timeInput.Component.GetOnEndEdit().AddListener(OnTimeInputEndEdit);
|
|
|
|
timeInput.Text = string.Empty;
|
|
timeInput.Text = Time.timeScale.ToString();
|
|
|
|
lockBtn = UIFactory.CreateButton(parent, "PauseButton", "Lock", new Color(0.2f, 0.2f, 0.2f));
|
|
UIFactory.SetLayoutElement(lockBtn.Component.gameObject, minHeight: 25, minWidth: 50);
|
|
lockBtn.OnClick += OnPauseButtonClicked;
|
|
}
|
|
|
|
// Only allow Time.timeScale to be set if the user hasn't "locked" it or if we are setting the value internally.
|
|
|
|
static void InitPatch()
|
|
{
|
|
|
|
try
|
|
{
|
|
MethodInfo target = typeof(Time).GetProperty("timeScale").GetSetMethod();
|
|
#if CPP
|
|
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(target) == null)
|
|
return;
|
|
#endif
|
|
ExplorerCore.Harmony.Patch(target,
|
|
prefix: new(AccessTools.Method(typeof(TimeScaleWidget), nameof(Prefix_Time_set_timeScale))));
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
static bool Prefix_Time_set_timeScale()
|
|
{
|
|
return !Instance.locked || Instance.settingTimeScale;
|
|
}
|
|
}
|
|
}
|