132 lines
4.0 KiB
C#
132 lines
4.0 KiB
C#
#pragma warning disable 0414, 0649
|
|
using UniGLTF;
|
|
using UnityEngine;
|
|
|
|
|
|
namespace VRM
|
|
{
|
|
public class VRMLookAtBoneApplyer : MonoBehaviour, IVRMComponent
|
|
{
|
|
public bool DrawGizmo = false;
|
|
|
|
[SerializeField]
|
|
public OffsetOnTransform LeftEye;
|
|
|
|
[SerializeField]
|
|
public OffsetOnTransform RightEye;
|
|
|
|
[SerializeField, Header("Degree Mapping")]
|
|
public CurveMapper HorizontalOuter = new CurveMapper(90.0f, 10.0f);
|
|
|
|
[SerializeField]
|
|
public CurveMapper HorizontalInner = new CurveMapper(90.0f, 10.0f);
|
|
|
|
[SerializeField]
|
|
public CurveMapper VerticalDown = new CurveMapper(90.0f, 10.0f);
|
|
|
|
[SerializeField]
|
|
public CurveMapper VerticalUp = new CurveMapper(90.0f, 10.0f);
|
|
|
|
public void OnImported(VRMImporterContext context)
|
|
{
|
|
var animator = GetComponent<Animator>();
|
|
if (animator != null)
|
|
{
|
|
LeftEye = OffsetOnTransform.Create(animator.GetBoneTransform(HumanBodyBones.LeftEye));
|
|
RightEye = OffsetOnTransform.Create(animator.GetBoneTransform(HumanBodyBones.RightEye));
|
|
}
|
|
|
|
var gltfFirstPerson = context.VRM.firstPerson;
|
|
HorizontalInner.Apply(gltfFirstPerson.lookAtHorizontalInner);
|
|
HorizontalOuter.Apply(gltfFirstPerson.lookAtHorizontalOuter);
|
|
VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown);
|
|
VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp);
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
HorizontalInner.OnValidate();
|
|
HorizontalOuter.OnValidate();
|
|
VerticalUp.OnValidate();
|
|
VerticalDown.OnValidate();
|
|
}
|
|
|
|
VRMLookAtHead m_head;
|
|
|
|
void Start()
|
|
{
|
|
m_head = GetComponent<VRMLookAtHead>();
|
|
if (m_head == null)
|
|
{
|
|
enabled = false;
|
|
Debug.LogError("[VRMLookAtBoneApplyer]VRMLookAtHead not found");
|
|
return;
|
|
}
|
|
m_head.YawPitchChanged += ApplyRotations;
|
|
LeftEye.Setup();
|
|
RightEye.Setup();
|
|
}
|
|
|
|
#region Gizmo
|
|
static void DrawMatrix(Matrix4x4 m, float size)
|
|
{
|
|
Gizmos.matrix = m;
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawLine(Vector3.zero, Vector3.right * size);
|
|
Gizmos.color = Color.green;
|
|
Gizmos.DrawLine(Vector3.zero, Vector3.up * size);
|
|
Gizmos.color = Color.blue;
|
|
Gizmos.DrawLine(Vector3.zero, Vector3.forward * size);
|
|
}
|
|
|
|
const float SIZE = 0.5f;
|
|
|
|
private void OnDrawGizmos()
|
|
{
|
|
if (DrawGizmo)
|
|
{
|
|
if (LeftEye.Transform != null & RightEye.Transform != null)
|
|
{
|
|
DrawMatrix(LeftEye.WorldMatrix, SIZE);
|
|
DrawMatrix(RightEye.WorldMatrix, SIZE);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
void ApplyRotations(float yaw, float pitch)
|
|
{
|
|
// horizontal
|
|
float leftYaw, rightYaw;
|
|
if (yaw < 0)
|
|
{
|
|
leftYaw = -HorizontalOuter.Map(-yaw);
|
|
rightYaw = -HorizontalInner.Map(-yaw);
|
|
}
|
|
else
|
|
{
|
|
rightYaw = HorizontalOuter.Map(yaw);
|
|
leftYaw = HorizontalInner.Map(yaw);
|
|
}
|
|
|
|
// vertical
|
|
if (pitch < 0)
|
|
{
|
|
pitch = -VerticalDown.Map(-pitch);
|
|
}
|
|
else
|
|
{
|
|
pitch = VerticalUp.Map(pitch);
|
|
}
|
|
|
|
// Apply
|
|
if (LeftEye.Transform != null && RightEye.Transform != null)
|
|
{
|
|
// 目に値を適用する
|
|
LeftEye.Transform.rotation = LeftEye.InitialWorldMatrix.ExtractRotation() * Matrix4x4.identity.YawPitchRotation(leftYaw, pitch);
|
|
RightEye.Transform.rotation = RightEye.InitialWorldMatrix.ExtractRotation() * Matrix4x4.identity.YawPitchRotation(rightYaw, pitch);
|
|
}
|
|
}
|
|
}
|
|
}
|