private void NormalizeCardinal() { if (cardinal < 0 || cardinal > 7) { cardinal = MathZ.Modulo(cardinal, 8); } }
private Vector3 CheckAtPositionCapsule(Vector3 toCheckAt, ref bool hitCollider, CapsuleCollider capCol) { for (int i = 0; i < collisionChecksPerFrame; i++) { //For a capsule we need to calculate the highestPoint - radius and the lowestPoint + radius first, but at our next position Vector3 point1 = new Vector3(toCheckAt.x, toCheckAt.y - ((capCol.height / 2) - capCol.radius), toCheckAt.z); Vector3 point2 = new Vector3(toCheckAt.x, toCheckAt.y + ((capCol.height / 2) - capCol.radius), toCheckAt.z); var collidingObjects = Physics.OverlapCapsule(point1, point2, capCol.radius); //Just a potential future bugfix if we wouldn't find our own collider anymore to save performance if (collidingObjects.Length == 0) { break; } foreach (var collider in collidingObjects) { //If we only find only our own collider there is no reason to keep going for this position if (collider == col && collidingObjects.Length == 1) { break; } //we will also find our own collider or triggers in which case we just skip it if (collider.isTrigger || collider == col) { continue; } /* We take the line from the top of our collider to the very bottom through the exact middle. * After we calculate the closest point on our line to the closest point on the object we are colliding with * to push this object away from the other object by the vector of those 2 points. */ Vector3 closestPointOnOther = collider.ClosestPoint(toCheckAt); Vector3 pointOnUs = MathZ.FindNearestPointOnLine(point1, point2, closestPointOnOther); Vector3 collisionVector = closestPointOnOther - pointOnUs; //After this we need to calculate the distance we need to be pushed so our collider will be outside of the other collider in the next Frame. Vector3 pushVector = collisionVector - (capCol.radius * collisionVector.normalized); toCheckAt += pushVector; //We apply the pushVector to our Position in the next Frame. Because we might collide with more objects and need to do additional pushing. hitCollider = true; // At this state we only know we hit anything. Could be optimized by returning the pushVector so we know where we hit it. } } //Updating our collisionInfo like in any other Collision Ray groundRay = new Ray(toCheckAt, gravityDirection); Ray topRay = new Ray(toCheckAt, -gravityDirection); //Note: Do better ground collision checking later (standing on an edge won't count as being grounded collisionInfo.grounded = Physics.Raycast(groundRay, out RaycastHit hit, capCol.height / 2 + .01f); collisionInfo.collisionOnTop = Physics.Raycast(topRay, out RaycastHit hit2, capCol.height / 2 + .01f); if (collisionInfo.grounded) { collisionInfo.standingOn = hit.collider.gameObject; } return(toCheckAt); }
public static TweenType NSmoothStep(int N) => x => { var result = 0f; var deriv = 0f; for (var n = 0; n <= N; ++n) { var inc = MathZ.nCr(-N - 1, n) * MathZ.nCr((2 * N) + 1, N - n) * math.pow(x.Value, N + n + 1); result += inc; if (x.Value != 0) { inc /= x.Value; } deriv += (N + n + 1) * inc; } return(new Sample <float>(result, deriv * x.Gradient)); };
private Vector3 CheckAtPositionBox(Vector3 toCheckAt, ref bool hitCollider, BoxCollider boxCol) { for (int i = 0; i < collisionChecksPerFrame; i++) { var collidingObjects = Physics.OverlapBox(toCheckAt, boxCol.bounds.extents, transform.rotation); //Just a potential future bugfix if we wouldn't find out own collider anymore to save performance if (collidingObjects.Length == 0) { break; } foreach (var collider in collidingObjects) { //If we only find only our own collider there is no reason to keep going for this position if (collider == col && collidingObjects.Length == 1) { break; } //we will also find our own collider or triggers in which case we just skip it //|| collider.tag == "Player" if (collider.isTrigger || collider == col) { continue; } if (collider.tag == "Player") //This is used for platforms so they won't crush the player { collisionInfo.collidingWithPlayer = true; } Vector3 closestPointOnOther = collider.ClosestPointOnBounds(toCheckAt); //we need to do this because we haven't actually moved so we the boxColliders position is still wrong Vector3 collisionDirection = (closestPointOnOther - toCheckAt).normalized; //We need the pushDirection to know into which direction we need to push to get out of the collider Vector3 pushDirection = MathZ.GetMainDirectionForBox(boxCol, collisionDirection); //This is the point on our Collider, which we need to know how far we need to move to get out of the collision Vector3 pointOnCollider = MathZ.FindNearestPointOnBoxBounds(boxCol, toCheckAt, closestPointOnOther, pushDirection); //After we just push towards the Direction for the distance from the other object to our collider Vector3 pushVector = pushDirection * (pointOnCollider - closestPointOnOther).magnitude; toCheckAt += pushVector; // we actually push us out of the other collider with this. //We tell our script to not check for any remaining OverlapBoxes because we already hit something. hitCollider = true; } } Ray groundRay = new Ray(toCheckAt, gravityDirection); Ray topRay = new Ray(toCheckAt, -gravityDirection); //Note: Do better ground collision checking later (standing at an edge won't count as being grounded collisionInfo.grounded = Physics.Raycast(groundRay, out RaycastHit hit, boxCol.bounds.extents.y + .01f); collisionInfo.collisionOnTop = Physics.Raycast(topRay, out RaycastHit hit2, boxCol.bounds.extents.y + .01f); if (collisionInfo.grounded) { collisionInfo.standingOn = hit.collider.gameObject; } //Debug.Log($"raylength: {((boxCol.bounds.min.y + toCheckAt.y - transform.position.y)) + .01f}"); return(toCheckAt); }