普段から映像作品を制作するときに意外と厄介な揺れものがファサーっとなるやつを抑制するスクリプトです。
VRMのキャラクターモデルにcomponentするだけで抑制できるので、困っていた人は使ってみてください。
スクリプトなしバージョン
スクリプトありバージョン
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using VRM;
public class SpringBoneController : MonoBehaviour
{
public float stabilizationDuration = 0.5f; // 安定化する時間(秒)
private VRMSpringBone[] springBones;
private Dictionary<VRMSpringBone, (float stiffness, float dragForce)> originalParameters;
private bool wasInactive = true;
private Coroutine stabilizeCoroutine;
private void Awake()
{
springBones = GetComponentsInChildren<VRMSpringBone>(true);
originalParameters = new Dictionary<VRMSpringBone, (float, float)>();
foreach (var springBone in springBones)
{
originalParameters[springBone] = (springBone.m_stiffnessForce, springBone.m_dragForce);
}
}
private void OnEnable()
{
if (wasInactive)
{
wasInactive = false;
if (stabilizeCoroutine != null)
{
StopCoroutine(stabilizeCoroutine);
}
stabilizeCoroutine = StartCoroutine(StabilizeSpringBones());
}
}
private void OnDisable()
{
wasInactive = true;
if (stabilizeCoroutine != null)
{
StopCoroutine(stabilizeCoroutine);
stabilizeCoroutine = null;
}
RestoreOriginalParameters();
}
private IEnumerator StabilizeSpringBones()
{
foreach (var springBone in springBones)
{
springBone.m_stiffnessForce = 1000f; // 非常に高い剛性
springBone.m_dragForce = 1f; // 最大のドラッグフォース
}
yield return new WaitForSeconds(stabilizationDuration);
RestoreOriginalParameters();
stabilizeCoroutine = null;
}
private void RestoreOriginalParameters()
{
foreach (var springBone in springBones)
{
if (originalParameters.TryGetValue(springBone, out var originalValues))
{
springBone.m_stiffnessForce = originalValues.stiffness;
springBone.m_dragForce = originalValues.dragForce;
}
}
}
}