As I said in my article on implementing hair physics in Unity, details are what give life to our models and this is especially important for eyes: moving eyes add a very polished appearance to our work.

In this article, I show you how to easily allow your models eyes to follow a moving object.

Offset Texture to Move the Pupil

A simple way to do this, is to offset the Eyes texture. Let’s bring up our model:

Model Picture
Bringing out my Model

Now go to your eye/pupil material, and change the texture offset to move the pupil around. If you are using a custom shader, you’ll need to expose a Vector2 property and plug it in your Sample Texture node (assuming you’re using Shadergraph). Else just use a simple lit or unlit shader on your material, for testing purposes.

Material texture offset property
Changing the offset

This is what we get when we modify the texture offset of our pupil material:

Demo Offsetting pupil texture
The Result

So, it seems offsetting the pupil texture is the way to go. Our next step will then be to create a script that controls the eye movement according to the position of a target object.

Tracking an object

To do this, create a sphere and put it at the level of your eyes in your model’s hierarchy. This is important, since we’ll be using the target’s local position as our offset.

Now we’ll create a script and call it “EyeTracking.cs”, and assign our eye materials to it.

  [Header("Materials Tracking")]
  public Material mLeftEyeMaterial;
  public Material mRightEyeMaterial;

Now in Update, we’ll simply set the texture offset to be equal to the local position of the target. There are 2 cases possible. If you are main texture of a standard shader provided by Unity, you can use the Material.mainTextureOffset property.

In my case however, I created a custom shader, with several textures stacked on each other and which are dependent on the same offset values. In this case, I created a Vector2 Property, which I called “Offset” so I need to open my shadergraph and get the reference value.

Getting the Offset property identifier from shader
Getting the Offset property Identifier from inside the shadergraph

Now that I have this identifier, I can modify it easily in my EyeTracking Script! (You can also modify the Reference provided in Shadergraph for convenience. I just left it as default)

void Update() {
    // set material offset
    mRightEyeMaterial.SetVector("Vector2_DDB245C2", transform.localPosition);
    mLeftEyeMaterial.SetVector("Vector2_DDB245C2", transform.localPosition);
}

Once this is done, add the references to the materials in your script, hit play and move the eye target around: you’ll see the pupils follow the movements of the target!

Model Pupils following Eyes Target
The Model's eyes follow the target

Continuation

This is just the basic setup, and you’ll see there are quite a few issues with our method.

In the Part 2, we’ll improve this by implementing the following:

  • Prevent eyes wrapping back
  • Setting a minimum and maximum offset to avoid fully white eyes
  • Performing a depth check on the target and implementing a default position for the eyes
  • Adjusting offset calculations for more realistic object tracking

Stay Tuned!

UPDATE: Part 2 of Object Eye Tracking in Unity has arrived, click here to read it!