UniVRM/Assets/VRM/Runtime/LookAt/LookAtTargetSwitcher.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

84 lines
2.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace VRM
{
public class LookAtTargetSwitcher : MonoBehaviour
{
[SerializeField]
List<Transform> m_targets = new List<Transform>();
[SerializeField, Range(0, 90.0f)]
float m_thresholdDegrees = 60.0f;
[SerializeField]
VRMLookAtHead m_lookAtHead;
[SerializeField]
Blinker m_blinker;
private void Reset()
{
#if UNITY_2022_3_OR_NEWER
m_lookAtHead = GameObject.FindFirstObjectByType<VRMLookAtHead>();
m_blinker = GameObject.FindFirstObjectByType<Blinker>();
#else
m_lookAtHead = GameObject.FindObjectOfType<VRMLookAtHead>();
m_blinker = GameObject.FindObjectOfType<Blinker>();
#endif
}
float CalcScore(Transform target)
{
return Vector3.Dot(m_lookAtHead.Head.forward, target.position - m_lookAtHead.Head.position);
}
Transform ChooseTarget()
{
Transform target = null;
float maxScore = 0;
var min = System.Math.Cos(m_thresholdDegrees * Mathf.Deg2Rad);
foreach (var x in m_targets)
{
var score = CalcScore(x);
if (score > min && score > maxScore)
{
maxScore = score;
target = x;
}
}
return target;
}
Transform m_lastTarget;
private void Update()
{
if (m_targets == null || m_targets.Count == 0) return;
var target = ChooseTarget();
if (target != m_lastTarget)
{
// blink
//Debug.Log("request");
m_lastTarget = target;
m_blinker.Request = true;
}
Vector3 targetPosition;
if (target == null)
{
// forward
targetPosition = m_lookAtHead.Head.position + m_lookAtHead.Head.forward * 20.0f;
}
else
{
targetPosition = target.position;
}
// half move
transform.position += (targetPosition - transform.position) * 0.5f;
}
}
}