Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: workaround VRCSDK bug where stale data is left in physbone state #231

Merged
merged 3 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `__Generated` folder is not removed after building avatar (#235)

### Fixed
- Workaround VRCSDK bug where stale PhysBones state could be retained over play mode transitions (#231)

### Changed

Expand Down
48 changes: 48 additions & 0 deletions Editor/VRChat/ForceReinitPhysBonesHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#region

using UnityEngine;
using VRC.Dynamics;
using VRC.SDK3.Dynamics.Contact.Components;
using VRC.SDK3.Dynamics.PhysBone.Components;
using VRC.SDKBase.Editor.BuildPipeline;

#endregion

namespace nadena.dev.ndmf.VRChat
{
/// <summary>
/// When domain reload is disabled, the VRChat physbones gizmo can leave outdated data in the VRCPhysBone component
/// when entering play mode. Force reinitialize the components to work around this issue.
///
/// Note that we only do this when entering play mode, as this is runtime state, not serialized state.
/// </summary>
public class ForceReinitPhysBonesHook : IVRCSDKPreprocessAvatarCallback
{
public int callbackOrder => int.MaxValue;

public bool OnPreprocessAvatar(GameObject avatarGameObject)
{
if (Application.isPlaying)
{
foreach (var physBone in avatarGameObject.GetComponentsInChildren<VRCPhysBone>(true))
{
physBone.InitTransforms(true);
physBone.InitParameters();
}

foreach (var collider in avatarGameObject.GetComponentsInChildren<VRCPhysBoneColliderBase>(true))
{
collider.UpdateShape();
}

foreach (var contact in avatarGameObject.GetComponentsInChildren<ContactBase>(true))
{
contact.UpdateShape();
contact.UpdateContact();
}
}

return true;
}
}
}
3 changes: 3 additions & 0 deletions Editor/VRChat/ForceReinitPhysBonesHook.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.