From 5fba0cf01188cc31d8ea6a1b031d29cbbf784e0e Mon Sep 17 00:00:00 2001 From: realtradam Date: Sun, 11 Dec 2022 06:15:05 -0500 Subject: basic multi planet and multi plane gravity --- Assets/Scripts/CustomGravity.cs | 35 +++++++++++++--- Assets/Scripts/GravitySource.cs | 18 --------- Assets/Scripts/GravitySource.cs.meta | 11 ----- Assets/Scripts/GravityTypes.meta | 8 ++++ Assets/Scripts/GravityTypes/GravityPlane.cs | 45 +++++++++++++++++++++ Assets/Scripts/GravityTypes/GravityPlane.cs.meta | 11 +++++ Assets/Scripts/GravityTypes/GravitySource.cs | 22 ++++++++++ Assets/Scripts/GravityTypes/GravitySource.cs.meta | 11 +++++ Assets/Scripts/GravityTypes/GravitySphere.cs | 49 +++++++++++++++++++++++ Assets/Scripts/GravityTypes/GravitySphere.cs.meta | 11 +++++ Assets/Scripts/OrbitCamera.cs | 49 +++++++++++++++++++---- 11 files changed, 229 insertions(+), 41 deletions(-) delete mode 100644 Assets/Scripts/GravitySource.cs delete mode 100644 Assets/Scripts/GravitySource.cs.meta create mode 100644 Assets/Scripts/GravityTypes.meta create mode 100644 Assets/Scripts/GravityTypes/GravityPlane.cs create mode 100644 Assets/Scripts/GravityTypes/GravityPlane.cs.meta create mode 100644 Assets/Scripts/GravityTypes/GravitySource.cs create mode 100644 Assets/Scripts/GravityTypes/GravitySource.cs.meta create mode 100644 Assets/Scripts/GravityTypes/GravitySphere.cs create mode 100644 Assets/Scripts/GravityTypes/GravitySphere.cs.meta (limited to 'Assets/Scripts') diff --git a/Assets/Scripts/CustomGravity.cs b/Assets/Scripts/CustomGravity.cs index 45f99bf..027cdd6 100644 --- a/Assets/Scripts/CustomGravity.cs +++ b/Assets/Scripts/CustomGravity.cs @@ -4,20 +4,45 @@ using UnityEngine; public class CustomGravity : MonoBehaviour { + static List sources = new List(); public static Vector3 GetGravity(Vector3 position, out Vector3 upAxis) { - upAxis = GetUpAxis(position); - return position.normalized * Physics.gravity.y; + Vector3 g = Vector3.zero; + for(int i = 0; i < sources.Count; i++) + g += sources[i].GetGravity(position); + upAxis = -g.normalized; + return g; } public static Vector3 GetGravity(Vector3 position) { - return position.normalized * Physics.gravity.y; + Vector3 g = Vector3.zero; + for(int i = 0; i < sources.Count; i++) + g += sources[i].GetGravity(position); + return g; } public static Vector3 GetUpAxis(Vector3 position) { - Vector3 up = position.normalized; - return Physics.gravity.y < 0f ? up : -up; + return -GetGravity(position).normalized; + } + + public static void Register(GravitySource source) + { + Debug.Assert( + !sources.Contains(source), + "WARNING: This source is already registered!", + source + ); + sources.Add(source); + } + public static void Unregister(GravitySource source) + { + Debug.Assert( + sources.Contains(source), + "WARNING: Trying to unregister unknown gravity source!", + source + ); + sources.Remove(source); } } diff --git a/Assets/Scripts/GravitySource.cs b/Assets/Scripts/GravitySource.cs deleted file mode 100644 index e34a42e..0000000 --- a/Assets/Scripts/GravitySource.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class GravitySource : MonoBehaviour -{ - // Start is called before the first frame update - void Start() - { - - } - - // Update is called once per frame - void Update() - { - - } -} diff --git a/Assets/Scripts/GravitySource.cs.meta b/Assets/Scripts/GravitySource.cs.meta deleted file mode 100644 index 2f4fe9f..0000000 --- a/Assets/Scripts/GravitySource.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3bf5ff68c1211656995c0e00b5f588c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/GravityTypes.meta b/Assets/Scripts/GravityTypes.meta new file mode 100644 index 0000000..e0cabd1 --- /dev/null +++ b/Assets/Scripts/GravityTypes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5767ee742d8a4c89690e8f1c18cf2564 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GravityTypes/GravityPlane.cs b/Assets/Scripts/GravityTypes/GravityPlane.cs new file mode 100644 index 0000000..81a7005 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravityPlane.cs @@ -0,0 +1,45 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class GravityPlane : GravitySource +{ + [SerializeField] + float gravity = 9.81f; + + [SerializeField] + float range = 1f; + + public override Vector3 GetGravity(Vector3 position) + { + Vector3 up = transform.up; + float distance = Vector3.Dot(up, position - transform.position); + if(distance > range) + return Vector3.zero; + + float g = -gravity; + if (distance > 0f) + g *= 1f - distance / range; + return -gravity * up; + } + + void OnDrawGizmos() + { + Vector3 scale = transform.localScale; + scale.y = range; + Gizmos.matrix = Matrix4x4.TRS( + transform.position, + transform.rotation, + scale + ); + //transform.localToWorldMatrix; + Vector3 size = new Vector3(1f, 0f, 1f); + Gizmos.color = Color.yellow; + Gizmos.DrawWireCube(Vector3.zero, size); + if (range > 0f) + { + Gizmos.color = Color.cyan; + Gizmos.DrawWireCube(Vector3.up, size); + } + } +} diff --git a/Assets/Scripts/GravityTypes/GravityPlane.cs.meta b/Assets/Scripts/GravityTypes/GravityPlane.cs.meta new file mode 100644 index 0000000..e843793 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravityPlane.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 76c633abed7adf812b42483ed0574852 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GravityTypes/GravitySource.cs b/Assets/Scripts/GravityTypes/GravitySource.cs new file mode 100644 index 0000000..0e2cc94 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravitySource.cs @@ -0,0 +1,22 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class GravitySource : MonoBehaviour +{ + + public virtual Vector3 GetGravity(Vector3 position) + { + return Physics.gravity; + } + + void OnEnable() + { + CustomGravity.Register(this); + } + + void OnDisable() + { + CustomGravity.Unregister(this); + } +} diff --git a/Assets/Scripts/GravityTypes/GravitySource.cs.meta b/Assets/Scripts/GravityTypes/GravitySource.cs.meta new file mode 100644 index 0000000..2f4fe9f --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravitySource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3bf5ff68c1211656995c0e00b5f588c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GravityTypes/GravitySphere.cs b/Assets/Scripts/GravityTypes/GravitySphere.cs new file mode 100644 index 0000000..2eb67a8 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravitySphere.cs @@ -0,0 +1,49 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class GravitySphere : GravitySource +{ + [SerializeField] + float gravity = 0.981f; + + [SerializeField, Min(0f)] + float outerRadius = 10f; + [SerializeField, Min(0f)] + float outerFalloffRadius = 15f; + + public override Vector3 GetGravity(Vector3 position) + { + Vector3 vector = transform.position - position; + float distance = vector.magnitude; + if(distance > outerFalloffRadius) + { + return Vector3.zero; + } + float g = gravity / distance; + return g * vector; + } + + void OnDrawGizmos() + { + Vector3 p = transform.position; + Gizmos.color = Color.yellow; + Gizmos.DrawWireSphere(p, outerRadius); + if(outerFalloffRadius > outerRadius) + { + Gizmos.color = Color.cyan; + Gizmos.DrawWireSphere(p, outerFalloffRadius); + } + } + + void Awake() + { + OnValidate(); + } + + void OnValidate() + { + outerFalloffRadius = Mathf.Max(outerFalloffRadius, outerRadius); + } + +} diff --git a/Assets/Scripts/GravityTypes/GravitySphere.cs.meta b/Assets/Scripts/GravityTypes/GravitySphere.cs.meta new file mode 100644 index 0000000..e74fe93 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravitySphere.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 777d997ba72cd51668cb6e0122d8a184 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/OrbitCamera.cs b/Assets/Scripts/OrbitCamera.cs index c0c84a7..57efdec 100644 --- a/Assets/Scripts/OrbitCamera.cs +++ b/Assets/Scripts/OrbitCamera.cs @@ -20,6 +20,9 @@ public class OrbitCamera : MonoBehaviour [SerializeField, Range(0f, 1f)] float focusCenteringSpeed = 0.5f; + [SerializeField, Range(0f, 1f)] + float rotationFlippingSpeed = 0.9f; + [SerializeField, Range(1f, 360f)] float rotationSpeed = 90f; @@ -57,10 +60,7 @@ public class OrbitCamera : MonoBehaviour void LateUpdate() { - gravityAlignment = Quaternion.FromToRotation( - gravityAlignment * Vector3.up, - CustomGravity.GetUpAxis(focusPoint) - ) * gravityAlignment; + UpdateGravityAlignment(); UpdateFocusPoint(); if(ManualRotation() || AutomaticRotation()) { @@ -96,6 +96,36 @@ public class OrbitCamera : MonoBehaviour transform.SetPositionAndRotation(lookPosition, lookRotation); } + void UpdateGravityAlignment() { + Vector3 fromUp = gravityAlignment * Vector3.up; + Vector3 toUp = CustomGravity.GetUpAxis(focusPoint); + float dot = Mathf.Clamp( + Vector3.Dot(fromUp, toUp), + -1f, + 1f + ); + float angle = Mathf.Acos(dot) * Mathf.Rad2Deg; + + + Quaternion newAlignment = + Quaternion.FromToRotation(fromUp, toUp) * gravityAlignment; + + if(angle > 0.1f && rotationFlippingSpeed > 0f) + { + float t = Mathf.Pow( + 1f - rotationFlippingSpeed, + Time.unscaledDeltaTime + ); + gravityAlignment = Quaternion.SlerpUnclamped( + gravityAlignment, + newAlignment, + 1-t + ); + } + else + gravityAlignment = newAlignment; + } + void UpdateFocusPoint() { previousFocusPoint = focusPoint; @@ -105,15 +135,20 @@ public class OrbitCamera : MonoBehaviour float t = 1f; float distance = Vector3.Distance(targetPoint, focusPoint); if(distance > 0.01f && focusCenteringSpeed > 0f) - t = Mathf.Pow(1f - focusCenteringSpeed, Time.unscaledDeltaTime); + { + t = Mathf.Pow( + 1f - focusCenteringSpeed, + Time.unscaledDeltaTime + ); + } if(distance > focusLimitRadius) { t = Mathf.Min(t, focusLimitRadius / distance); } focusPoint = Vector3.Lerp( - targetPoint, focusPoint, - t + targetPoint, + 1-t ); } else -- cgit v1.2.3