rabidus-test/Assets/BNG Framework/Scripts/Components/RotateWithHMD.cs

99 lines
3.8 KiB
C#
Raw Normal View History

2023-07-24 16:38:13 +03:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BNG {
// This will rotate a transform along with a users headset. Useful for keeping an object aligned with the camera, independent of the player capsule collider.
public class RotateWithHMD : MonoBehaviour {
[Tooltip("The Transform to rotate along with")]
public Transform FollowTransform;
/// <summary>
/// The Character Capsule to rotate along with
/// </summary>
[Tooltip("The Character Capsule to rotate along with")]
public CharacterController Character;
/// <summary>
/// Offset to apply in local space to the hmdTransform
/// </summary>
public Vector3 Offset = new Vector3(0, -0.25f, 0);
public float RotateSpeed = 5f;
public float MovementSmoothing = 0;
private Vector3 velocity = Vector3.zero;
[Tooltip("If true this transform will be parented to the characterController. Set this to true if you want the position and rotation to align with the character controller without delay.")]
public bool ParentToCharacter = false;
Transform originalParent;
/// <summary>
/// This object will be used as a reference to follow
/// </summary>
Transform followTransform;
Transform camTransform;
void Start() {
originalParent = transform.parent;
followTransform = new GameObject().transform;
followTransform.name = "RotateReferenceObject";
followTransform.position = transform.position;
followTransform.rotation = transform.rotation;
// Parent the object to our character and let the hierarchy take care of positioning
if (ParentToCharacter) {
transform.parent = Character.transform;
}
// Set our reference transform to the Character object if it is available
if(FollowTransform) {
followTransform.parent = FollowTransform;
}
else if (Character) {
followTransform.parent = Character.transform;
}
else {
followTransform.parent = originalParent;
}
}
void LateUpdate() {
UpdatePosition();
}
void UpdatePosition() {
// Find Main Camera Object if it changed or not yet been fou nd
// Use the transform with the "MainCamera" tag, instead of Camera.main, as the Camera component could be disabled when using dual eye cameras.
if (camTransform == null && GameObject.FindGameObjectWithTag("MainCamera") != null) {
camTransform = GameObject.FindGameObjectWithTag("MainCamera").transform;
followTransform.position = camTransform.position;
followTransform.localEulerAngles = Vector3.zero;
}
// No main camera available
if (camTransform == null) {
return;
}
// Offset from Character's body if available
Vector3 worldOffset = Vector3.zero;
if(FollowTransform) {
worldOffset = FollowTransform.position - FollowTransform.TransformVector(Offset);
}
else if (Character) {
worldOffset = Character.transform.position - Character.transform.TransformVector(Offset);
}
Vector3 moveToPosition = new Vector3(worldOffset.x, camTransform.position.y - Offset.y, worldOffset.z);
transform.position = Vector3.SmoothDamp(transform.position, moveToPosition, ref velocity, MovementSmoothing);
transform.rotation = Quaternion.Lerp(transform.rotation, followTransform.rotation, Time.deltaTime * RotateSpeed);
}
}
}