[AvatarScaleMod] Refactor & Avatar Parameters

This commit is contained in:
NotAKidoS 2023-06-24 01:11:38 -05:00
parent 5b7b586298
commit acacc21050
5 changed files with 322 additions and 162 deletions

View file

@ -1,26 +1,28 @@
using UnityEngine; using ABI_RC.Core.Savior;
using ABI_RC.Core.Savior; using UnityEngine;
namespace NAK.AvatarScaleMod; namespace NAK.AvatarScaleMod;
public static class AvatarScaleGesture public static class AvatarScaleGesture
{ {
// Toggle for scale gesture
public static bool GestureEnabled; public static bool GestureEnabled;
// Require triggers to be down while doing fist? - Exteratta
public static bool RequireTriggers = true; public static bool RequireTriggers = true;
public static float InitialModifier = 1f;
public static float InitialTargetHeight = 1.8f; // Initial values when scale gesture is started
public static float InitialModifier;
public static float InitialTargetHeight;
public static void OnScaleStart(float modifier, Transform transform1, Transform transform2) public static void OnScaleStart(float modifier, Transform transform1, Transform transform2)
{ {
// AvatarScaleMod.Logger.Msg("OnScaleStart!");
if (!GestureEnabled) if (!GestureEnabled)
return; return;
// you can start the scale, but cant interact with it without holding triggers
if (AvatarScaleManager.LocalAvatar != null) if (AvatarScaleManager.LocalAvatar != null)
{ {
// store initial modifier // Store initial modifier so we can get difference later
InitialModifier = modifier; InitialModifier = modifier;
InitialTargetHeight = AvatarScaleManager.LocalAvatar.TargetHeight; InitialTargetHeight = AvatarScaleManager.LocalAvatar.TargetHeight;
} }
@ -28,16 +30,21 @@ public static class AvatarScaleGesture
public static void OnScaleStay(float modifier, Transform transform1, Transform transform2) public static void OnScaleStay(float modifier, Transform transform1, Transform transform2)
{ {
// AvatarScaleMod.Logger.Msg("OnScaleStay!");
if (!GestureEnabled) if (!GestureEnabled)
return; return;
if (RequireTriggers && !IsBothTriggersDown()) // Allow user to release triggers to reset "world grip"
if (RequireTriggers && !AreBothTriggersDown())
{
InitialModifier = modifier;
InitialTargetHeight = AvatarScaleManager.LocalAvatar.TargetHeight;
return; return;
}
if (AvatarScaleManager.LocalAvatar != null) if (AvatarScaleManager.LocalAvatar != null)
{ {
float modifierRatio = modifier / InitialModifier; // Invert so the gesture is more of a world squish instead of happy hug
float modifierRatio = 1f / (modifier / InitialModifier);
// Determine the adjustment factor for the height, this will be >1 if scaling up, <1 if scaling down. // Determine the adjustment factor for the height, this will be >1 if scaling up, <1 if scaling down.
float heightAdjustmentFactor = (modifierRatio > 1) ? 1 + (modifierRatio - 1) : 1 - (1 - modifierRatio); float heightAdjustmentFactor = (modifierRatio > 1) ? 1 + (modifierRatio - 1) : 1 - (1 - modifierRatio);
@ -49,10 +56,11 @@ public static class AvatarScaleGesture
public static void OnScaleEnd(float modifier, Transform transform1, Transform transform2) public static void OnScaleEnd(float modifier, Transform transform1, Transform transform2)
{ {
// AvatarScaleMod.Logger.Msg("OnScaleEnd!"); // Unused, needed for mod network?
} }
public static bool IsBothTriggersDown() // Maybe it should be one trigger? Imagine XSOverlay scaling but for player.
public static bool AreBothTriggersDown()
{ {
return CVRInputManager.Instance.interactLeftValue > 0.75f && CVRInputManager.Instance.interactRightValue > 0.75f; return CVRInputManager.Instance.interactLeftValue > 0.75f && CVRInputManager.Instance.interactRightValue > 0.75f;
} }

View file

@ -1,4 +1,5 @@
using ABI.CCK.Components; using ABI.CCK.Components;
using ABI_RC.Core.Player;
using NAK.AvatarScaleMod.ScaledComponents; using NAK.AvatarScaleMod.ScaledComponents;
using System.Collections; using System.Collections;
using UnityEngine; using UnityEngine;
@ -8,66 +9,143 @@ namespace NAK.AvatarScaleMod;
public class AvatarScaleManager : MonoBehaviour public class AvatarScaleManager : MonoBehaviour
{ {
public static AvatarScaleManager LocalAvatar { get; private set; } // Constants
public const float MinHeight = 0.1f; // TODO: Make into Setting
public const float MaxHeight = 10f; // TODO: Make into Setting
public const string ScaleFactorParameterName = "ScaleFactor";
public const string ScaleFactorParameterNameLocal = "#ScaleFactor";
// List of component types to be collected and scaled private static readonly System.Type[] scalableComponentTypes =
private static readonly System.Type[] scaleComponentTypes = new System.Type[]
{ {
typeof(Light), typeof(Light),
typeof(AudioSource), typeof(AudioSource),
typeof(ParticleSystem), typeof(ParticleSystem),
typeof(ParentConstraint), typeof(ParentConstraint),
typeof(PositionConstraint), typeof(PositionConstraint),
typeof(ScaleConstraint), typeof(ScaleConstraint)
}; };
public const float MinimumHeight = 0.1f; // Public properties
public const float MaximumHeight = 10f; public static bool GlobalEnabled { get; set; }
public static AvatarScaleManager LocalAvatar { get; private set; }
// Scalable Components
private List<ScaledLight> _lights = new List<ScaledLight>();
private List<ScaledAudioSource> _audioSources = new List<ScaledAudioSource>();
//private List<ScaledComponent<ParticleSystem>> _particleSystems = new List<ScaledComponent<ParticleSystem>>();
private List<ScaledParentConstraint> _parentConstraints = new List<ScaledParentConstraint>();
private List<ScaledPositionConstraint> _positionConstraints = new List<ScaledPositionConstraint>();
private List<ScaledScaleConstraint> _scaleConstraints = new List<ScaledScaleConstraint>();
public float TargetHeight { get; private set; } public float TargetHeight { get; private set; }
public float InitialHeight { get; private set; } public float InitialHeight { get; private set; }
public Vector3 InitialScale { get; private set; } public Vector3 InitialScale { get; private set; }
public float ScaleFactor { get; private set; } public float ScaleFactor { get; private set; }
public void Initialize(float initialHeight, Vector3 initialScale) // Private properties
private bool _isLocalAvatar;
private Animator _animator;
private CVRAvatar _avatar;
private List<ScaledLight> _scaledLights = new List<ScaledLight>();
private List<ScaledAudioSource> _scaledAudioSources = new List<ScaledAudioSource>();
private List<ScaledParentConstraint> _scaledParentConstraints = new List<ScaledParentConstraint>();
private List<ScaledPositionConstraint> _scaledPositionConstraints = new List<ScaledPositionConstraint>();
private List<ScaledScaleConstraint> _scaledScaleConstraints = new List<ScaledScaleConstraint>();
public void Initialize(float initialHeight, Vector3 initialScale, bool isLocalAvatar)
{ {
// Check for zero height
if (Math.Abs(initialHeight) < 1E-6) if (Math.Abs(initialHeight) < 1E-6)
{ {
AvatarScaleMod.Logger.Warning("Cannot initialize with a height of zero!"); AvatarScaleMod.Logger.Warning("Cannot initialize with a height of zero!");
return; return;
} }
this.TargetHeight = 1f; if (isLocalAvatar && LocalAvatar == null)
{
_isLocalAvatar = true;
LocalAvatar = this;
}
this.TargetHeight = initialHeight;
this.InitialHeight = initialHeight; this.InitialHeight = initialHeight;
this.InitialScale = initialScale; this.InitialScale = initialScale;
UpdateScaleFactor(); this.ScaleFactor = 1f;
}
private async void Start()
{
_avatar = GetComponent<CVRAvatar>();
if (_avatar == null)
{
AvatarScaleMod.Logger.Error("AvatarScaleManager should be attached to a GameObject with a CVRAvatar component.");
return;
}
if (!_isLocalAvatar)
{
_animator = GetComponent<Animator>();
}
// I am unsure if this reduces the hitch or not.
// I do not want to patch where the game already does scanning though.
await FindComponentsOfTypeAsync(scalableComponentTypes);
}
private void OnDisable()
{
// TODO: Test with Avatar Distance Hider
ResetAllToInitialScale();
}
private void OnDestroy()
{
ClearLists();
if (LocalAvatar == this)
{
LocalAvatar = null;
}
}
private void ClearLists()
{
_scaledAudioSources.Clear();
_scaledLights.Clear();
_scaledParentConstraints.Clear();
_scaledPositionConstraints.Clear();
_scaledScaleConstraints.Clear();
} }
public void SetTargetHeight(float newHeight) public void SetTargetHeight(float newHeight)
{ {
TargetHeight = Mathf.Clamp(newHeight, MinimumHeight, MaximumHeight); TargetHeight = Mathf.Clamp(newHeight, MinHeight, MaxHeight);
UpdateScaleFactor(); UpdateScaleFactor();
UpdateAnimatorParameter();
} }
public void UpdateScaleFactor() public void SetTargetHeightOverTime(float newHeight, float duration)
{
StartCoroutine(SetTargetHeightOverTimeCoroutine(newHeight, duration));
}
private void UpdateScaleFactor()
{ {
// Check for zero
if (Math.Abs(InitialHeight) < 1E-6) if (Math.Abs(InitialHeight) < 1E-6)
{ {
AvatarScaleMod.Logger.Warning("InitialHeight is zero, cannot calculate ScaleFactor."); AvatarScaleMod.Logger.Warning("InitialHeight is zero, cannot calculate ScaleFactor.");
return; return;
} }
this.ScaleFactor = TargetHeight / InitialHeight; ScaleFactor = TargetHeight / InitialHeight;
}
private void UpdateAnimatorParameter()
{
if (_isLocalAvatar)
{
// Set synced and local parameters for Local Player
PlayerSetup.Instance.animatorManager.SetAnimatorParameter(ScaleFactorParameterName, ScaleFactor);
PlayerSetup.Instance.animatorManager.SetAnimatorParameter(ScaleFactorParameterNameLocal, ScaleFactor);
}
else if (_animator != null)
{
// Set local parameter for Remote Player
_animator.SetFloat(ScaleFactorParameterNameLocal, ScaleFactor);
}
} }
private Vector3 CalculateNewScale() private Vector3 CalculateNewScale()
@ -75,68 +153,70 @@ public class AvatarScaleManager : MonoBehaviour
return InitialScale * ScaleFactor; return InitialScale * ScaleFactor;
} }
private void Awake() private IEnumerator SetTargetHeightOverTimeCoroutine(float newHeight, float duration)
{ {
// why am i caching the avatar float startTime = Time.time;
CVRAvatar avatar = GetComponent<CVRAvatar>(); float startHeight = TargetHeight;
if (avatar == null)
// Clamping the newHeight to be between MinHeight and MaxHeight
newHeight = Mathf.Clamp(newHeight, MinHeight, MaxHeight);
while (Time.time < startTime + duration)
{ {
AvatarScaleMod.Logger.Error("AvatarScaleManager should be attached to a GameObject with a CVRAvatar component."); float t = (Time.time - startTime) / duration;
return; TargetHeight = Mathf.Lerp(startHeight, newHeight, t);
UpdateScaleFactor();
yield return null;
} }
// i cant believe i would stoop this low // Final setting of the TargetHeight after the loop is done.
if (gameObject.layer == 8 && LocalAvatar == null) TargetHeight = newHeight;
LocalAvatar = this; UpdateScaleFactor();
FindComponentsOfType(scaleComponentTypes);
} }
private void OnDestroy() // TODO: actually profile this
private async Task FindComponentsOfTypeAsync(Type[] types)
{ {
_audioSources.Clear(); var tasks = new List<Task>();
_lights.Clear(); var components = GetComponentsInChildren<Component>(true);
//_particleSystems.Clear(); // fuck no
_parentConstraints.Clear();
_positionConstraints.Clear();
_scaleConstraints.Clear();
// local player manager foreach (var component in components)
if (LocalAvatar == this)
LocalAvatar = null;
}
private void OnDisable()
{
ResetAllToInitialScale();
}
private void FindComponentsOfType(params System.Type[] types)
{
foreach (var type in types)
{ {
var components = gameObject.GetComponentsInChildren(type, true); if (this == null) break;
foreach (var component in components) if (component == null) continue;
tasks.Add(Task.Run(() =>
{ {
switch (component) var componentType = component.GetType();
if (types.Contains(componentType))
{ {
case AudioSource audioSource: AddScaledComponent(componentType, component);
_audioSources.Add(new ScaledAudioSource(audioSource));
break;
case Light light:
_lights.Add(new ScaledLight(light));
break;
case ParentConstraint parentConstraint:
_parentConstraints.Add(new ScaledParentConstraint(parentConstraint));
break;
case PositionConstraint positionConstraint:
_positionConstraints.Add(new ScaledPositionConstraint(positionConstraint));
break;
case ScaleConstraint scaleConstraint:
_scaleConstraints.Add(new ScaledScaleConstraint(scaleConstraint));
break;
} }
} }));
}
await Task.WhenAll(tasks);
}
private void AddScaledComponent(Type type, Component component)
{
switch (type)
{
case Type _ when type == typeof(AudioSource):
_scaledAudioSources.Add(new ScaledAudioSource((AudioSource)component));
break;
case Type _ when type == typeof(Light):
_scaledLights.Add(new ScaledLight((Light)component));
break;
case Type _ when type == typeof(ParentConstraint):
_scaledParentConstraints.Add(new ScaledParentConstraint((ParentConstraint)component));
break;
case Type _ when type == typeof(PositionConstraint):
_scaledPositionConstraints.Add(new ScaledPositionConstraint((PositionConstraint)component));
break;
case Type _ when type == typeof(ScaleConstraint):
_scaledScaleConstraints.Add(new ScaledScaleConstraint((ScaleConstraint)component));
break;
} }
} }
@ -154,11 +234,17 @@ public class AvatarScaleManager : MonoBehaviour
private void ApplyAvatarScaling() private void ApplyAvatarScaling()
{ {
if (!GlobalEnabled)
return;
transform.localScale = CalculateNewScale(); transform.localScale = CalculateNewScale();
} }
private void ApplyComponentScaling() private void ApplyComponentScaling()
{ {
if (!GlobalEnabled)
return;
UpdateLightScales(); UpdateLightScales();
UpdateAudioSourceScales(); UpdateAudioSourceScales();
UpdateParentConstraintScales(); UpdateParentConstraintScales();
@ -168,103 +254,89 @@ public class AvatarScaleManager : MonoBehaviour
private void UpdateLightScales() private void UpdateLightScales()
{ {
foreach (var scaledLight in _lights) // Update range of each light component
foreach (var light in _scaledLights)
{ {
scaledLight.Component.range = scaledLight.InitialRange * ScaleFactor; light.Component.range = light.InitialRange * ScaleFactor;
} }
} }
private void UpdateAudioSourceScales() private void UpdateAudioSourceScales()
{ {
foreach (var scaledAudioSource in _audioSources) // Update min and max distance of each audio source component
foreach (var audioSource in _scaledAudioSources)
{ {
scaledAudioSource.Component.minDistance = scaledAudioSource.InitialMinDistance * ScaleFactor; audioSource.Component.minDistance = audioSource.InitialMinDistance * ScaleFactor;
scaledAudioSource.Component.maxDistance = scaledAudioSource.InitialMaxDistance * ScaleFactor; audioSource.Component.maxDistance = audioSource.InitialMaxDistance * ScaleFactor;
} }
} }
private void UpdateParentConstraintScales() private void UpdateParentConstraintScales()
{ {
foreach (var scaledParentConstraint in _parentConstraints) // Update translationAtRest and translationOffsets of each parent constraint component
foreach (var parentConstraint in _scaledParentConstraints)
{ {
scaledParentConstraint.Component.translationAtRest = scaledParentConstraint.InitialTranslationAtRest * ScaleFactor; parentConstraint.Component.translationAtRest = parentConstraint.InitialTranslationAtRest * ScaleFactor;
for (int i = 0; i < scaledParentConstraint.InitialTranslationOffsets.Count; i++) for (int i = 0; i < parentConstraint.InitialTranslationOffsets.Count; i++)
{ {
scaledParentConstraint.Component.translationOffsets[i] = scaledParentConstraint.InitialTranslationOffsets[i] * ScaleFactor; parentConstraint.Component.translationOffsets[i] = parentConstraint.InitialTranslationOffsets[i] * ScaleFactor;
} }
} }
} }
private void UpdatePositionConstraintScales() private void UpdatePositionConstraintScales()
{ {
foreach (var scaledPositionConstraint in _positionConstraints) // Update translationAtRest and translationOffset of each position constraint component
foreach (var positionConstraint in _scaledPositionConstraints)
{ {
scaledPositionConstraint.Component.translationAtRest = scaledPositionConstraint.InitialTranslationAtRest * ScaleFactor; positionConstraint.Component.translationAtRest = positionConstraint.InitialTranslationAtRest * ScaleFactor;
scaledPositionConstraint.Component.translationOffset = scaledPositionConstraint.InitialTranslationOffset * ScaleFactor; positionConstraint.Component.translationOffset = positionConstraint.InitialTranslationOffset * ScaleFactor;
} }
} }
private void UpdateScaleConstraintScales() private void UpdateScaleConstraintScales()
{ {
foreach (var scaledScaleConstraint in _scaleConstraints) // Update scaleAtRest and scaleOffset of each scale constraint component
foreach (var scaleConstraint in _scaledScaleConstraints)
{ {
scaledScaleConstraint.Component.scaleAtRest = scaledScaleConstraint.InitialScaleAtRest * ScaleFactor; scaleConstraint.Component.scaleAtRest = scaleConstraint.InitialScaleAtRest * ScaleFactor;
scaledScaleConstraint.Component.scaleOffset = scaledScaleConstraint.InitialScaleOffset * ScaleFactor; scaleConstraint.Component.scaleOffset = scaleConstraint.InitialScaleOffset * ScaleFactor;
} }
} }
private void ResetAllToInitialScale() private void ResetAllToInitialScale()
{ {
// quick n lazy for right now // Reset transform scale and each component to their initial scales
transform.localScale = InitialScale; transform.localScale = InitialScale;
foreach (var scaledLight in _lights) foreach (var light in _scaledLights)
{ {
scaledLight.Component.range = scaledLight.InitialRange; light.Component.range = light.InitialRange;
} }
foreach (var scaledAudioSource in _audioSources) foreach (var audioSource in _scaledAudioSources)
{ {
scaledAudioSource.Component.minDistance = scaledAudioSource.InitialMinDistance; audioSource.Component.minDistance = audioSource.InitialMinDistance;
scaledAudioSource.Component.maxDistance = scaledAudioSource.InitialMaxDistance; audioSource.Component.maxDistance = audioSource.InitialMaxDistance;
} }
foreach (var scaledParentConstraint in _parentConstraints) foreach (var parentConstraint in _scaledParentConstraints)
{ {
scaledParentConstraint.Component.translationAtRest = scaledParentConstraint.InitialTranslationAtRest; parentConstraint.Component.translationAtRest = parentConstraint.InitialTranslationAtRest;
for (int i = 0; i < scaledParentConstraint.InitialTranslationOffsets.Count; i++) for (int i = 0; i < parentConstraint.InitialTranslationOffsets.Count; i++)
{ {
scaledParentConstraint.Component.translationOffsets[i] = scaledParentConstraint.InitialTranslationOffsets[i]; parentConstraint.Component.translationOffsets[i] = parentConstraint.InitialTranslationOffsets[i];
} }
} }
foreach (var scaledPositionConstraint in _positionConstraints) foreach (var positionConstraint in _scaledPositionConstraints)
{ {
scaledPositionConstraint.Component.translationAtRest = scaledPositionConstraint.InitialTranslationAtRest; positionConstraint.Component.translationAtRest = positionConstraint.InitialTranslationAtRest;
scaledPositionConstraint.Component.translationOffset = scaledPositionConstraint.InitialTranslationOffset; positionConstraint.Component.translationOffset = positionConstraint.InitialTranslationOffset;
} }
foreach (var scaledScaleConstraint in _scaleConstraints) foreach (var scaleConstraint in _scaledScaleConstraints)
{ {
scaledScaleConstraint.Component.scaleAtRest = scaledScaleConstraint.InitialScaleAtRest; scaleConstraint.Component.scaleAtRest = scaleConstraint.InitialScaleAtRest;
scaledScaleConstraint.Component.scaleOffset = scaledScaleConstraint.InitialScaleOffset; scaleConstraint.Component.scaleOffset = scaleConstraint.InitialScaleOffset;
} }
} }
// use for slow transition between avatars initial height & saved height>>>??????????????
public IEnumerator SetTargetHeightOverTime(float newHeight, float duration)
{
float startTime = Time.time;
float startHeight = TargetHeight;
newHeight = Mathf.Clamp(newHeight, MinimumHeight, MaximumHeight);
while (Time.time < startTime + duration)
{
float t = (Time.time - startTime) / duration;
TargetHeight = Mathf.Lerp(startHeight, newHeight, t);
UpdateScaleFactor();
yield return null;
}
TargetHeight = newHeight;
UpdateScaleFactor();
}
} }

View file

@ -3,6 +3,8 @@ using ABI_RC.Core.Savior;
using HarmonyLib; using HarmonyLib;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using ABI_RC.Systems.IK;
using RootMotion.FinalIK;
namespace NAK.AvatarScaleMod.HarmonyPatches; namespace NAK.AvatarScaleMod.HarmonyPatches;
@ -14,7 +16,8 @@ class PlayerSetupPatches
{ {
try try
{ {
__instance._avatar.AddComponent<AvatarScaleManager>().Initialize(__instance._initialAvatarHeight, __instance.initialScale); __instance._avatar.AddComponent<AvatarScaleManager>().Initialize(__instance._initialAvatarHeight, __instance.initialScale, true);
} }
catch (Exception e) catch (Exception e)
{ {
@ -22,6 +25,54 @@ class PlayerSetupPatches
AvatarScaleMod.Logger.Error(e); AvatarScaleMod.Logger.Error(e);
} }
} }
static Vector3 originalPosition;
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.SetPlaySpaceScale))]
static void Prefix_PlayerSetup_SetPlaySpaceScale(ref PlayerSetup __instance)
{
originalPosition = __instance.vrCamera.transform.position;
originalPosition.y = __instance.transform.position.y;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.SetPlaySpaceScale))]
static void Postfix_PlayerSetup_SetPlaySpaceScale(ref PlayerSetup __instance)
{
Vector3 newPosition = __instance.vrCamera.transform.position;
newPosition.y = __instance.transform.position.y;
Vector3 offset = newPosition - originalPosition;
// Apply the offset to the VR camera rig's position
__instance.transform.position -= offset;
//if (IKSystem.vrik != null)
//{
// IKSystem.vrik.solver.locomotion.AddDeltaPosition(offset * 2);
// IKSystem.vrik.solver.raycastOriginPelvis += offset * 2;
// IKSystem.vrik.solver.Reset();
//}
}
}
class PuppetMasterPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(PuppetMaster), nameof(PuppetMaster.AvatarInstantiated))]
static void Postfix_PuppetMaster_AvatarInstantiated(ref PuppetMaster __instance)
{
try
{
__instance.avatarObject.AddComponent<AvatarScaleManager>().Initialize(__instance._initialAvatarHeight, __instance.initialAvatarScale, false);
}
catch (Exception e)
{
AvatarScaleMod.Logger.Error($"Error during the patched method {nameof(Postfix_PuppetMaster_AvatarInstantiated)}");
AvatarScaleMod.Logger.Error(e);
}
}
} }
class GesturePlaneTestPatches class GesturePlaneTestPatches
@ -33,24 +84,45 @@ class GesturePlaneTestPatches
try try
{ {
// nicked from Kafe >:)))) // nicked from Kafe >:))))
// This requires arms far outward- pull inward with fist and triggers.
// Release triggers while still holding fist to readjust.
var gesture = new CVRGesture var gesture = new CVRGesture
{ {
name = "avatarScale", name = "avatarScaleIn",
type = CVRGesture.GestureType.Hold, type = CVRGesture.GestureType.Hold,
}; };
// TODO: Expose these settings in-game and tune till they feel right
gesture.steps.Add(new CVRGestureStep gesture.steps.Add(new CVRGestureStep
{ {
firstGesture = CVRGestureStep.Gesture.Fist, firstGesture = CVRGestureStep.Gesture.Fist,
secondGesture = CVRGestureStep.Gesture.Fist, secondGesture = CVRGestureStep.Gesture.Fist,
startDistance = 0.5f, startDistance = 1f,
endDistance = 0.4f, endDistance = 0.25f,
direction = CVRGestureStep.GestureDirection.MovingIn, direction = CVRGestureStep.GestureDirection.MovingIn,
}); });
gesture.onStart.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleStart)); gesture.onStart.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleStart));
gesture.onStay.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleStay)); gesture.onStay.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleStay));
gesture.onEnd.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleEnd)); gesture.onEnd.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleEnd));
CVRGestureRecognizer.Instance.gestures.Add(gesture); CVRGestureRecognizer.Instance.gestures.Add(gesture);
gesture = new CVRGesture
{
name = "avatarScaleOut",
type = CVRGesture.GestureType.Hold,
};
gesture.steps.Add(new CVRGestureStep
{
firstGesture = CVRGestureStep.Gesture.Fist,
secondGesture = CVRGestureStep.Gesture.Fist,
startDistance = 0.25f,
endDistance = 1f,
direction = CVRGestureStep.GestureDirection.MovingOut,
});
gesture.onStart.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleStart));
gesture.onStay.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleStay));
gesture.onEnd.AddListener(new UnityAction<float, Transform, Transform>(AvatarScaleGesture.OnScaleEnd));
CVRGestureRecognizer.Instance.gestures.Add(gesture);
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -6,21 +6,13 @@ public class AvatarScaleMod : MelonMod
{ {
internal static MelonLogger.Instance Logger; internal static MelonLogger.Instance Logger;
public static readonly MelonPreferences_Category Category =
MelonPreferences.CreateCategory(nameof(AvatarScaleMod));
public static readonly MelonPreferences_Entry<bool> EntryEnabled =
Category.CreateEntry("Enabled", true, description: "Toggle AvatarScaleMod entirely.");
public static readonly MelonPreferences_Entry<bool> EntryUseScaleGesture =
Category.CreateEntry("Scale Gesture", false, description: "Use two fists to scale yourself easily.");
public override void OnInitializeMelon() public override void OnInitializeMelon()
{ {
Logger = LoggerInstance; Logger = LoggerInstance;
ModSettings.InitializeModSettings(); ModSettings.InitializeModSettings();
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches)); ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
//ApplyPatches(typeof(HarmonyPatches.PuppetMasterPatches));
ApplyPatches(typeof(HarmonyPatches.GesturePlaneTestPatches)); ApplyPatches(typeof(HarmonyPatches.GesturePlaneTestPatches));
} }

