Skip to main content

Eye movement using UV shifting

✍ Last Updated : September 5, 2022

🚪 Prequisite Knowledge (Optional)

UploadUnity’s Inmaterial Progressand shader

❓ Key Question / Problem / Issue

How to make character’s eye tracking an object

✅ Expected Output/Definition of Done

Character, which is a 3D animated object has his/her eye moving/following an object

🎁 Resulting Solution

Prerequisite

The model need to have both eye mapped in the same orientation (not mirrored). To check, simply adjust the eye material offset X to anything than 0.

Correct, both eyes looking in the same direction

Correct, both eyes looking in the same direction

Incorrect, the eyes UV mapping might be mirrored

Incorrect, the eyes UV mapping might be mirrored

Approximating the eye offset

The best practice is to calculate the eye offset by projecting it into a plane and scale down the plane by the eye radius divided by the actual distance between the eye position and target position. But the equation could be approximated by transforming the eyeTarget direction into the eye’s localSpace, divided by the eye’s radius. But since the model’s bone is scaled by 100 when exported to fbx, the projected vector also needs to be downscaled (divided) by 100.

Vector3 targetDirection = transform.InverseTransformPoint(eyeTarget.position - eyeCenterPosition.position);// - transform.InverseTransformPoint(eyeCenterPosition.position);
Vector3 projected       = targetDirection.normalized * 1f / (eyeRadius * 100);
projected.x             = Mathf.Clamp(projected.x + pupilOffsetOffset.x, -pupilOffsetLimit.x, pupilOffsetLimit.x) * (invertX ? -1 : 1);
projected.y             = -Mathf.Clamp(projected.y + pupilOffsetOffset.y, -pupilOffsetLimit.y, pupilOffsetLimit.y);
Vector2 pupilOffset     = new Vector2(projected.x, projected.y);
pupilMaterial.SetTextureOffset(pupilTextureName, pupilOffset);

Also, to make the eye movement more natural, the offsets need to be limited by certain value

Untitled