Skip to content

[BUG] VRM1 Eyetracking #536

@PAMEH-2045

Description

@PAMEH-2045

What happened?

In UniVRM10 0.128.3, there are 3 ways to set LookAtInput:

Since Animation is not the case and YawPitchValue is used historically, SetYawPitchManually() is the way

Patch for DoEye() would look something like this:

void DoEye()
 {
        var mouse = Input.mousePosition;
        var world = mainCam.ScreenToWorldPoint(new Vector3(mouse.x, mouse.y, mainCam.nearClipPlane));
-       if (vrm10 && vrmLookAtTarget)
-       {
-               vrmLookAtTarget.position = world;
-               var par = vrmLookAtTarget.parent ?? transform;
-               Matrix4x4 mtx = Matrix4x4.TRS(par.position, par.rotation, Vector3.one);
-               var (rawYaw, rawPitch) = mtx.CalcYawPitch(world);
-               float yaw = Mathf.Clamp(-rawYaw, -eyeYawLimit, eyeYawLimit);
-               float pitch = Mathf.Clamp(rawPitch, -eyePitchLimit, eyePitchLimit);
-               var currFwd = vrmLookAtTarget.forward;
-               var tgtFwd = Quaternion.Euler(-pitch, yaw, 0f) * Vector3.forward;
-               var smooth = Vector3.Slerp(currFwd, tgtFwd, Time.deltaTime * eyeSmoothness);
-               vrmLookAtTarget.rotation = Quaternion.LookRotation(smooth);
-               return;
-       }
        if (!leftEyeBone || !rightEyeBone || !eyeCenter) return;  // VRM1 Expression LookAt operates fine without any eye bones
        eyeCenter.position = (leftEyeBone.position + rightEyeBone.position) * 0.5f;
        var dir = (world - eyeCenter.position).normalized;
        var localDir = eyeCenter.parent.InverseTransformDirection(dir);  // Parent of eyeCenter is not always head bone. 
        // This is not according to VRM standard and ME recommendations, but i would make a check for shared parent for both eye bones
        float eyeYaw = Mathf.Clamp(Mathf.Atan2(localDir.x, localDir.z) * Mathf.Rad2Deg, -eyeYawLimit, eyeYawLimit);
        float eyePitch = Mathf.Clamp(Mathf.Asin(localDir.y) * Mathf.Rad2Deg, -eyePitchLimit, eyePitchLimit);
+       if (vrm10 && vrmLookAtTarget)
+       {
+               var smoothYaw = Mathf.Lerp(vrm10.Runtime.LookAt.Yaw, eyeYaw, Time.deltaTime * eyeSmoothness);
+               var smoothPitch = Mathf.Lerp(vrm10.Runtime.LookAt.Pitch, eyePitch, Time.deltaTime * eyeSmoothness);
+
+               vrm10.Runtime.LookAt.SetYawPitchManually(smoothYaw, smoothPitch);
+               return;
+       }
        var eyeRot = Quaternion.Euler(-eyePitch, eyeYaw, 0f);
        leftEyeDriver.localRotation = Quaternion.Slerp(leftEyeDriver.localRotation, eyeRot, Time.deltaTime * eyeSmoothness);
        rightEyeDriver.localRotation = Quaternion.Slerp(rightEyeDriver.localRotation, eyeRot, Time.deltaTime * eyeSmoothness);

PS If you have "eyes barely moving", check out Look At settings in VRM1 ScriptableObject.
Formula for Curve*RangeDegree:

public float Map(float src)
{
// https://github.com/vrm-c/UniVRM/issues/2452
var t = Mathf.Clamp01(src / Mathf.Max(0.001f, CurveXRangeDegree));
return t * CurveYRangeDegree;
}

Steps to Reproduce

App Version

2.1.4

Store Edition

GitHub Edition

Confirmation

  • I confirm this report includes only one bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions