From f39e9a0f20729eb084e75444445a5087790ac75f Mon Sep 17 00:00:00 2001 From: realtradam Date: Wed, 18 Jan 2023 17:34:16 -0500 Subject: Built test level and added some comments --- Assets/Scripts/CustomGravity.cs | 4 ++++ Assets/Scripts/MovingSphere.cs | 32 +++++++++++++++++++++++--------- Assets/Scripts/OrbitCamera.cs | 28 ++++++++++++++++++++-------- Assets/Scripts/RigidBodyCustomGravity.cs | 2 ++ 4 files changed, 49 insertions(+), 17 deletions(-) (limited to 'Assets/Scripts') diff --git a/Assets/Scripts/CustomGravity.cs b/Assets/Scripts/CustomGravity.cs index 027cdd6..feebab2 100644 --- a/Assets/Scripts/CustomGravity.cs +++ b/Assets/Scripts/CustomGravity.cs @@ -2,6 +2,10 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +// Gravity Source Manager +// This is a component holds all the gravity sources +// and provides a simple api for physics objects to +// query and get net gravity effects. public class CustomGravity : MonoBehaviour { static List sources = new List(); diff --git a/Assets/Scripts/MovingSphere.cs b/Assets/Scripts/MovingSphere.cs index f457ab8..ba6a77c 100644 --- a/Assets/Scripts/MovingSphere.cs +++ b/Assets/Scripts/MovingSphere.cs @@ -2,6 +2,8 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +// Player Sphere +// The sphere that the player can control and move around public class MovingSphere : MonoBehaviour { // if we want input relative to a @@ -9,6 +11,7 @@ public class MovingSphere : MonoBehaviour // put that object here [SerializeField] Transform playerInputSpace = default; + [SerializeField] Transform ball = default; @@ -38,6 +41,7 @@ public class MovingSphere : MonoBehaviour [SerializeField, Min(0f)] float raycastProbeDistance = 1f; + // Define the following 2 variables in the editor [SerializeField] LayerMask probeMask = -1; [SerializeField] @@ -84,11 +88,14 @@ public class MovingSphere : MonoBehaviour { body = GetComponent(); renderer = ball.GetComponent(); + + // we define our own gravity so disable the built in one. body.useGravity = false; } void Update() { + // --- Get Input --- Vector2 playerInput = new Vector2( Input.GetAxis("Horizontal"), Input.GetAxis("Vertical") @@ -96,7 +103,9 @@ public class MovingSphere : MonoBehaviour playerInput = Vector2.ClampMagnitude(playerInput, 1f); desiredJump |= Input.GetButtonDown("Jump"); + // --- --- + // --- Calculate what is considered the "floor" --- if(playerInputSpace) { rightAxis = ProjectDirectionOnPlane(playerInputSpace.right, upAxis); @@ -108,14 +117,9 @@ public class MovingSphere : MonoBehaviour 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 - // ); + // Update visual orientation of the ball UpdateBall(); } @@ -124,6 +128,7 @@ public class MovingSphere : MonoBehaviour { Vector3 gravity = CustomGravity.GetGravity(body.position, out upAxis); UpdateState(); + // apply input velocities AdjustVelocity(); if(desiredJump) @@ -147,13 +152,15 @@ public class MovingSphere : MonoBehaviour void UpdateState() { - // if changed in editor, update these + // if slope angle changed in editor, update these minGroundDotProduct = Mathf.Cos(maxSlopeAngle * 90 * Mathf.Deg2Rad); minStairsDotProduct = Mathf.Cos(maxStairAngle * 90 * Mathf.Deg2Rad); stepsSinceLastGrounded += 1; stepsSinceLastJump += 1; + velocity = body.velocity; + if(OnGround || SnapToGround() || CheckSteepContacts()) { stepsSinceLastGrounded = 0; @@ -168,6 +175,7 @@ public class MovingSphere : MonoBehaviour contactNormal = upAxis; } + // Update visual orientation of the ball void UpdateBall() { Vector3 movement = body.velocity * Time.deltaTime; @@ -252,6 +260,7 @@ public class MovingSphere : MonoBehaviour if(upDot < GetMinDot(hit.collider.gameObject.layer)) return false; + Debug.Log(Time.time); groundContactCount = 1; contactNormal = hit.normal; float dot = Vector3.Dot(velocity, hit.normal); @@ -260,13 +269,15 @@ public class MovingSphere : MonoBehaviour return true; } + // --- Hooks into Unity api for collisions --- void OnCollisionStay(Collision collision) { EvaluateCollision(collision); } void OnCollisionEnter(Collision collision) { - EvaluateCollision(collision); + EvaluateCollision(collision); } + // --- --- void EvaluateCollision(Collision collision) { float minDot = GetMinDot(collision.gameObject.layer); @@ -329,6 +340,9 @@ public class MovingSphere : MonoBehaviour bool CheckSteepContacts() { + // check if there are multiple contact points + // if there are: use the average normal of + // all contacts instead if(steepContactCount > 1) { steepNormal.Normalize(); diff --git a/Assets/Scripts/OrbitCamera.cs b/Assets/Scripts/OrbitCamera.cs index 57efdec..0a2b1f5 100644 --- a/Assets/Scripts/OrbitCamera.cs +++ b/Assets/Scripts/OrbitCamera.cs @@ -7,7 +7,6 @@ public class OrbitCamera : MonoBehaviour { Camera regularCamera; - [SerializeField] Transform focus = default; @@ -62,16 +61,21 @@ public class OrbitCamera : MonoBehaviour { UpdateGravityAlignment(); UpdateFocusPoint(); + if(ManualRotation() || AutomaticRotation()) { ConstrainAngles(); orbitRotation = Quaternion.Euler(orbitAngles); } + Quaternion lookRotation = gravityAlignment * orbitRotation; Vector3 lookDirection = lookRotation * Vector3.forward; Vector3 lookPosition = focusPoint - lookDirection * distance; + // --- Perform box cast between camera and focus target --- + // determine if anything is blocking the camera. + // If it is, place camera in front of that object. Vector3 rectOffset = lookDirection * regularCamera.nearClipPlane; Vector3 rectPosition = lookPosition + rectOffset; Vector3 castFrom = focus.position; @@ -80,22 +84,26 @@ public class OrbitCamera : MonoBehaviour Vector3 castDirection = castLine / castDistance; if(Physics.BoxCast( - castFrom, - CameraHalfExtends, - castDirection, - out RaycastHit hit, - lookRotation, - castDistance, - obstructionMask + castFrom, // center + CameraHalfExtends, // halfExtents + castDirection, // direction + out RaycastHit hit, // hitInfo + lookRotation, // orientation + castDistance, // maxDistance + obstructionMask // layerMask ) ) { rectPosition = castFrom + castDirection * hit.distance; lookPosition = rectPosition - rectOffset; } + // --- --- + transform.SetPositionAndRotation(lookPosition, lookRotation); } + // Orients the camera depending on the direction of gravity. + // Interpolates the rotation so that it is smooth. void UpdateGravityAlignment() { Vector3 fromUp = gravityAlignment * Vector3.up; Vector3 toUp = CustomGravity.GetUpAxis(focusPoint); @@ -126,6 +134,8 @@ public class OrbitCamera : MonoBehaviour gravityAlignment = newAlignment; } + // Applies camera movement smoothing by interpolating + // the current focus point and the actual focus point void UpdateFocusPoint() { previousFocusPoint = focusPoint; @@ -216,6 +226,8 @@ public class OrbitCamera : MonoBehaviour return true; } + // Box cast requires a box that extends 1/2 in all directions + // (width, height, depth) Vector3 CameraHalfExtends { get diff --git a/Assets/Scripts/RigidBodyCustomGravity.cs b/Assets/Scripts/RigidBodyCustomGravity.cs index 516f937..9ea6141 100644 --- a/Assets/Scripts/RigidBodyCustomGravity.cs +++ b/Assets/Scripts/RigidBodyCustomGravity.cs @@ -2,6 +2,8 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +// Custom rigidbody which overrides the existing rigidbody +// so that it uses our custom gravity system instead. [RequireComponent(typeof(Rigidbody))] public class RigidBodyCustomGravity : MonoBehaviour { -- cgit v1.2.3