mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 14:29:25 +00:00
broken
This commit is contained in:
parent
26441f8b1e
commit
c7b16abd4f
27 changed files with 591 additions and 91 deletions
68
InteractionTest/AutoArmIK.cs
Normal file
68
InteractionTest/AutoArmIK.cs
Normal file
|
@ -0,0 +1,68 @@
|
|||
using UnityEngine;
|
||||
using RootMotion.FinalIK;
|
||||
|
||||
namespace NAK.InteractionTest;
|
||||
|
||||
public class AutoArmIK : MonoBehaviour
|
||||
{
|
||||
public bool calibrateOnStart = true;
|
||||
public Transform leftHand, rightHand;
|
||||
|
||||
Animator animator;
|
||||
ArmIK leftArmIK, rightArmIK;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (calibrateOnStart) CalibrateArmIK();
|
||||
}
|
||||
|
||||
public void CalibrateArmIK()
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
if (animator == null)
|
||||
{
|
||||
Debug.LogError("Animator component not found on the avatar.");
|
||||
return;
|
||||
}
|
||||
|
||||
leftArmIK = gameObject.AddComponent<ArmIK>();
|
||||
leftArmIK.solver.isLeft = true;
|
||||
rightArmIK = gameObject.AddComponent<ArmIK>();
|
||||
rightArmIK.solver.isLeft = false;
|
||||
|
||||
CreateHandTarget(HumanBodyBones.LeftHand, ref leftHand);
|
||||
CreateHandTarget(HumanBodyBones.RightHand, ref rightHand);
|
||||
|
||||
leftArmIK.solver.arm.target = leftHand;
|
||||
rightArmIK.solver.arm.target = rightHand;
|
||||
|
||||
SetArmIKChain(leftArmIK, HumanBodyBones.LeftShoulder, HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand);
|
||||
SetArmIKChain(rightArmIK, HumanBodyBones.RightShoulder, HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand);
|
||||
|
||||
leftArmIK.solver.IKPositionWeight = 1f;
|
||||
rightArmIK.solver.IKPositionWeight = 1f;
|
||||
}
|
||||
|
||||
private void CreateHandTarget(HumanBodyBones bone, ref Transform handTarget)
|
||||
{
|
||||
var boneTransform = animator.GetBoneTransform(bone);
|
||||
var handGO = new GameObject($"{boneTransform.name} Target");
|
||||
handTarget = handGO.transform;
|
||||
handTarget.position = boneTransform.position;
|
||||
|
||||
Vector3 sourceYWorld = boneTransform.TransformDirection(Vector3.up);
|
||||
handTarget.rotation = Quaternion.LookRotation(boneTransform.forward, sourceYWorld);
|
||||
}
|
||||
|
||||
private void SetArmIKChain(ArmIK armIK, HumanBodyBones shoulder, HumanBodyBones upperArm, HumanBodyBones lowerArm, HumanBodyBones hand)
|
||||
{
|
||||
armIK.solver.SetChain(
|
||||
animator.GetBoneTransform(HumanBodyBones.Chest),
|
||||
animator.GetBoneTransform(shoulder),
|
||||
animator.GetBoneTransform(upperArm),
|
||||
animator.GetBoneTransform(lowerArm),
|
||||
animator.GetBoneTransform(hand),
|
||||
animator.transform
|
||||
);
|
||||
}
|
||||
}
|
40
InteractionTest/GrabbableAvatar.cs
Normal file
40
InteractionTest/GrabbableAvatar.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using ABI_RC.Core;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.InteractionTest;
|
||||
|
||||
internal class GrabbableAvatar : MonoBehaviour
|
||||
{
|
||||
private static readonly HumanBodyBones[][] boneSequences = new[]
|
||||
{
|
||||
new[] { HumanBodyBones.Hips, HumanBodyBones.Spine, HumanBodyBones.Chest, HumanBodyBones.Neck, HumanBodyBones.Head },
|
||||
new[] { HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot },
|
||||
new[] { HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot },
|
||||
new[] { HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand },
|
||||
new[] { HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand }
|
||||
};
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var animator = GetComponent<Animator>();
|
||||
|
||||
for (int seqIndex = 0; seqIndex < boneSequences.Length; seqIndex++)
|
||||
{
|
||||
var boneSequence = boneSequences[seqIndex];
|
||||
|
||||
for (int i = 0; i < boneSequence.Length - 1; i++)
|
||||
{
|
||||
var fromBone = animator.GetBoneTransform(boneSequence[i]);
|
||||
var toBone = animator.GetBoneTransform(boneSequence[i + 1]);
|
||||
|
||||
var colliderName = new StringBuilder(fromBone.name)
|
||||
.Append("_to_")
|
||||
.Append(toBone.name)
|
||||
.ToString();
|
||||
|
||||
CVRTools.GenerateBoneCollider(fromBone, toBone, 1f, colliderName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
108
InteractionTest/GrabbingAvatar.cs
Normal file
108
InteractionTest/GrabbingAvatar.cs
Normal file
|
@ -0,0 +1,108 @@
|
|||
using UnityEngine;
|
||||
using RootMotion.FinalIK;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
|
||||
namespace NAK.InteractionTest;
|
||||
|
||||
internal class GrabbingAvatar : MonoBehaviour
|
||||
{
|
||||
VRIK m_vrik;
|
||||
|
||||
private bool m_isGrabbingLeft = false;
|
||||
private bool m_isGrabbingRight = false;
|
||||
|
||||
private Transform m_grabbedTransform = null;
|
||||
private Vector3 m_localOffset;
|
||||
private Quaternion m_localRotation;
|
||||
|
||||
public float m_grabRadius = 0.1f;
|
||||
public LayerMask m_grabLayerMask;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_vrik = GetComponent<VRIK>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
bool isGrabLeft = CVRInputManager.Instance.gripLeftValue >= 0.5f;
|
||||
bool isGrabRight = CVRInputManager.Instance.gripRightValue >= 0.5f;
|
||||
|
||||
if (isGrabLeft && !m_isGrabbingLeft)
|
||||
{
|
||||
m_isGrabbingLeft = true;
|
||||
OnGrab(Hand.Left);
|
||||
}
|
||||
else if (!isGrabLeft && m_isGrabbingLeft)
|
||||
{
|
||||
m_isGrabbingLeft = false;
|
||||
OnRelease(Hand.Left);
|
||||
}
|
||||
|
||||
if (isGrabRight && !m_isGrabbingRight)
|
||||
{
|
||||
m_isGrabbingRight = true;
|
||||
OnGrab(Hand.Right);
|
||||
}
|
||||
else if (!isGrabRight && m_isGrabbingRight)
|
||||
{
|
||||
m_isGrabbingRight = false;
|
||||
OnRelease(Hand.Right);
|
||||
}
|
||||
|
||||
if (m_isGrabbingLeft)
|
||||
{
|
||||
UpdateGrabbedHand(Hand.Left);
|
||||
}
|
||||
|
||||
if (m_isGrabbingRight)
|
||||
{
|
||||
UpdateGrabbedHand(Hand.Right);
|
||||
}
|
||||
}
|
||||
|
||||
void OnGrab(Hand hand)
|
||||
{
|
||||
// Find the closest grabbable object using a sphere cast
|
||||
Collider[] colliders = Physics.OverlapSphere(transform.position, m_grabRadius, m_grabLayerMask);
|
||||
if (colliders.Length > 0)
|
||||
{
|
||||
Collider closestCollider = colliders[0];
|
||||
float closestDistance = float.MaxValue;
|
||||
foreach (Collider collider in colliders)
|
||||
{
|
||||
float distance = (collider.transform.position - transform.position).magnitude;
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
closestCollider = collider;
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the grabbed transform and local position/rotation offset
|
||||
m_grabbedTransform = closestCollider.transform;
|
||||
m_localOffset = transform.InverseTransformVector(m_grabbedTransform.position - transform.position);
|
||||
m_localRotation = Quaternion.Inverse(transform.rotation) * m_grabbedTransform.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(Hand hand)
|
||||
{
|
||||
// Reset the grabbed transform and local position/rotation offset
|
||||
m_grabbedTransform = null;
|
||||
m_localOffset = Vector3.zero;
|
||||
m_localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
void UpdateGrabbedHand(Hand hand)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public enum Hand
|
||||
{
|
||||
Left,
|
||||
Right
|
||||
}
|
24
InteractionTest/HarmonyPatches.cs
Normal file
24
InteractionTest/HarmonyPatches.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using HarmonyLib;
|
||||
using ABI_RC.Core.Player;
|
||||
|
||||
namespace NAK.InteractionTest.HarmonyPatches;
|
||||
|
||||
class PuppetMasterPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PuppetMaster), nameof(PuppetMaster.AvatarInstantiated))]
|
||||
static void Postfix_PuppetMaster_SetupAvatar(ref PuppetMaster __instance)
|
||||
{
|
||||
__instance.avatarObject.AddComponent<AutoArmIK>();
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerSetupPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.SetupAvatar))]
|
||||
static void Postfix_PlayerSetup_SetupAvatar(ref PlayerSetup __instance)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
8
InteractionTest/InteractionTest.csproj
Normal file
8
InteractionTest/InteractionTest.csproj
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<ItemGroup>
|
||||
<Reference Include="ml_prm">
|
||||
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\ml_prm.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
26
InteractionTest/Main.cs
Normal file
26
InteractionTest/Main.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using MelonLoader;
|
||||
|
||||
namespace NAK.InteractionTest;
|
||||
|
||||
public class InteractionTest : MelonMod
|
||||
{
|
||||
internal static MelonLogger.Instance Logger;
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
ApplyPatches(typeof(HarmonyPatches.PuppetMasterPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
|
||||
}
|
||||
|
||||
void ApplyPatches(Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
HarmonyInstance.PatchAll(type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerInstance.Msg($"Failed while patching {type.Name}!");
|
||||
LoggerInstance.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
30
InteractionTest/Properties/AssemblyInfo.cs
Normal file
30
InteractionTest/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using MelonLoader;
|
||||
using NAK.InteractionTest.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.InteractionTest))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.InteractionTest))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.InteractionTest.InteractionTest),
|
||||
nameof(NAK.InteractionTest),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/AvatarScale"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonAdditionalDependencies("PlayerRagdollMod")]
|
||||
|
||||
namespace NAK.InteractionTest.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
16
InteractionTest/README.md
Normal file
16
InteractionTest/README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# InteractionTest
|
||||
|
||||
Makes "AvatarScale" parameter persistant across avatars.
|
||||
|
||||
Combined with AvatarScaleTool, this allows for crossa consistant scale when switching between avatars.
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation and is not affiliated with, supported by or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
23
InteractionTest/format.json
Normal file
23
InteractionTest/format.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": 126,
|
||||
"name": "AvatarScale",
|
||||
"modversion": "1.0.5",
|
||||
"gameversion": "2022r170",
|
||||
"loaderversion": "0.5.7",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Fixes two issues with the Avatar Advanced Settings buffers when loading remote avatars. In simple terms, it means 'fewer wardrobe malfunctions'.\n\nEmpty buffer (all 0/false) will no longer be applied on load.\nReceived AAS data is ignored until the wearer has loaded into the expected avatar.\n(The avatar will sit in its default state until the wearer has loaded and started syncing correct AAS)\nAAS will no longer be sent while switching avatar.\n\nPlease view the GitHub README for links to relevant feedback posts.",
|
||||
"searchtags": [
|
||||
"aas",
|
||||
"sync",
|
||||
"naked",
|
||||
"buffer"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r3/AvatarScale.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/AvatarScale/",
|
||||
"changelog": "",
|
||||
"embedcolor": "9b59b6"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue