UniVRM/Assets/VRM10/Runtime/FastSpringBone/System/FastSpringBoneService.cs
Isamu Mogi 698a4dbc8e Unity2022.2.4以下と2021.3.17以下でFindObjectBy系APIが存在しないのに対応
FindObjectsBy系のAPIは、UniVRMがサポートしているUnityのうち、次の範囲のバージョンには存在しない。

- 2021.3.0~2021.3.17
- 2022.1.0~2022.1.24
- 2022.2.0~2022.2.4

そのため、該当するバージョンのUnityではコンパイルエラーが発生していた。UNITY_2022_3_OR_NEWERで分岐することで、旧APIと新APIを安全に選択するようにした。

厳密にはUNITY_2022_2_5_OR_NEWERを用いたいが、そのようなシンボルは存在していなかった。
2024-05-14 20:15:56 +09:00

106 lines
3.1 KiB
C#

using UnityEngine;
namespace UniVRM10.FastSpringBones.System
{
[DefaultExecutionOrder(11010)]
/// <summary>
/// VRM-1.0 ではコンポーネントの処理順が規定されている
///
/// 1. ヒューマノイドボーンを解決
/// 2. 頭の位置が決まるのでLookAtを解決
/// 3. ExpressionUpdate
/// 4. コンストレイントを解決
/// 5. SpringBoneを解決
///
/// 1~4 は Vrm10Runtime が管理し LateUpdate で処理される。
/// このクラスは DefaultExecutionOrder(11000) によりその後ろにまわる。
///
/// # [Manual update]
///
/// foreach(var vrmInstance in allVrm)
/// {
/// vrmInstance.UpdateType = None;
/// vrmInstance.Runtime.Process();
/// }
/// FastSpringBoneService.Instance.UpdateType = Manual;
/// FastSpringBoneService.Instance.ManualUpdate();
///
/// </summary>
public sealed class FastSpringBoneService : MonoBehaviour
{
public enum UpdateTypes
{
Manual,
LateUpdate,
}
[SerializeField, Header("Runtime")]
public UpdateTypes UpdateType = UpdateTypes.LateUpdate;
public FastSpringBoneBufferCombiner BufferCombiner { get; private set; }
private FastSpringBoneScheduler _fastSpringBoneScheduler;
private static FastSpringBoneService _instance;
public static FastSpringBoneService Instance
{
get
{
if (_instance) return _instance;
#if UNITY_2022_3_OR_NEWER
_instance = FindFirstObjectByType<FastSpringBoneService>();
#else
_instance = FindObjectOfType<FastSpringBoneService>();
#endif
if (_instance) return _instance;
var gameObject = new GameObject("FastSpringBone Service");
DontDestroyOnLoad(gameObject);
_instance = gameObject.AddComponent<FastSpringBoneService>();
return _instance;
}
}
/// <summary>
/// 専有しているインスタンスを破棄する
/// </summary>
public static void Free()
{
Destroy(_instance.gameObject);
_instance = null;
}
private void OnEnable()
{
BufferCombiner = new FastSpringBoneBufferCombiner();
_fastSpringBoneScheduler = new FastSpringBoneScheduler(BufferCombiner);
}
private void OnDisable()
{
BufferCombiner.Dispose();
_fastSpringBoneScheduler.Dispose();
}
private void LateUpdate()
{
if (UpdateType == UpdateTypes.LateUpdate)
{
_fastSpringBoneScheduler.Schedule(Time.deltaTime).Complete();
}
}
public void ManualUpdate(float deltaTime)
{
if (UpdateType != UpdateTypes.Manual)
{
throw new global::System.ArgumentException("require UpdateTypes.Manual");
}
_fastSpringBoneScheduler.Schedule(deltaTime).Complete();
}
}
}