using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class RotationController : MonoBehaviour
|
|
{
|
|
|
|
#region Read-Only Fields
|
|
public float RotationPeriod => m_RotationPeriod;
|
|
public Vector3 Position => transform.position;
|
|
public Vector3 RotationAxis => m_RotationAxis;
|
|
public float CoriolisStrength => m_coriolisStrength;
|
|
public float EnvironmentRotationPeriod => m_RotationPeriod / m_SkyboxRotationMultiplier;
|
|
#endregion Read-Only Fields
|
|
|
|
[SerializeField]
|
|
private float m_RotationPeriod;
|
|
|
|
[SerializeField]
|
|
private Vector3 m_RotationAxis = Vector3.forward;
|
|
|
|
[SerializeField]
|
|
private float m_coriolisStrength = 100;
|
|
|
|
[SerializeField]
|
|
private Material m_Skybox;
|
|
|
|
[SerializeField]
|
|
private float m_SkyboxRotationMultiplier = 1;
|
|
|
|
|
|
public Vector3 getDownDirection(Vector3 objectPosition, bool normalized = true)
|
|
{
|
|
if (normalized)
|
|
return Vector3.ProjectOnPlane((objectPosition - transform.position), m_RotationAxis).normalized;
|
|
else
|
|
return Vector3.ProjectOnPlane((objectPosition - transform.position), m_RotationAxis);
|
|
|
|
}
|
|
|
|
public Vector3 getPerpendicularDirection(Vector3 objectPosition)
|
|
{
|
|
return Vector3.Cross(RotationAxis, getDownDirection(objectPosition)).normalized;
|
|
}
|
|
|
|
public Quaternion getUpRotation(Vector3 objectPosition)
|
|
{
|
|
return Quaternion.FromToRotation(Vector3.up, -getDownDirection(objectPosition));
|
|
}
|
|
|
|
public float GetGravityAtRadius(float radius)
|
|
{
|
|
return radius * Mathf.Pow(2 * Mathf.PI / RotationPeriod, 2);
|
|
}
|
|
|
|
public Vector3 GetGravityAtPoint(Vector3 point)
|
|
{
|
|
Vector3 direction = getDownDirection(point,false);
|
|
return direction.normalized * GetGravityAtRadius(direction.magnitude);
|
|
}
|
|
|
|
public Vector3 GetCoriolisAtPoint(Vector3 point)
|
|
{
|
|
return getPerpendicularDirection(point) * Mathf.Pow(2 * Mathf.PI / RotationPeriod, 2) * CoriolisStrength;
|
|
}
|
|
|
|
public void SetGravityAtRadius(float Strength, float radius)
|
|
{
|
|
m_RotationPeriod = 2 * Mathf.PI * Mathf.Sqrt(radius / Strength);
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (m_Skybox == null)
|
|
m_Skybox = RenderSettings.skybox;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (m_Skybox != null)
|
|
{
|
|
m_Skybox.SetVector("_RotationAxis", m_RotationAxis);
|
|
m_Skybox.SetFloat("_Rotation", (Time.time * 360/EnvironmentRotationPeriod) % 360);
|
|
}
|
|
}
|
|
|
|
|
|
}
|