Last week after the team meeting and the feedback from our supervisor and the class "realistic eye movement based on the behaviour" was a possible good addition to our already reactive behaviour NPC.
I have looked into doing realistic eye behaviour using animation rigging that ties to the project I did in the last post. I believe personally I am new to the Unity Engine so I have spent some time understanding what my teammate Jungfeng did to make the blend shapes to have a "Happy" or "Sad" expression so that I can incorporate the realistic blinking.
Happy Face Expression:
Sad Face Expression:
Script elements:
The expressions are formed but the blend shapes transform into a certain location.
Creating realistic eye movements in characters can significantly enhance the immersive experience of video games, making interactions and scenes feel more lifelike.
To achieve this in Unity, leveraging blend shapes (also known as morph targets) provides a powerful and flexible way to animate your characters' eyes realistically.
In this blog post, we'll dive into the scripting methods and classes required to implement such eye movement behaviours, alongside explaining the underlying principles that make these animations feel natural.
Scripting for Realistic Eye Movements
To script eye movements, we will create a simple C# script in Unity that allows us to control the blend shapes for eye movements programmatically.
Basic Script Structure
First, let's outline the basic script structure for controlling blend shapes:
using UnityEngine;
public class EyeMovement : MonoBehaviour
{
public SkinnedMeshRenderer skinnedMeshRenderer;
private int blinkShapeIndex; // The index of the blink blend shape
private int lookLeftShapeIndex; // Example additional blend shape indexes
void Start()
{
// Initialize blend shape indexes
// Note: These indexes must match the ones set up in your 3D modeling software
blinkShapeIndex = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("Blink");
lookLeftShapeIndex = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("LookLeft");
}
void Update()
{
// Example of setting blend shape weights
skinnedMeshRenderer.SetBlendShapeWeight(blinkShapeIndex, 50f); // Half blink
}
}
Adding Realism through Script
For realism, eye movements should not feel mechanical or uniform. Here are some tips to enhance realism:
- Random Blinking: Implement a routine that triggers blinking at random intervals, mimicking natural behaviour.
- Smooth Transitions: Use `Mathf.Lerp` or a tweening library like DoTween to smoothly transition between blend shapes, avoiding abrupt changes.
- Look Around: Implement logic that simulates natural eye movements as the character observes their surroundings. This could involve randomly selecting points for the character to look at and smoothly transitioning their gaze.
Implementing Random Blinking
Here's an example of how you might implement random blinking:
IEnumerator BlinkRandomly()
{
while (true)
{
float waitTime = Random.Range(2f, 10f); // Random wait time between blinks
yield return new WaitForSeconds(waitTime);
// Trigger blink
DoBlink();
}
}
void DoBlink()
{
// Use DoTween or a similar library to smoothly transition the blink
float duration = 0.1f; // Duration of the blink
DOTween.To(() => skinnedMeshRenderer.GetBlendShapeWeight(blinkShapeIndex), x => skinnedMeshRenderer.SetBlendShapeWeight(blinkShapeIndex, x), 100, duration).SetLoops(2, LoopType.Yoyo);
}
Remember to start the `BlinkRandomly` coroutine in the `Start` method:
void Start()
{
// Initialization code here
StartCoroutine(BlinkRandomly());
}
```
Conclusion
These are basic methods that I have learnt that can be used for realistic behaviours by utilizing blended shapes and thoughtful scripting, maybe I can create characters with eye movements that feel alive and engaging.
I am going to Experiment with different blend shapes and scripts to find the perfect balance for our characters.
Comments