How to set up Object Eye Tracking for a 3D model in Unity - Part 1
Published
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:
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.
This is what we get when we modify the texture offset of our pupil material:
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.
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.
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)
voidUpdate() {// 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!
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