API Example -- Eyes Setup (boxHead)

NOTE: See the Eyes API documentation for API details.

// Script designed for use on the boxHead.v2.small model

using UnityEngine;
using CrazyMinnow.SALSA; // Use the CrazyMinnow.SALSA namespace

namespace DemoCode // change this to your custom namespace...
{
    public class BoxheadEyesRuntime : MonoBehaviour
    {     
        private void Awake()
        {   
            /*
                Variables
            */
            string head = "boxHead.v2.small";
            // Unity component that can store blendshapes
            SkinnedMeshRenderer smr;
            // Add Eyes instance to the game object
            Eyes eyes = gameObject.AddComponent<Eyes>();
            // Processing component used by the entire SALSA LipSync Suite
            QueueProcessor qp = gameObject.AddComponent<QueueProcessor>();

            /*
                System Properties
            */
            // Character root used in tracking calculations
            eyes.characterRoot = gameObject.transform;
            // Eyes reference to the QueueProcessor
            eyes.queueProcessor = qp;

            /*
                Head setup (Bone_Rotation_XY)
            */
            // Head template using the Bone_Rotation_XY rotation
            eyes.BuildHeadTemplate(Eyes.HeadTemplates.Bone_Rotation_XY);
            // Find and link the head bone
            eyes.heads[0].expData.controllerVars[0].bone = Eyes.FindTransform(eyes.characterRoot, head);
            // Name the head expression
            eyes.heads[0].expData.name = "head";
            // Name the head component
            eyes.heads[0].expData.components[0].name = "head";
            // Set a target offset so the head and eyes gaze vertically at the same point
            eyes.headTargetOffset.y = 0.225f;
            // Capture the min/max bone settings, head reverts to this orientation upon component disable
            eyes.CaptureMin(ref eyes.heads);
            eyes.CaptureMax(ref eyes.heads);

            /*
                Eyes setup (Blendshapes)
            */
            // Find and link the SkinnedMeshRenderer component so we can access the blendshapes
            smr = Eyes.FindTransform(eyes.characterRoot, head).GetComponent<SkinnedMeshRenderer>();
            // Eye template using blendshape controllers
            eyes.BuildEyeTemplate(Eyes.EyeTemplates.BlendShapes);
            // Boxhead uses one set of blendshapes for both eyes so we remove the second expression in the template
            eyes.RemoveExpression(ref eyes.eyes, 1);
            // Name the eye expression
            eyes.eyes[0].expData.name = "eyes";
            // Name the eye component
            eyes.eyes[0].expData.components[0].name = "eyes";
            // Link the SkinnedMeshRenderer and set blendshape indexes
            eyes.eyes[0].expData.controllerVars[0].smr = smr;
            eyes.eyes[0].expData.controllerVars[0].blendIndex = 4;
            eyes.eyes[0].expData.controllerVars[1].smr = smr;
            eyes.eyes[0].expData.controllerVars[1].blendIndex = 7;
            eyes.eyes[0].expData.controllerVars[2].smr = smr;
            eyes.eyes[0].expData.controllerVars[2].blendIndex = 5;
            eyes.eyes[0].expData.controllerVars[3].smr = smr;
            eyes.eyes[0].expData.controllerVars[3].blendIndex = 6;
            // Create and position the eye gizmo that tells Eyes where to calculate tracking from
            eyes.eyes[0].gizmo = eyes.CreateEyeGizmo(smr.name, eyes.characterRoot);
            eyes.eyes[0].gizmo.transform.parent = smr.transform;
            eyes.eyes[0].gizmo.transform.localPosition = new Vector3(0f, 0.2239f, 0.1624f);

            /*
                Eyelid setup (Blendshapes)
            */
            // Eyelid template using blendshapes with the Upper lid option
            eyes.BuildEyelidTemplate(Eyes.EyelidTemplates.BlendShapes, Eyes.EyelidSelection.Upper);
            // Boxhead uses one set of blendshapes for both eyelids so we remove the second expression in the template
            eyes.RemoveExpression(ref eyes.blinklids, 1);
            // Name the eyelid expression
            eyes.blinklids[0].expData.name = "eyelids";
            // Name the eyelid component
            eyes.blinklids[0].expData.components[0].name = "eyelids";
            // Link the SkinnedMeshRenderer and set the blendshape indexes
            eyes.blinklids[0].expData.controllerVars[0].smr = smr;
            eyes.blinklids[0].expData.controllerVars[0].blendIndex = 8;

            /*
                Boxhead has no body, we'll add an empty parent as his body for head tracking
            */
            if (eyes.characterRoot == eyes.heads[0].expData.controllerVars[0].bone)
                eyes.characterRoot = eyes.AddParent(gameObject.transform);

            /*
                Initialization
            */            
            // Controller initialization, update any runtime controllers we plan to use
            eyes.UpdateRuntimeExpressionControllers(ref eyes.heads);
            eyes.UpdateRuntimeExpressionControllers(ref eyes.eyes);
            eyes.UpdateRuntimeExpressionControllers(ref eyes.blinklids);
            // Initialize the Eyes module last. This builds the reference gizmos, captures offsets, sets timers, etc.
            eyes.Initialize();
        }
    }
}