View file

@ -1,23 +1,39 @@
namespace NAK.AvatarScaleMod; using MelonLoader;
namespace NAK.AvatarScaleMod;
// i like this
// Another thing i stole from Kafe, this organizes stuff so much moreee
// Should I move the entries here too?
static class ModSettings static class ModSettings
{ {
public static readonly MelonPreferences_Category Category =
MelonPreferences.CreateCategory(nameof(AvatarScaleMod));
public static readonly MelonPreferences_Entry<bool> EntryEnabled =
Category.CreateEntry("Enabled", true, description: "Toggle AvatarScaleMod entirely for Local user. Kinda.");
public static readonly MelonPreferences_Entry<bool> EntryUseScaleGesture =
Category.CreateEntry("Scale Gesture", false, description: "Use two fists to scale yourself easily.");
static ModSettings()
{
EntryEnabled.OnEntryValueChanged.Subscribe(OnEntryEnabledChanged);
EntryUseScaleGesture.OnEntryValueChanged.Subscribe(OnEntryUseScaleGestureChanged);
}
public static void InitializeModSettings() public static void InitializeModSettings()
{ {
AvatarScaleMod.EntryEnabled.OnEntryValueChanged.Subscribe(OnEntryEnabledChanged); AvatarScaleManager.GlobalEnabled = EntryEnabled.Value;
AvatarScaleMod.EntryUseScaleGesture.OnEntryValueChanged.Subscribe(OnEntryUseScaleGestureChanged); AvatarScaleGesture.GestureEnabled = EntryUseScaleGesture.Value;
} }
static void OnEntryEnabledChanged(bool oldVal, bool newVal) static void OnEntryEnabledChanged(bool oldValue, bool newValue)
{ {
if (AvatarScaleManager.LocalAvatar != null) AvatarScaleManager.GlobalEnabled = newValue;
AvatarScaleManager.LocalAvatar.enabled = newVal;
} }
static void OnEntryUseScaleGestureChanged(bool oldVal, bool newVal) static void OnEntryUseScaleGestureChanged(bool oldValue, bool newValue)
{ {
AvatarScaleGesture.GestureEnabled = newVal; AvatarScaleGesture.GestureEnabled = newValue;
} }
} }