Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void Update () {
- GetComponent<Renderer>().material.SetColor(
- "_Color", OnGround ? Color.black : Color.white
- );
- }
- int stepsSinceLastGrounded;
- void UpdateState () {
- stepsSinceLastGrounded += 1;
- velocity = body.velocity;
- if (OnGround) {
- stepsSinceLastGrounded = 0;
- jumpPhase = 0;
- if (groundContactCount > 1) {
- contactNormal.Normalize();
- }
- }
- else {
- contactNormal = Vector3.up;
- }
- }
- bool SnapToGround () {
- return false;
- }
- void UpdateState () {
- stepsSinceLastGrounded += 1;
- velocity = body.velocity;
- if (OnGround || SnapToGround()) {
- }
- }
- bool SnapToGround () {
- if (stepsSinceLastGrounded > 1) {
- return false;
- }
- return false;
- }
- if (stepsSinceLastGrounded > 1) {
- return false;
- }
- if (!Physics.Raycast(body.position, Vector3.down)) {
- return false;
- }
- return false;
- if (!Physics.Raycast(body.position, Vector3.down, out RaycastHit hit)) {
- return false;
- }
- }
- if (hit.normal.y < minGroundDotProduct) {
- return false;
- }
- if (hit.normal.y < minGroundDotProduct) {
- return false;
- }
- groundContactCount = 1;
- contactNormal = hit.normal;
- float speed = velocity.magnitude;
- float dot = Vector3.Dot(velocity, hit.normal);
- velocity = (velocity - hit.normal * dot).normalized * speed;
- return true;
- if (dot > 0f) {
- velocity = (velocity - hit.normal * dot).normalized * speed;
- }
- [SerializeField, Range(1f, 1000f)]
- float maxSnapSpeed = 1000f;
- bool SnapToGround () {
- if (stepsSinceLastGrounded > 1) {
- return false;
- }
- float speed = velocity.magnitude;
- if (speed > maxSnapSpeed) {
- return false;
- }
- if (!Physics.Raycast(body.position, Vector3.down, out RaycastHit hit)) {
- return false;
- }
- if (hit.normal.y < minGroundDotProduct) {
- return false;
- }
- groundContactCount = 1;
- contactNormal = hit.normal;
- float dot = Vector3.Dot(velocity, hit.normal);
- if (dot > 0f) {
- velocity = (velocity - hit.normal * dot).normalized * speed;
- }
- return true;
- }
- [SerializeField, Min(0f)]
- float probeDistance = 1f;
- if (!Physics.Raycast(
- body.position, Vector3.down, out RaycastHit hit,
- probeDistance, probeMask
- )) {
- return false;
- }
- [SerializeField]
- LayerMask probeMask = -1, stairsMask = -1;
- [SerializeField, Range(0, 90)]
- float maxGroundAngle = 25f, maxStairsAngle = 50f;
- float minGroundDotProduct, minStairsDotProduct;
- void OnValidate () {
- minGroundDotProduct = Mathf.Cos(maxGroundAngle * Mathf.Deg2Rad);
- minStairsDotProduct = Mathf.Cos(maxStairsAngle * Mathf.Deg2Rad);
- }
- float GetMinDot (int layer) {
- return stairsMask != layer ?
- minGroundDotProduct : minStairsDotProduct;
- }
- return (stairsMask & (1 << layer)) == 0 ?
- void EvaluateCollision (Collision collision) {
- float minDot = GetMinDot(collision.gameObject.layer);
- for (int i = 0; i < collision.contactCount; i++) {
- Vector3 normal = collision.GetContact(i).normal;
- if (normal.y >= minDot) {
- groundContactCount += 1;
- contactNormal += normal;
- }
- }
- }
- if (hit.normal.y < GetMinDot(hit.collider.gameObject.layer)) {
- return false;
- }
- Vector3 contactNormal, steepNormal;
- int groundContactCount, steepContactCount;
- bool OnGround => groundContactCount > 0;
- bool OnSteep => steepContactCount > 0;
- void ClearState () {
- groundContactCount = steepContactCount = 0;
- contactNormal = steepNormal = Vector3.zero;
- }
- if (normal.y >= minDot) {
- groundContactCount += 1;
- contactNormal += normal;
- }
- else if (normal.y > -0.01f) {
- steepContactCount += 1;
- steepNormal += normal;
- }
- bool CheckSteepContacts () {
- if (steepContactCount > 1) {
- steepNormal.Normalize();
- if (steepNormal.y >= minGroundDotProduct) {
- groundContactCount = 1;
- contactNormal = steepNormal;
- return true;
- }
- }
- return false;
- }
- if (OnGround || SnapToGround() || CheckSteepContacts()) {
- stepsSinceLastGrounded = 0;
- jumpPhase = 0;
- if (groundContactCount > 1) {
- contactNormal.Normalize();
- }
- }
- void Jump () {
- Vector3 jumpDirection;
- stepsSinceLastJump = 0;
- jumpPhase += 1;
- float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight);
- float alignedSpeed = Vector3.Dot(velocity, jumpDirection);
- if (alignedSpeed > 0f) {
- jumpSpeed = Mathf.Max(jumpSpeed - alignedSpeed, 0f);
- }
- velocity += jumpDirection * jumpSpeed;
- }
- }
- Vector3 jumpDirection;
- if (OnGround) {
- jumpDirection = contactNormal;
- }
- else if (OnSteep) {
- jumpDirection = steepNormal;
- }
- else if (jumpPhase < maxAirJumps) {
- jumpDirection = contactNormal;
- }
- else {
- return;
- }
- stepsSinceLastGrounded = 0;
- if (stepsSinceLastJump > 1) {
- jumpPhase = 0;
- }
- else if (maxAirJumps > 0 && jumpPhase <= maxAirJumps) {
- if (jumpPhase == 0) {
- jumpPhase = 1;
- }
- jumpDirection = contactNormal;
- }
- else if (OnSteep) {
- jumpDirection = steepNormal;
- jumpPhase = 0;
- }
- jumpDirection = (jumpDirection + Vector3.up).normalized;
- float alignedSpeed = Vector3.Dot(velocity, jumpDirection);
- //This is a very old script I made a year ago in Unity3D and never used so apologies if it doesn't work, I just learnt it from an old YouTube tutorial so it may be broken! (same as: https://pastebin.com/80qY21pB)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement