mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 22:39:22 +00:00
[IKFixes] Updates for 2023r171
Removed unneeded settings. Fixed halfbody fake root angle option. Added Reset Settings UIExpansionKit button.
This commit is contained in:
parent
3c52f8c60c
commit
e31bf87609
7 changed files with 141 additions and 202 deletions
21
IKFixes/ChatBoxExtensions.csproj
Normal file
21
IKFixes/ChatBoxExtensions.csproj
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- Mute SDraw's funny warning, because he only compilled for x64 while most people compile for both -->
|
||||||
|
<NoWarn>$(NoWarn);MSB3270</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- Didn't put in the Directory.Build.props because it spams funny warnings... -->
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="ml_prm">
|
||||||
|
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\ml_prm.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ChatBox">
|
||||||
|
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\ChatBox.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -2,11 +2,11 @@
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using ABI_RC.Systems.IK.SubSystems;
|
using ABI_RC.Systems.IK.SubSystems;
|
||||||
|
using ABI_RC.Systems.InputManagement;
|
||||||
using ABI_RC.Systems.MovementSystem;
|
using ABI_RC.Systems.MovementSystem;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using RootMotion.FinalIK;
|
using RootMotion.FinalIK;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
|
||||||
|
|
||||||
namespace NAK.IKFixes.HarmonyPatches;
|
namespace NAK.IKFixes.HarmonyPatches;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ internal static class BodySystemPatches
|
||||||
{
|
{
|
||||||
Transform parent = null;
|
Transform parent = null;
|
||||||
float offsetDistance = 0f;
|
float offsetDistance = 0f;
|
||||||
|
|
||||||
switch (trackingPoint.assignedRole)
|
switch (trackingPoint.assignedRole)
|
||||||
{
|
{
|
||||||
case TrackingPoint.TrackingRole.LeftKnee:
|
case TrackingPoint.TrackingRole.LeftKnee:
|
||||||
|
@ -42,27 +42,27 @@ internal static class BodySystemPatches
|
||||||
offsetDistance = -0.15f;
|
offsetDistance = -0.15f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent != null)
|
if (parent == null)
|
||||||
{
|
continue;
|
||||||
// Set the offset transform's parent and reset its local position and rotation
|
|
||||||
trackingPoint.offsetTransform.parent = parent;
|
// Set the offset transform's parent and reset its local position and rotation
|
||||||
trackingPoint.offsetTransform.localPosition = Vector3.zero;
|
trackingPoint.offsetTransform.parent = parent;
|
||||||
trackingPoint.offsetTransform.localRotation = Quaternion.identity;
|
trackingPoint.offsetTransform.localPosition = Vector3.zero;
|
||||||
trackingPoint.offsetTransform.parent = trackingPoint.referenceTransform;
|
trackingPoint.offsetTransform.localRotation = Quaternion.identity;
|
||||||
|
trackingPoint.offsetTransform.parent = trackingPoint.referenceTransform;
|
||||||
// Apply additional offset based on the assigned role
|
|
||||||
Vector3 additionalOffset = IKSystem.vrik.references.root.forward * offsetDistance;
|
// Apply additional offset based on the assigned role
|
||||||
trackingPoint.offsetTransform.position += additionalOffset;
|
Vector3 additionalOffset = IKSystem.vrik.references.root.forward * offsetDistance;
|
||||||
|
trackingPoint.offsetTransform.position += additionalOffset;
|
||||||
// Game originally sets them to about half a meter out, which fucks with slime tracker users and
|
|
||||||
// makes the bendGoals less responsive/less accurate.
|
// Game originally sets them to about half a meter out, which fucks with slime tracker users and
|
||||||
|
// makes the bendGoals less responsive/less accurate.
|
||||||
//Funny thing is that IKTweaks specifically made this an option, which should be added to both CVR & Standable for the same reason.
|
|
||||||
/// Elbow / knee / chest bend goal offset - controls how far bend goal targets will be away from the actual joint.
|
//Funny thing is that IKTweaks specifically made this an option, which should be added to both CVR & Standable for the same reason.
|
||||||
/// Lower values should produce better precision with bent joint, higher values - better stability with straight joint.
|
/// Elbow / knee / chest bend goal offset - controls how far bend goal targets will be away from the actual joint.
|
||||||
/// Sensible range of values is between 0 and 1.
|
/// Lower values should produce better precision with bent joint, higher values - better stability with straight joint.
|
||||||
}
|
/// Sensible range of values is between 0 and 1.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,6 @@ internal static class BodySystemPatches
|
||||||
arm.shoulderRotationWeight = weight;
|
arm.shoulderRotationWeight = weight;
|
||||||
arm.shoulderTwistWeight = weight;
|
arm.shoulderTwistWeight = weight;
|
||||||
// assumed fix of bend goal weight if arms disabled with elbows (havent tested)
|
// assumed fix of bend goal weight if arms disabled with elbows (havent tested)
|
||||||
// why is there no "usingElbowTracker" flag like knees? where is the consistancy???
|
|
||||||
arm.bendGoalWeight = arm.bendGoal != null ? weight : 0f;
|
arm.bendGoalWeight = arm.bendGoal != null ? weight : 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,25 +129,33 @@ internal static class BodySystemPatches
|
||||||
float maxRootAngle = 25f;
|
float maxRootAngle = 25f;
|
||||||
float rootHeadingOffset = 0f;
|
float rootHeadingOffset = 0f;
|
||||||
|
|
||||||
if (BodySystem.isCalibratedAsFullBody || IKFixes.EntryUseFakeRootAngle.Value)
|
if (BodySystem.isCalibratedAsFullBody
|
||||||
|
|| IKFixes.EntryUseFakeRootAngle.Value
|
||||||
|
|| CVRInputManager.Instance.movementVector.sqrMagnitude > 0f)
|
||||||
maxRootAngle = 0f;
|
maxRootAngle = 0f;
|
||||||
|
|
||||||
|
// fixes body being wrong direction while playing emotes (root rotation)
|
||||||
if (PlayerSetup.Instance._emotePlaying)
|
if (PlayerSetup.Instance._emotePlaying)
|
||||||
maxRootAngle = 180f;
|
maxRootAngle = 180f;
|
||||||
|
|
||||||
|
// fixes feet always pointing toward head direction
|
||||||
if (IKFixes.EntryUseFakeRootAngle.Value && !BodySystem.isCalibratedAsFullBody)
|
if (IKFixes.EntryUseFakeRootAngle.Value && !BodySystem.isCalibratedAsFullBody)
|
||||||
{
|
{
|
||||||
float weightedAngleLimit = IKFixes.EntryFakeRootAngleLimit.Value * solver.locomotion.weight;
|
float weightedAngleLimit = IKFixes.EntryFakeRootAngleLimit.Value * solver.locomotion.weight;
|
||||||
float pivotAngle = MovementSystem.Instance.rotationPivot.eulerAngles.y;
|
float playerDirection = MovementSystem.Instance.rotationPivot.eulerAngles.y;
|
||||||
float deltaAngleRoot = Mathf.DeltaAngle(pivotAngle, _ikSimulatedRootAngle);
|
|
||||||
float absDeltaAngleRoot = Mathf.Abs(deltaAngleRoot);
|
float deltaAngleRoot = Mathf.DeltaAngle(playerDirection, _ikSimulatedRootAngle);
|
||||||
|
float angleOverLimit = Mathf.Abs(deltaAngleRoot) - weightedAngleLimit;
|
||||||
deltaAngleRoot = Mathf.Clamp(deltaAngleRoot, -weightedAngleLimit, weightedAngleLimit);
|
|
||||||
_ikSimulatedRootAngle = Mathf.MoveTowardsAngle(_ikSimulatedRootAngle, pivotAngle, absDeltaAngleRoot - weightedAngleLimit);
|
|
||||||
|
|
||||||
|
if (angleOverLimit > 0)
|
||||||
|
{
|
||||||
|
deltaAngleRoot = Mathf.Sign(deltaAngleRoot) * weightedAngleLimit;
|
||||||
|
_ikSimulatedRootAngle = Mathf.MoveTowardsAngle(_ikSimulatedRootAngle, playerDirection, angleOverLimit);
|
||||||
|
}
|
||||||
|
|
||||||
rootHeadingOffset = deltaAngleRoot;
|
rootHeadingOffset = deltaAngleRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
solver.spine.maxRootAngle = maxRootAngle;
|
solver.spine.maxRootAngle = maxRootAngle;
|
||||||
solver.spine.rootHeadingOffset = rootHeadingOffset;
|
solver.spine.rootHeadingOffset = rootHeadingOffset;
|
||||||
|
|
||||||
|
@ -207,7 +214,7 @@ internal static class BodySystemPatches
|
||||||
|
|
||||||
if (BodySystem.isCalibratedAsFullBody && BodySystem.TrackingPositionWeight > 0f)
|
if (BodySystem.isCalibratedAsFullBody && BodySystem.TrackingPositionWeight > 0f)
|
||||||
{
|
{
|
||||||
bool isRunning = MovementSystem.Instance.movementVector.magnitude > 0f;
|
bool isRunning = MovementSystem.Instance.movementVector.sqrMagnitude > 0f;
|
||||||
bool isGrounded = MovementSystem.Instance._isGrounded;
|
bool isGrounded = MovementSystem.Instance._isGrounded;
|
||||||
bool isFlying = MovementSystem.Instance.flying;
|
bool isFlying = MovementSystem.Instance.flying;
|
||||||
bool playRunningAnimation = BodySystem.PlayRunningAnimationInFullBody;
|
bool playRunningAnimation = BodySystem.PlayRunningAnimationInFullBody;
|
||||||
|
@ -257,128 +264,6 @@ internal static class IKSystemPatches
|
||||||
__instance.applyOriginalHipPosition = true;
|
__instance.applyOriginalHipPosition = true;
|
||||||
__instance.applyOriginalHipRotation = true;
|
__instance.applyOriginalHipRotation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
|
||||||
[HarmonyPatch(typeof(IKSystem), nameof(IKSystem.InitializeHalfBodyIK))]
|
|
||||||
private static void Postfix_IKSystem_InitializeHalfBodyIK(ref IKSystem __instance)
|
|
||||||
{
|
|
||||||
if (!IKFixes.EntryUseIKPose.Value) return;
|
|
||||||
|
|
||||||
__instance._poseHandler.GetHumanPose(ref __instance.humanPose);
|
|
||||||
|
|
||||||
for (int i = 0; i < IKPoseMuscles.Length; i++)
|
|
||||||
{
|
|
||||||
__instance.ApplyMuscleValue((MuscleIndex)i, IKPoseMuscles[i], ref __instance.humanPose.muscles);
|
|
||||||
}
|
|
||||||
__instance.humanPose.bodyPosition = Vector3.up;
|
|
||||||
__instance.humanPose.bodyRotation = Quaternion.identity;
|
|
||||||
__instance._poseHandler.SetHumanPose(ref __instance.humanPose);
|
|
||||||
|
|
||||||
// recentering avatar so it doesnt need to step from random place on switch
|
|
||||||
IKSystem.vrik.transform.localPosition = Vector3.zero;
|
|
||||||
IKSystem.vrik.transform.localRotation = Quaternion.identity;
|
|
||||||
// janky fix, initializing early with correct pose
|
|
||||||
IKSystem.vrik.solver.Initiate(IKSystem.vrik.transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly float[] IKPoseMuscles = new float[]
|
|
||||||
{
|
|
||||||
0.00133321f,
|
|
||||||
8.195831E-06f,
|
|
||||||
8.537738E-07f,
|
|
||||||
-0.002669832f,
|
|
||||||
-7.651234E-06f,
|
|
||||||
-0.001659694f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0.04213953f,
|
|
||||||
0.0003007996f,
|
|
||||||
-0.008032114f,
|
|
||||||
-0.03059979f,
|
|
||||||
-0.0003182998f,
|
|
||||||
0.009640567f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0f,
|
|
||||||
0.5768794f,
|
|
||||||
0.01061097f,
|
|
||||||
-0.1127839f,
|
|
||||||
0.9705755f,
|
|
||||||
0.07972051f,
|
|
||||||
-0.0268422f,
|
|
||||||
0.007237188f,
|
|
||||||
0f,
|
|
||||||
0.5768792f,
|
|
||||||
0.01056608f,
|
|
||||||
-0.1127519f,
|
|
||||||
0.9705756f,
|
|
||||||
0.07971933f,
|
|
||||||
-0.02682396f,
|
|
||||||
0.007229362f,
|
|
||||||
0f,
|
|
||||||
-5.651802E-06f,
|
|
||||||
-3.034899E-07f,
|
|
||||||
0.4100508f,
|
|
||||||
0.3610304f,
|
|
||||||
-0.0838329f,
|
|
||||||
0.9262537f,
|
|
||||||
0.1353517f,
|
|
||||||
-0.03578902f,
|
|
||||||
0.06005657f,
|
|
||||||
-4.95989E-06f,
|
|
||||||
-1.43007E-06f,
|
|
||||||
0.4096187f,
|
|
||||||
0.363263f,
|
|
||||||
-0.08205152f,
|
|
||||||
0.9250782f,
|
|
||||||
0.1345718f,
|
|
||||||
-0.03572125f,
|
|
||||||
0.06055461f,
|
|
||||||
-1.079177f,
|
|
||||||
0.2095419f,
|
|
||||||
0.6140652f,
|
|
||||||
0.6365265f,
|
|
||||||
0.6683931f,
|
|
||||||
-0.4764312f,
|
|
||||||
0.8099416f,
|
|
||||||
0.8099371f,
|
|
||||||
0.6658203f,
|
|
||||||
-0.7327053f,
|
|
||||||
0.8113618f,
|
|
||||||
0.8114051f,
|
|
||||||
0.6643661f,
|
|
||||||
-0.40341f,
|
|
||||||
0.8111364f,
|
|
||||||
0.8111367f,
|
|
||||||
0.6170399f,
|
|
||||||
-0.2524227f,
|
|
||||||
0.8138723f,
|
|
||||||
0.8110135f,
|
|
||||||
-1.079171f,
|
|
||||||
0.2095456f,
|
|
||||||
0.6140658f,
|
|
||||||
0.6365255f,
|
|
||||||
0.6683878f,
|
|
||||||
-0.4764301f,
|
|
||||||
0.8099402f,
|
|
||||||
0.8099376f,
|
|
||||||
0.6658241f,
|
|
||||||
-0.7327023f,
|
|
||||||
0.8113653f,
|
|
||||||
0.8113793f,
|
|
||||||
0.664364f,
|
|
||||||
-0.4034042f,
|
|
||||||
0.811136f,
|
|
||||||
0.8111364f,
|
|
||||||
0.6170469f,
|
|
||||||
-0.2524345f,
|
|
||||||
0.8138595f,
|
|
||||||
0.8110138f
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class PlayerSetupPatches
|
internal static class PlayerSetupPatches
|
||||||
|
@ -392,34 +277,30 @@ internal static class PlayerSetupPatches
|
||||||
[HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.ResetIk))]
|
[HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.ResetIk))]
|
||||||
private static bool Prefix_PlayerSetup_ResetIk()
|
private static bool Prefix_PlayerSetup_ResetIk()
|
||||||
{
|
{
|
||||||
if (IKSystem.vrik == null) return false;
|
if (IKSystem.vrik == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
CVRMovementParent currentParent = MovementSystem.Instance._currentParent;
|
CVRMovementParent currentParent = MovementSystem.Instance._currentParent;
|
||||||
if (currentParent != null && currentParent._referencePoint != null)
|
if (currentParent == null || currentParent._referencePoint == null)
|
||||||
{
|
return true;
|
||||||
// Get current position, VR pivots around VR camera
|
|
||||||
Vector3 currentPosition = MovementSystem.Instance.rotationPivot.transform.position;
|
// Get current position, VR pivots around VR camera
|
||||||
currentPosition.y = IKSystem.vrik.transform.position.y; // set pivot to floor
|
Vector3 currentPosition = MovementSystem.Instance.rotationPivot.transform.position;
|
||||||
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
|
currentPosition.y = IKSystem.vrik.transform.position.y; // set pivot to floor
|
||||||
|
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
|
||||||
|
|
||||||
// Convert to delta position (how much changed since last frame)
|
// Convert to delta position (how much changed since last frame)
|
||||||
Vector3 deltaPosition = currentPosition - lastMovementPosition;
|
Vector3 deltaPosition = currentPosition - lastMovementPosition;
|
||||||
Quaternion deltaRotation = Quaternion.Inverse(lastMovementRotation) * currentRotation;
|
Quaternion deltaRotation = Quaternion.Inverse(lastMovementRotation) * currentRotation;
|
||||||
|
|
||||||
// Prevent targeting other parent position
|
// Prevent targeting previous movement parent
|
||||||
if (lastMovementParent == currentParent || lastMovementParent == null)
|
if (lastMovementParent == currentParent || lastMovementParent == null)
|
||||||
{
|
IKSystem.vrik.solver.AddPlatformMotion(deltaPosition, deltaRotation, currentPosition);
|
||||||
// Add platform motion to IK solver
|
|
||||||
IKSystem.vrik.solver.AddPlatformMotion(deltaPosition, deltaRotation, currentPosition);
|
lastMovementParent = currentParent;
|
||||||
}
|
lastMovementPosition = currentPosition;
|
||||||
|
lastMovementRotation = currentRotation;
|
||||||
// Store for next frame
|
|
||||||
lastMovementParent = currentParent;
|
return false;
|
||||||
lastMovementPosition = currentPosition;
|
|
||||||
lastMovementRotation = currentRotation;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,2 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project Sdk="Microsoft.NET.Sdk"/>
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="UIExpansionKit">
|
||||||
|
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\UIExpansionKit.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
21
IKFixes/Integrations/UIExKitAddon.cs
Normal file
21
IKFixes/Integrations/UIExKitAddon.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using MelonLoader;
|
||||||
|
using UIExpansionKit.API;
|
||||||
|
|
||||||
|
namespace NAK.IKFixes.Integrations;
|
||||||
|
|
||||||
|
public static class UIExKitAddon
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
var settings = ExpansionKitApi.GetSettingsCategory(IKFixes.SettingsCategory);
|
||||||
|
settings.AddSimpleButton("Reset Settings (Only visually updates bool values, UIExpansionKit bug!)", ResetSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ResetSettings()
|
||||||
|
{
|
||||||
|
foreach (MelonPreferences_Entry setting in IKFixes.Category.Entries)
|
||||||
|
setting.ResetToDefault();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,41 +4,47 @@ namespace NAK.IKFixes;
|
||||||
|
|
||||||
public class IKFixes : MelonMod
|
public class IKFixes : MelonMod
|
||||||
{
|
{
|
||||||
|
internal const string SettingsCategory = nameof(IKFixes);
|
||||||
|
|
||||||
public static readonly MelonPreferences_Category Category =
|
public static readonly MelonPreferences_Category Category =
|
||||||
MelonPreferences.CreateCategory(nameof(IKFixes));
|
MelonPreferences.CreateCategory(SettingsCategory);
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<bool> EntryUseFakeRootAngle =
|
public static readonly MelonPreferences_Entry<bool> EntryUseFakeRootAngle =
|
||||||
Category.CreateEntry("Use Fake Root Angle", true, description: "Emulates maxRootAngle. This fixes feet pointing in direction of head when looking around.");
|
Category.CreateEntry("Use Fake Root Angle", true, description: "Emulates maxRootAngle. This fixes feet pointing in direction of head when looking around.");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<float> EntryFakeRootAngleLimit =
|
public static readonly MelonPreferences_Entry<float> EntryFakeRootAngleLimit =
|
||||||
Category.CreateEntry("Fake Root Angle Limit", 25f, description: "Specifies the maximum angle the lower body can have relative to the head when rotating.");
|
Category.CreateEntry("Fake Root Angle Limit (25f)", 25f, description: "Specifies the maximum angle the lower body can have relative to the head when rotating.");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<float> EntryNeckStiffness =
|
public static readonly MelonPreferences_Entry<float> EntryNeckStiffness =
|
||||||
Category.CreateEntry("Neck Stiffness", 0.2f, description: "Neck stiffness.");
|
Category.CreateEntry("Neck Stiffness (0.2f)", 0.2f, description: "Neck stiffness.");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<float> EntryBodyRotStiffness =
|
public static readonly MelonPreferences_Entry<float> EntryBodyRotStiffness =
|
||||||
Category.CreateEntry("Body Rot Stiffness", 0.1f, description: "Body rotation stiffness.");
|
Category.CreateEntry("Body Rot Stiffness (0.1f)", 0.1f, description: "Body rotation stiffness.");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<float> EntryRotateChestByHands =
|
public static readonly MelonPreferences_Entry<float> EntryRotateChestByHands =
|
||||||
Category.CreateEntry("Rot Chest By Hands", 1f, description: "Rotate chest by hands.");
|
Category.CreateEntry("Rot Chest By Hands (1f)", 1f, description: "Rotate chest by hands.");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<float> EntryBendToTargetWeight =
|
public static readonly MelonPreferences_Entry<float> EntryBendToTargetWeight =
|
||||||
Category.CreateEntry("Leg Bend To Target", 1f, description: "Leg bend to target weight");
|
Category.CreateEntry("Leg Bend To Target (1f)", 1f, description: "Leg bend to target weight");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<bool> EntryAssignRemainingTrackers =
|
public static readonly MelonPreferences_Entry<bool> EntryAssignRemainingTrackers =
|
||||||
Category.CreateEntry("Assign Remaining Trackers", true, description: "Should the game calibrate any additional trackers as secondary trackers for already-tracked points?");
|
Category.CreateEntry("Assign Remaining Trackers (true)", true, description: "Should the game calibrate any additional trackers as secondary trackers for already-tracked points?");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<bool> EntryUseIKPose =
|
|
||||||
Category.CreateEntry("Use IK Pose", true, description: "Should an IKPose be used after VRIK initialization? This can fix some issues with feet targeting.");
|
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<bool> EntryNetIKPass =
|
|
||||||
Category.CreateEntry("Network IK Pass", true, description: "Should NetIK pass be applied? This fixes a bunch of small rotation errors after VRIK is run.");
|
|
||||||
|
|
||||||
public override void OnInitializeMelon()
|
public override void OnInitializeMelon()
|
||||||
{
|
{
|
||||||
ApplyPatches(typeof(HarmonyPatches.BodySystemPatches));
|
ApplyPatches(typeof(HarmonyPatches.BodySystemPatches));
|
||||||
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
|
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
|
||||||
ApplyPatches(typeof(HarmonyPatches.IKSystemPatches));
|
ApplyPatches(typeof(HarmonyPatches.IKSystemPatches));
|
||||||
|
InitializeIntegration("UI Expansion Kit", Integrations.UIExKitAddon.Initialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeIntegration(string modName, Action integrationAction)
|
||||||
|
{
|
||||||
|
if (RegisteredMelons.All(it => it.Info.Name != modName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LoggerInstance.Msg($"Initializing {modName} integration.");
|
||||||
|
integrationAction.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyPatches(Type type)
|
private void ApplyPatches(Type type)
|
||||||
|
|
|
@ -25,6 +25,6 @@ using System.Reflection;
|
||||||
namespace NAK.IKFixes.Properties;
|
namespace NAK.IKFixes.Properties;
|
||||||
internal static class AssemblyInfoParams
|
internal static class AssemblyInfoParams
|
||||||
{
|
{
|
||||||
public const string Version = "1.0.6";
|
public const string Version = "1.0.7";
|
||||||
public const string Author = "NotAKidoS";
|
public const string Author = "NotAKidoS";
|
||||||
}
|
}
|
|
@ -1,23 +1,24 @@
|
||||||
{
|
{
|
||||||
"_id": 142,
|
"_id": 142,
|
||||||
"name": "IKFixes",
|
"name": "IKFixes",
|
||||||
"modversion": "1.0.6",
|
"modversion": "1.0.7",
|
||||||
"gameversion": "2022r170p1",
|
"gameversion": "2023r171",
|
||||||
"loaderversion": "0.6.1",
|
"loaderversion": "0.6.1",
|
||||||
"modtype": "Mod",
|
"modtype": "Mod",
|
||||||
"author": "NotAKidoS",
|
"author": "NotAKidoS",
|
||||||
"description": "A few small fixes and configuration options to IK. Major ones are listed below:\n\n**FBT** - Fixes knee tracking, running animation direction, and animation bleeding into IK while calibrating/running. (no more chest tracker wiggle)\n\n**Halfbody** - Fixes footsteps while on a MovementParent, uses root angle offset to prevent feet from only pointing in head direction, and uses an IKPose to fix feet pointing upward.",
|
"description": "A few small fixes and configuration options to IK. Major ones are listed below:\n\n**FBT** - Fixes root rotation animation bleeding, chest tracking, locomotion animations, and bend goal offsets.\n\n**Halfbody** - Fixes footsteps while on a Movement Parent & feet always pointing in head direction.",
|
||||||
"searchtags": [
|
"searchtags": [
|
||||||
"knee",
|
"knee",
|
||||||
"ik",
|
"ik",
|
||||||
"tracking",
|
"tracking",
|
||||||
"fix"
|
"fix",
|
||||||
|
"chest"
|
||||||
],
|
],
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"None"
|
"None"
|
||||||
],
|
],
|
||||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r8/IKFixes.dll",
|
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r8/IKFixes.dll",
|
||||||
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/IKFixes/",
|
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/IKFixes/",
|
||||||
"changelog": "- Added fix for animations affecting root to bleed into IK.\n- Use an IKPose after HalfbodyIK Initialization.\n- Fixed patch to leg solver that prevented lower leg rotation while using knee trackers.\n- Adjusted elbow target offsets for a balance between accuracy and stability. Makes StandableFBE-tracked elbows feel much better to use.\n- Added option to disable AssignRemainingTrackers feature.\n- Exposed a couple VRIK solver settings for more fine-tuning.",
|
"changelog": "- Updates for 2023r171\n- Removed unneeded settings (IKPose & NetIKPass).\n- Fixed halfbody fake root angle option.\n- Added Reset Settings UIExpansionKit button.",
|
||||||
"embedcolor": "f46e49"
|
"embedcolor": "f46e49"
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue