// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.UI { /// /// The Billboard class implements the behaviors needed to keep a GameObject oriented towards the user. /// [AddComponentMenu("Scripts/MRTK/SDK/Billboard")] public class Billboard : MonoBehaviour { /// /// The axis about which the object will rotate. /// public PivotAxis PivotAxis { get { return pivotAxis; } set { pivotAxis = value; } } [Tooltip("Specifies the axis about which the object will rotate.")] [SerializeField] private PivotAxis pivotAxis = PivotAxis.XY; /// /// The target we will orient to. If no target is specified, the main camera will be used. /// public Transform TargetTransform { get { return targetTransform; } set { targetTransform = value; } } [Tooltip("Specifies the target we will orient to. If no target is specified, the main camera will be used.")] [SerializeField] private Transform targetTransform; private void OnEnable() { if (targetTransform == null) { targetTransform = CameraCache.Main.transform; } } /// /// Keeps the object facing the camera. /// private void Update() { if (targetTransform == null) { return; } // Get a Vector that points from the target to the main camera. Vector3 directionToTarget = targetTransform.position - transform.position; bool useCameraAsUpVector = true; // Adjust for the pivot axis. switch (pivotAxis) { case PivotAxis.X: directionToTarget.x = 0.0f; useCameraAsUpVector = false; break; case PivotAxis.Y: directionToTarget.y = 0.0f; useCameraAsUpVector = false; break; case PivotAxis.Z: directionToTarget.x = 0.0f; directionToTarget.y = 0.0f; break; case PivotAxis.XY: useCameraAsUpVector = false; break; case PivotAxis.XZ: directionToTarget.x = 0.0f; break; case PivotAxis.YZ: directionToTarget.y = 0.0f; break; case PivotAxis.Free: default: // No changes needed. break; } // If we are right next to the camera the rotation is undefined. if (directionToTarget.sqrMagnitude < 0.001f) { return; } // Calculate and apply the rotation required to reorient the object if (useCameraAsUpVector) { transform.rotation = Quaternion.LookRotation(-directionToTarget, CameraCache.Main.transform.up); } else { transform.rotation = Quaternion.LookRotation(-directionToTarget); } } } }