diff options
Diffstat (limited to 'Assets/Scripts/GravityTypes')
| -rw-r--r-- | Assets/Scripts/GravityTypes/GravityBox.cs | 225 | ||||
| -rw-r--r-- | Assets/Scripts/GravityTypes/GravityBox.cs.meta | 11 | ||||
| -rw-r--r-- | Assets/Scripts/GravityTypes/GravitySphere.cs | 32 |
3 files changed, 267 insertions, 1 deletions
diff --git a/Assets/Scripts/GravityTypes/GravityBox.cs b/Assets/Scripts/GravityTypes/GravityBox.cs new file mode 100644 index 0000000..77e6847 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravityBox.cs @@ -0,0 +1,225 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class GravityBox : GravitySource
+{
+ [SerializeField]
+ float gravity = 9.81f;
+
+ [SerializeField]
+ Vector3 boundaryDistance = Vector3.one;
+
+ [SerializeField, Min(0f)]
+ float innerDistance = 0f;
+ [SerializeField, Min(0f)]
+ float innerFalloffDistance = 0f;
+ [SerializeField, Min(0f)]
+ float outerDistance = 0f;
+ [SerializeField, Min(0f)]
+ float outerFalloffDistance = 0f;
+
+ float innerFalloffFactor;
+ float outerFalloffFactor;
+
+ void Awake()
+ {
+ OnValidate();
+ }
+
+ void OnValidate()
+ {
+ boundaryDistance = Vector3.Max(boundaryDistance, Vector3.zero);
+ float maxInner = Mathf.Min(
+ Mathf.Min(
+ boundaryDistance.x,
+ boundaryDistance.y),
+ boundaryDistance.z
+ );
+ innerDistance = Mathf.Min(innerDistance, maxInner);
+
+ innerFalloffDistance =
+ Mathf.Max(
+ Mathf.Min(
+ innerFalloffDistance,
+ maxInner),
+ innerDistance
+ );
+ outerFalloffDistance = Mathf.Max(
+ outerFalloffDistance,
+ outerDistance
+ );
+
+ innerFalloffFactor = 1f / (innerFalloffDistance - innerDistance);
+ outerFalloffFactor = 1f / (outerFalloffDistance - outerDistance);
+
+ }
+
+ void OnDrawGizmos()
+ {
+ Gizmos.matrix =
+ Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
+ Vector3 size;
+ if(innerFalloffDistance > innerDistance)
+ {
+ Gizmos.color = Color.cyan;
+ size.x = 2f *(boundaryDistance.x - innerFalloffDistance);
+ size.y = 2f *(boundaryDistance.y - innerFalloffDistance);
+ size.z = 2f *(boundaryDistance.z - innerFalloffDistance);
+ Gizmos.DrawWireCube(Vector3.zero, size);
+ }
+ if(innerDistance > 0f)
+ {
+ Gizmos.color = Color.yellow;
+ size.x = 2f *(boundaryDistance.x - innerDistance);
+ size.y = 2f *(boundaryDistance.y - innerDistance);
+ size.z = 2f *(boundaryDistance.z - innerDistance);
+ Gizmos.DrawWireCube(Vector3.zero, size);
+ }
+ if(outerDistance > 0f)
+ {
+ Gizmos.color = Color.yellow;
+ DrawGizmosOuterCube(outerDistance);
+ }
+ if(outerFalloffDistance > outerDistance)
+ {
+ Gizmos.color = Color.cyan;
+ DrawGizmosOuterCube(outerFalloffDistance);
+ }
+ Gizmos.color = Color.red;
+ Gizmos.DrawWireCube(Vector3.zero, 2f * boundaryDistance);
+ }
+
+ void DrawGizmosRect(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
+ {
+ Gizmos.DrawLine(a, b);
+ Gizmos.DrawLine(b, c);
+ Gizmos.DrawLine(c, d);
+ Gizmos.DrawLine(d, a);
+ }
+
+ void DrawGizmosOuterCube(float distance)
+ {
+ Vector3 a, b, c, d;
+ a.y = b.y = boundaryDistance.y;
+ d.y = c.y = -boundaryDistance.y;
+ b.z = c.z = boundaryDistance.z;
+ d.z = a.z = -boundaryDistance.z;
+ a.x = b.x = c.x = d.x = boundaryDistance.x + distance;
+ DrawGizmosRect(a, b, c, d);
+ a.x = b.x = c.x = d.x = -a.x;
+ DrawGizmosRect(a, b, c, d);
+
+ a.x = d.x = boundaryDistance.x;
+ b.x = c.x = -boundaryDistance.x;
+ a.z = d.z = boundaryDistance.z;
+ c.z = d.z = -boundaryDistance.z;
+ a.y = b.y = c.y = d.y = boundaryDistance.y + distance;
+ DrawGizmosRect(a, b, c, d);
+ a.y = b.y = c.y = d.y = -a.y;
+ DrawGizmosRect(a, b, c, d);
+
+ a.x = d.x = boundaryDistance.x;
+ b.x = c.x = -boundaryDistance.x;
+ a.y = b.y = boundaryDistance.y;
+ c.y = d.y = -boundaryDistance.y;
+ a.z = b.z = c.z = d.z = boundaryDistance.z + distance;
+ DrawGizmosRect(a, b, c, d);
+ a.z = b.z = c.z = d.z = -a.z;
+ DrawGizmosRect(a, b, c, d);
+
+ distance *= 0.5773502692f; // sqrt(1/3)
+ Vector3 size = boundaryDistance;
+ size.x = 2f * (size.x + distance);
+ size.y = 2f * (size.y + distance);
+ size.z = 2f * (size.z + distance);
+ Gizmos.DrawWireCube(Vector3.zero, size);
+ }
+
+ float GetGravityComponent(float coordinate, float distance)
+ {
+ if(distance > innerFalloffDistance)
+ return 0f;
+ float g = gravity;
+ if(distance > innerDistance)
+ g *= 1f - (distance - innerDistance) * innerFalloffFactor;
+ return coordinate <= 0f ? -g : g;
+ }
+
+ public override Vector3 GetGravity(Vector3 position)
+ {
+ position = transform.InverseTransformDirection(
+ position - transform.position
+ );
+
+ Vector3 vector = Vector3.zero;
+ int outside = 0;
+
+ // check if outside of x faces
+ if(position.x > boundaryDistance.x)
+ {
+ vector.x = boundaryDistance.x - position.x;
+ outside = 1;
+ }
+ else if(position.x < -boundaryDistance.x)
+ {
+ vector.x = -boundaryDistance.x - position.x;
+ outside = 1;
+ }
+
+ // check if outside of y faces
+ if(position.y > boundaryDistance.y)
+ {
+ vector.y = boundaryDistance.y - position.y;
+ outside += 1;
+ }
+ else if(position.y < -boundaryDistance.y)
+ {
+ vector.y = -boundaryDistance.y - position.y;
+ outside += 1;
+ }
+
+ // check if outside of z faces
+ if(position.z > boundaryDistance.z)
+ {
+ vector.z = boundaryDistance.z - position.z;
+ outside += 1;
+ }
+ else if(position.z < -boundaryDistance.z)
+ {
+ vector.z = -boundaryDistance.z - position.z;
+ outside += 1;
+ }
+
+ // if outside: check distances and return relevant gravity
+ if(outside > 0)
+ {
+ float distance = (outside == 1) ?
+ Mathf.Abs(vector.x + vector.y + vector.z) :
+ vector.magnitude;
+ if(distance > outerFalloffDistance)
+ return Vector3.zero;
+ float g = gravity / distance;
+ if(distance > outerDistance)
+ g *= 1f - (distance - outerDistance * outerFalloffFactor);
+ return transform.TransformDirection(g * vector);
+ }
+
+ Vector3 distances;
+ distances.x = boundaryDistance.x - Mathf.Abs(position.x);
+ distances.y = boundaryDistance.y - Mathf.Abs(position.y);
+ distances.z = boundaryDistance.z - Mathf.Abs(position.z);
+ if(distances.x < distances.y)
+ {
+ if(distances.x < distances.z)
+ vector.x = GetGravityComponent(position.x, distances.x);
+ else
+ vector.z = GetGravityComponent(position.z, distances.z);
+ }
+ else if(distances.y < distances.z)
+ vector.y = GetGravityComponent(position.y, distances.y);
+ else
+ vector.z = GetGravityComponent(position.z, distances.z);
+ return transform.TransformDirection(vector);
+ }
+}
diff --git a/Assets/Scripts/GravityTypes/GravityBox.cs.meta b/Assets/Scripts/GravityTypes/GravityBox.cs.meta new file mode 100644 index 0000000..efd4588 --- /dev/null +++ b/Assets/Scripts/GravityTypes/GravityBox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc8691d2a79101e46b68837299f38672 +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 index 2eb67a8..63418c5 100644 --- a/Assets/Scripts/GravityTypes/GravitySphere.cs +++ b/Assets/Scripts/GravityTypes/GravitySphere.cs @@ -11,23 +11,47 @@ public class GravitySphere : GravitySource float outerRadius = 10f;
[SerializeField, Min(0f)]
float outerFalloffRadius = 15f;
+ float outerFalloffFactor;
+
+ [SerializeField, Min(0f)]
+ float innerFalloffRadius = 1f;
+ [SerializeField, Min(0f)]
+ float innerRadius = 5f;
+ float innerFalloffFactor;
public override Vector3 GetGravity(Vector3 position)
{
Vector3 vector = transform.position - position;
float distance = vector.magnitude;
- if(distance > outerFalloffRadius)
+ if(distance > outerFalloffRadius || distance < innerFalloffRadius)
{
return Vector3.zero;
}
float g = gravity / distance;
+ if(distance > outerRadius)
+ {
+ g *= 1f - (distance - outerRadius) * outerFalloffFactor;
+ }
+ else if(distance < innerRadius)
+ {
+ g *= -(1f - (distance - innerRadius) * innerFalloffFactor);
+ }
return g * vector;
}
void OnDrawGizmos()
{
Vector3 p = transform.position;
+ if((innerFalloffRadius > 0f) && (innerFalloffRadius < innerRadius))
+ {
+ Gizmos.color = Color.cyan;
+ Gizmos.DrawWireSphere(p, innerFalloffRadius);
+ }
Gizmos.color = Color.yellow;
+ if(innerRadius > 0f && innerRadius < outerRadius)
+ {
+ Gizmos.DrawWireSphere(p, innerRadius);
+ }
Gizmos.DrawWireSphere(p, outerRadius);
if(outerFalloffRadius > outerRadius)
{
@@ -43,7 +67,13 @@ public class GravitySphere : GravitySource void OnValidate()
{
+ innerRadius = Mathf.Max(innerRadius, innerFalloffRadius);
+ innerFalloffRadius = Mathf.Max(innerFalloffRadius, 0f);
+ outerRadius = Mathf.Max(outerRadius, innerRadius);
outerFalloffRadius = Mathf.Max(outerFalloffRadius, outerRadius);
+
+ innerFalloffFactor = 1f / (innerFalloffRadius - innerRadius);
+ outerFalloffFactor = 1f / (outerFalloffRadius - outerRadius);
}
}
|
