diff options
Diffstat (limited to 'Assets/Scripts')
| -rw-r--r-- | Assets/Scripts/CustomGravity.cs | 23 | ||||
| -rw-r--r-- | Assets/Scripts/CustomGravity.cs.meta | 11 | ||||
| -rw-r--r-- | Assets/Scripts/GravitySource.cs | 18 | ||||
| -rw-r--r-- | Assets/Scripts/GravitySource.cs.meta | 11 | ||||
| -rw-r--r-- | Assets/Scripts/MovingSphere.cs | 60 | ||||
| -rw-r--r-- | Assets/Scripts/OrbitCamera.cs | 22 | ||||
| -rw-r--r-- | Assets/Scripts/RigidBodyCustomGravity.cs | 59 | ||||
| -rw-r--r-- | Assets/Scripts/RigidBodyCustomGravity.cs.meta | 11 |
8 files changed, 183 insertions, 32 deletions
diff --git a/Assets/Scripts/CustomGravity.cs b/Assets/Scripts/CustomGravity.cs new file mode 100644 index 0000000..45f99bf --- /dev/null +++ b/Assets/Scripts/CustomGravity.cs @@ -0,0 +1,23 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class CustomGravity : MonoBehaviour
+{
+
+ public static Vector3 GetGravity(Vector3 position, out Vector3 upAxis)
+ {
+ upAxis = GetUpAxis(position);
+ return position.normalized * Physics.gravity.y;
+ }
+ public static Vector3 GetGravity(Vector3 position)
+ {
+ return position.normalized * Physics.gravity.y;
+ }
+
+ public static Vector3 GetUpAxis(Vector3 position)
+ {
+ Vector3 up = position.normalized;
+ return Physics.gravity.y < 0f ? up : -up;
+ }
+}
diff --git a/Assets/Scripts/CustomGravity.cs.meta b/Assets/Scripts/CustomGravity.cs.meta new file mode 100644 index 0000000..c71df89 --- /dev/null +++ b/Assets/Scripts/CustomGravity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cfd69678f471ae2ccbfd723cbafda9ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GravitySource.cs b/Assets/Scripts/GravitySource.cs new file mode 100644 index 0000000..e34a42e --- /dev/null +++ b/Assets/Scripts/GravitySource.cs @@ -0,0 +1,18 @@ +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 new file mode 100644 index 0000000..2f4fe9f --- /dev/null +++ b/Assets/Scripts/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/MovingSphere.cs b/Assets/Scripts/MovingSphere.cs index 77ac00f..e97e1ef 100644 --- a/Assets/Scripts/MovingSphere.cs +++ b/Assets/Scripts/MovingSphere.cs @@ -4,9 +4,13 @@ using UnityEngine; public class MovingSphere : MonoBehaviour
{
+ // if we want input relative to a
+ // camera(or some other arbitrary object) we
+ // put that object here
[SerializeField]
Transform playerInputSpace = default;
+ // "self" objects
Rigidbody body;
Renderer renderer;
@@ -34,6 +38,7 @@ public class MovingSphere : MonoBehaviour float raycastProbeDistance = 1f;
[SerializeField]
LayerMask probeMask = -1;
+ [SerializeField]
LayerMask stairsMask = -1;
@@ -50,7 +55,8 @@ public class MovingSphere : MonoBehaviour bool OnSteep => steepContactCount > 0;
Vector3 upAxis;
-
+ Vector3 rightAxis;
+ Vector3 forwardAxis;
// 1.0 means walls
// 0.0 means floors
@@ -68,6 +74,7 @@ public class MovingSphere : MonoBehaviour {
body = GetComponent<Rigidbody>();
renderer = GetComponent<Renderer>();
+ body.useGravity = false;
}
void Update()
@@ -82,39 +89,39 @@ public class MovingSphere : MonoBehaviour if(playerInputSpace)
{
- Vector3 forward = playerInputSpace.forward;
- forward.y = 0f;
- forward.Normalize();
- Vector3 right = playerInputSpace.right;
- right.y = 0f;
- right.Normalize();
- inputVelocity =
- ((forward * playerInput.y) + (right * playerInput.x)) * maxSpeed;
+ rightAxis = ProjectDirectionOnPlane(playerInputSpace.right, upAxis);
+ forwardAxis = ProjectDirectionOnPlane(playerInputSpace.forward, upAxis);
}
else
- inputVelocity = new Vector3(playerInput.x, 0f, playerInput.y) * maxSpeed;
+ {
+ rightAxis = ProjectDirectionOnPlane(Vector3.right, upAxis);
+ forwardAxis = ProjectDirectionOnPlane(Vector3.forward, upAxis);
+ }
+ inputVelocity = new Vector3(playerInput.x, 0f, playerInput.y) * maxSpeed;
Color purple = Color.red + Color.blue;
//renderer.material.SetColor(
// "_BaseColor", purple - (purple * (groundContactCount * 0.33f))
// );
- renderer.material.SetColor(
- "_BaseColor", OnGround ? purple * 0.9f : purple * 0.1f
- );
+ //renderer.material.SetColor(
+ // "_BaseColor", OnGround ? purple * 0.9f : purple * 0.1f
+ // );
}
void FixedUpdate()
{
- upAxis = -Physics.gravity.normalized;
+ Vector3 gravity = CustomGravity.GetGravity(body.position, out upAxis);
UpdateState();
AdjustVelocity();
if(desiredJump)
{
desiredJump = false;
- Jump();
+ Jump(gravity);
}
+ velocity += gravity * Time.deltaTime;
+
body.velocity = velocity;
ClearState();
}
@@ -148,7 +155,7 @@ public class MovingSphere : MonoBehaviour contactNormal = upAxis;
}
- void Jump()
+ void Jump(Vector3 gravity)
{
Vector3 jumpDirection;
@@ -170,7 +177,7 @@ public class MovingSphere : MonoBehaviour stepsSinceLastJump = 0;
jumpPhase += 1;
- float jumpSpeed = Mathf.Sqrt(2f * Physics.gravity.magnitude * jumpHeight);
+ float jumpSpeed = Mathf.Sqrt(2f * gravity.magnitude * jumpHeight);
jumpDirection = (jumpDirection + upAxis).normalized;
float alignedSpeed = Vector3.Dot(velocity, jumpDirection);
if(alignedSpeed > 0f)
@@ -193,7 +200,8 @@ public class MovingSphere : MonoBehaviour probeMask
))
return false;
- if(hit.normal.y < GetMinDot(hit.collider.gameObject.layer))
+ float upDot = Vector3.Dot(upAxis, hit.normal);
+ if(upDot < GetMinDot(hit.collider.gameObject.layer))
return false;
groundContactCount = 1;
@@ -217,12 +225,13 @@ public class MovingSphere : MonoBehaviour for(int i = 0; i < collision.contactCount; i++)
{
Vector3 normal = collision.GetContact(i).normal;
- if(normal.y >= minDot)
+ float upDot = GetMinDot(collision.gameObject.layer);
+ if(upDot >= minDot)
{
groundContactCount += 1;
contactNormal += normal;
}
- else if(normal.y > -0.01f)
+ else if(upDot > -0.01f)
{
steepContactCount += 1;
steepNormal += normal;
@@ -232,8 +241,8 @@ public class MovingSphere : MonoBehaviour void AdjustVelocity()
{
- Vector3 xAxis = ProjectOnContactPlane(Vector3.right).normalized;
- Vector3 zAxis = ProjectOnContactPlane(Vector3.forward).normalized;
+ Vector3 xAxis = ProjectDirectionOnPlane(rightAxis, contactNormal);
+ Vector3 zAxis = ProjectDirectionOnPlane(forwardAxis, contactNormal);
Vector3 currentVel = new Vector3(
Vector3.Dot(velocity, xAxis),
@@ -257,9 +266,9 @@ public class MovingSphere : MonoBehaviour velocity += xAxis * (newVel.x - currentVel.x) + zAxis * (newVel.z - currentVel.z);
}
- Vector3 ProjectOnContactPlane(Vector3 vector)
+ Vector3 ProjectDirectionOnPlane(Vector3 direction, Vector3 normal)
{
- return vector - contactNormal * Vector3.Dot(vector, contactNormal);
+ return (direction - normal * Vector3.Dot(direction, normal)).normalized;
}
float GetMinDot(int layer)
@@ -275,7 +284,8 @@ public class MovingSphere : MonoBehaviour if(steepContactCount > 1)
{
steepNormal.Normalize();
- if(steepNormal.y >= minGroundDotProduct)
+ float upDot = Vector3.Dot(upAxis, steepNormal);
+ if(upDot >= minGroundDotProduct)
{
groundContactCount = 1;
contactNormal = steepNormal;
diff --git a/Assets/Scripts/OrbitCamera.cs b/Assets/Scripts/OrbitCamera.cs index 81a6941..c0c84a7 100644 --- a/Assets/Scripts/OrbitCamera.cs +++ b/Assets/Scripts/OrbitCamera.cs @@ -41,6 +41,9 @@ public class OrbitCamera : MonoBehaviour Vector3 orbitAngles = new Vector2(45f, 0f);
+ Quaternion gravityAlignment = Quaternion.identity;
+ Quaternion orbitRotation;
+
[SerializeField]
LayerMask obstructionMask = -1;
@@ -48,20 +51,23 @@ public class OrbitCamera : MonoBehaviour {
regularCamera = GetComponent<Camera>();
focusPoint = focus.position;
- transform.localRotation = Quaternion.Euler(orbitAngles);
+ transform.localRotation = orbitRotation = Quaternion.Euler(orbitAngles);
+ OnValidate();
}
void LateUpdate()
{
+ gravityAlignment = Quaternion.FromToRotation(
+ gravityAlignment * Vector3.up,
+ CustomGravity.GetUpAxis(focusPoint)
+ ) * gravityAlignment;
UpdateFocusPoint();
- Quaternion lookRotation;
if(ManualRotation() || AutomaticRotation())
{
ConstrainAngles();
- lookRotation = Quaternion.Euler(orbitAngles);
+ orbitRotation = Quaternion.Euler(orbitAngles);
}
- else
- lookRotation = transform.localRotation;
+ Quaternion lookRotation = gravityAlignment * orbitRotation;
Vector3 lookDirection = lookRotation * Vector3.forward;
Vector3 lookPosition = focusPoint - lookDirection * distance;
@@ -153,9 +159,11 @@ public class OrbitCamera : MonoBehaviour if(Time.unscaledTime - lastManualRotationTime < alignDelay)
return false;
+ Vector3 alignedDelta = Quaternion.Inverse(gravityAlignment) *
+ (focusPoint - previousFocusPoint);
Vector2 movement = new Vector2(
- focusPoint.x - previousFocusPoint.x,
- focusPoint.z - previousFocusPoint.z
+ alignedDelta.x,
+ alignedDelta.z
);
float movementDeltaSqr = movement.sqrMagnitude;
if(movementDeltaSqr < 0.0001f)
diff --git a/Assets/Scripts/RigidBodyCustomGravity.cs b/Assets/Scripts/RigidBodyCustomGravity.cs new file mode 100644 index 0000000..516f937 --- /dev/null +++ b/Assets/Scripts/RigidBodyCustomGravity.cs @@ -0,0 +1,59 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+[RequireComponent(typeof(Rigidbody))]
+public class RigidBodyCustomGravity : MonoBehaviour
+{
+ Rigidbody body;
+ Renderer renderer;
+ float floatDelay = 0f;
+
+ void Awake()
+ {
+ body = GetComponent<Rigidbody>();
+ renderer = GetComponent<Renderer>();
+ body.useGravity = false;
+ }
+
+ void FixedUpdate()
+ {
+ if(body.IsSleeping())
+ {
+ renderer.material.SetColor(
+ "_BaseColor",
+ Color.gray
+ );
+ floatDelay = 0f;
+ return;
+ }
+
+ if(body.velocity.sqrMagnitude < 0.0005f)
+ {
+ // disable interpolation when ready to sleep
+ body.interpolation = RigidbodyInterpolation.None;
+ renderer.material.SetColor(
+ "_BaseColor",
+ Color.yellow
+ );
+ floatDelay += Time.deltaTime;
+ if(floatDelay >= 1f)
+ return;
+ }
+ else
+ floatDelay = 0f;
+
+ // enable interpolation when not sleeping
+ body.interpolation = RigidbodyInterpolation.Interpolate;
+
+ renderer.material.SetColor(
+ "_BaseColor",
+ Color.red
+ );
+
+ body.AddForce(
+ CustomGravity.GetGravity(body.position),
+ ForceMode.Acceleration
+ );
+ }
+}
diff --git a/Assets/Scripts/RigidBodyCustomGravity.cs.meta b/Assets/Scripts/RigidBodyCustomGravity.cs.meta new file mode 100644 index 0000000..bce7e73 --- /dev/null +++ b/Assets/Scripts/RigidBodyCustomGravity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1d4f338d4ac8031fb6dfacb838c1371 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |
