LookAt
Updated: 01/30/2020
Summary
LookAt is a function that manipulates the value of the desired parameter to follow a specific coordinate.
By customizing the coordinates to be tracked by the user, Cubism models can be made to track specific GameObjects and other objects.
Click here for more information on how to use LookAt.
LookAt in Cubism SDK for Unity consists of three types of elements.
- Components for specifying parameters to be tracked
- Components that apply values to each parameter
- Manipulation of the values applied in number 2
1. Components for Specifying Parameters to Be Tracked
To specify parameters to be followed by LookAt, use CubismLookParameter.
CubismLookParameter is used by attaching it to GameObjects placed under [Prefab root]/Parameters/.
The parameter with the same ID as the GameObject to which it is attached is treated as a parameter for eye tracking.
CubismLookParameter has two setting items, Axis and Factor.
/// <summary> /// Look axis. /// </summary> [SerializeField] public CubismLookAxis Axis; /// <summary> /// Factor. /// </summary> [SerializeField] public float Factor;
- Axis
Sets which axis values of the input coordinates will be used.
There are three items that can be set: X, Y, and Z.
namespace Live2D.Cubism.Framework.LookAt { /// <summary> /// Look axis. /// </summary> public enum CubismLookAxis { /// <summary> /// X axis. /// </summary> X, /// <summary> /// Y axis. /// </summary> Y, /// <summary> /// Z axis. /// </summary> Z } }
- Factor
Sets the correction value to the value to be applied.
The coordinates entered will be processed to a value in the range of -1.0f to 1.0f when applied.
The value set for Factor is a multiplier that multiplies the input values to match the minimum and maximum values of each parameter.
/// <summary> /// Updates and evaluates the instance. /// </summary> /// <param name="targetOffset">Delta to target.</param> /// <returns>Evaluation result.</returns> internal float TickAndEvaluate(Vector3 targetOffset) { var result = (Axis == CubismLookAxis.X) ? targetOffset.x : targetOffset.y; if (Axis == CubismLookAxis.Z) { result = targetOffset.z; } return result * Factor; }
CubismLookParameter is also used as a marker for CubismLookController to obtain references.
2. Components that Apply Values to Each Parameter
Use CubismLookController to apply eye tracking to each parameter.
When using CubismLookController, attach it to the root of Cubism’s Prefab.
Gets a reference to all CubismLookParameters attached to Prefab during initialization of CubismLookController.
When parameters for eye tracking are added/removed during execution, CubismLookController.Refresh() is called to get the references again.
/// <summary> /// Refreshes the controller. Call this method after adding and/or removing <see cref="CubismLookParameter"/>s. /// </summary> public void Refresh() { var model = this.FindCubismModel(); // Catch sources and destinations. Sources = model .Parameters .GetComponentsMany<CubismLookParameter>(); Destinations = new CubismParameter[Sources.Length]; for (var i = 0; i < Sources.Length; ++i) { Destinations[i] = Sources[i].GetComponent<CubismParameter>(); } // Get cubism update controller. HasUpdateController = (GetComponent<CubismUpdateController>() != null); } ... /// <summary> /// Called by Unity. Makes sure cache is initialized. /// </summary> private void Start() { // Default center if necessary. if (Center == null) { Center = transform; } // Initialize cache. Refresh(); }
CubismLookController applies the coordinates returned by the object set to CubismLookController.Target to the parameters marked by CubismLookParameter at the timing of LateUpdate() in every frame.
// Update position. var position = LastPosition; GoalPosition = transform.InverseTransformPoint(target.GetPosition()) - Center.localPosition; if (position != GoalPosition) { position = Vector3.SmoothDamp( position, GoalPosition, ref VelocityBuffer, Damping); } // Update sources and destinations. for (var i = 0; i < Destinations.Length; ++i) { Destinations[i].BlendToValue(BlendMode, Sources[i].TickAndEvaluate(position)); } // Store position. LastPosition = position;
3. Manipulation of the Values Applied in Number 2
As described in “2. Components that Apply Values to Each Parameter,” the coordinates that CubismLookController applies to the parameters for eye tracking return the object set in CubismLookController.Target.
This is an implementation of the ICubismLookTarget interface, which can be implemented by the user to track the model to desired coordinates.
using UnityEngine; namespace Live2D.Cubism.Framework.LookAt { /// <summary> /// Target to look at. /// </summary> public interface ICubismLookTarget { /// <summary> /// Gets the position of the target. /// </summary> /// <returns>The position of the target in world space.</returns> Vector3 GetPosition(); /// <summary> /// Gets whether the target is active. /// </summary> /// <returns><see langword="true"/> if the target is active; <see langword="false"/> otherwise.</returns> bool IsActive(); } }
- GetPosition()
Returns the coordinates to be followed.
The coordinates returned here are treated as world coordinates.
- IsActive()
Returns whether the tracking is valid or not.
Follows only when true is returned.
CubismLookTargetBehaviour is included in the SDK as an example implementation of ICubismLookTarget.
CubismLookTargetBehaviour will be a sample that returns the coordinates of the GameObject to which it is attached.
using UnityEngine; namespace Live2D.Cubism.Framework.LookAt { /// <summary> /// Straight-forward <see cref="ICubismLookTarget"/> <see cref="MonoBehaviour"/>. /// </summary> public class CubismLookTargetBehaviour : MonoBehaviour, ICubismLookTarget { #region Implementation of ICubismLookTarget /// <summary> /// Gets the position of the target. /// </summary> /// <returns>The position of the target in world space.</returns> Vector3 ICubismLookTarget.GetPosition() { return transform.position; } /// <summary> /// Gets whether the target is active. /// </summary> /// <returns><see langword="true"/> if the target is active; <see langword="false"/> otherwise.</returns> bool ICubismLookTarget.IsActive() { return isActiveAndEnabled; } #endregion } }