Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by HappyFoots · Nov 15, 2020 at 08:41 AM · 2d-platformerrigidbody2dphysics2d2d-physics

FixedUpdate or Update for collision detection and climbing slopes?

I am learning about unit and trying to figure out how to use the fixed update correctly. I saw that in the platformer kit 2D they used collision detection and movement in fixed update. Thanks in advance.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class CustomPhysics : RaycastOrigins
 {
     protected Vector2 velocity;
     private Rigidbody2D rb2d;
     private ContactFilter2D contactFilter2D;
     private RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
     private List<RaycastHit2D> hitList = new List<RaycastHit2D>();
 
     private float shellRadius = 0.015f;
     private float minGroundNormalY = 0.0f;
     private float minMoveDistance = 0.001f;
 
     bool grounded = false;
     private Vector2 groundNormal;
     private float gravityModifier = 1f;
 
     protected Animator animator;
     protected Vector2 targetVelocity;
     private Vector2 currentPosition;
     private Vector2 nextPosition;
     public Collisions collisons2D;
     public float maxClimbingAngle = 60;
     public LayerMask groundMask=0;
     int facingRight;
 
     private void OnEnable()
     {
         
     }
 
     public override void Awake()
     {
         base.Awake();
         rb2d = GetComponent<Rigidbody2D>();
         animator = GetComponent<Animator>();
     }
 
     // Start is called before the first frame update
     public override void Start()
     {
         base.Start();
         contactFilter2D.useTriggers = false;
         contactFilter2D.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
         contactFilter2D.useLayerMask = true;
         
         Debug.Log("verticalSpacing:" + verticalRaycastSpacing);
     }
 
     // Update is called once per frame
     void Update()
     {
 
     }
 
     private void FixedUpdate()
     {
         //if (groundNormal.x == 0)
         //{
         //    groundNormal = Vector2.up;
         //}
         CalculateOrigins();
         collisons2D.Reset();
         //collisons2D.slopeAngleOld = collisons2D.slopeAngle;
         //collisons2D.slopeAngle = 0;
         grounded = false;
 
         currentPosition = rb2d.position;
 
         HorizontalCollisions(ref velocity);
 
         VerticalCollisions(ref velocity);
 
         
 
 
         Debug.Log("VELOCITY:"+velocity.y);
         Debug.Log("SLOPEANGLE:" + collisons2D.slopeAngle);
 
         
         nextPosition = currentPosition + velocity;
         rb2d.MovePosition(nextPosition);
         velocity = Vector2.zero;
 
 
 
         Debug.Log("Collisions UP|DOWN:" + collisons2D.up + "|" + collisons2D.down);
         Debug.Log("Collisions LEFT|RIGHT:" + collisons2D.left + "|" + collisons2D.right);
         Debug.Log("CLIMBINGSLOPE:" + collisons2D.climbingSlope);
         //Debug.Log("FacingRight:" + facingRight);
         
         //Debug.Log("velocityY "+ velocity.y);
         //animator.SetFloat("velocityX", velocity.x);
         animator.SetBool("grounded", grounded);
         //Debug.DrawRay(rb2d.position, new Vector2(0, 0.1f) * 10, Color.blue);
         //Debug.DrawRay(rb2d.position, moveAlongGround, Color.green);
     }
 
     public void Move(Vector2 move)
     {
         velocity += move;
     }
 
     private void HorizontalCollisions(ref Vector2 velocity)
     {
         float distance = Mathf.Abs(velocity.x) + skinWidth;
         float directionX = Mathf.Sign(velocity.x);
         
         for (int i = 0; i < horizontalRaycastsCount; i++)
         {
             Vector2 rayOrigin = directionX == -1 ? origins.bottomLeft : origins.bottomRight;
             rayOrigin += Vector2.up * (i * horizontalRaycastSpacing);
             Debug.DrawRay(rayOrigin, Vector2.right * directionX * distance, Color.red);
             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, distance, groundMask);
             if (hit)
             {
                 Debug.Log("HIT I=" + i);
                 float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
                 if (i == 0 && slopeAngle <= maxClimbingAngle)
                 {
                     Debug.DrawRay(hit.point, hit.normal.normalized*hit.distance);
                     //velocity.x -= (hit.distance - skinWidth) * directionX;
 
                     float tmp = 0;
                     if (slopeAngle != collisons2D.slopeAngleOld)
                     {
                         Debug.Log("before velocity:" + velocity.x);
                         //tmp = velocity.x;
                         Debug.Log("distanceToSlopeStart:" + tmp);
                         
                         //velocity.x = (hit.distance-skinWidth) * directionX;
                         //Debug.DrawRay(rb2d.position, velocity, Color.green);
                         //transform.Translate(new Vector2(directionX * tmp, 0));
                         //Debug.Log("after velocity:" + velocity.x);
                         //Debug.Log("HITPOINTX" + hit.point.x);
                         //Debug.Break();
                         //slopeAngle -= 5;
                     }
                     
                     ClimbingSlope(ref velocity, slopeAngle);
 
                     //velocity.x += (hit.distance - skinWidth) * directionX;
                     //velocity.x +=tmp;
                     Debug.Log("VELOCITYX I=0:" + velocity.x);
                 }
                 Debug.Log("SLOPEANGLE I=" + i + ":" + slopeAngle);
                 if (!collisons2D.climbingSlope || slopeAngle > maxClimbingAngle)
                 {
                     velocity.x = (hit.distance - skinWidth) * directionX;
                     Debug.Log("VELOCITYX:" + velocity.x);
                     distance = hit.distance;
 
                     if (collisons2D.climbingSlope)
                     {
                         velocity.y = Mathf.Tan(collisons2D.slopeAngle * Mathf.Deg2Rad) * Mathf.Abs(velocity.x);
                     }
 
 
                     collisons2D.left = directionX == -1;
                     collisons2D.right = directionX == 1;
                 }
                 
                 
             }
         }
         Debug.DrawRay(rb2d.position, velocity, Color.blue);
 
     }
     private void VerticalCollisions(ref Vector2 velocity)
     {
         float distance = Mathf.Abs(velocity.y)+skinWidth;
         float directionY = Mathf.Sign(velocity.y);
         
         for (int i = 0; i < verticalRaycastsCount; i++)
         {
             Vector2 rayOrigin = directionY == -1 ? origins.bottomLeft : origins.topLeft;
             rayOrigin += Vector2.right * (i * verticalRaycastSpacing);
             Debug.DrawRay(rayOrigin , Vector2.up * directionY * distance, Color.red);
             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, distance, groundMask);
             if (hit)
             {
 
                 velocity.y = (hit.distance - skinWidth) * directionY;
                 distance = hit.distance;
 
                 if (collisons2D.climbingSlope)
                 {
                     velocity.x = velocity.y / Mathf.Tan(collisons2D.slopeAngle * Mathf.Deg2Rad) * Mathf.Sign(velocity.x);
                 }
 
                 collisons2D.down = directionY == -1;
                 collisons2D.up = directionY == 1;
             }
         }
 
         if (collisons2D.climbingSlope)
         {
             float directionX = Mathf.Sign(velocity.x);
             Vector2 rayOrigin = directionX == -1 ? origins.bottomLeft : origins.bottomRight;
             Debug.DrawRay(rayOrigin, Vector2.right * directionX * distance, Color.cyan);
             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, distance, groundMask);
             if(hit)
             {
                 float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
                 if (slopeAngle != collisons2D.slopeAngle)
                 {
                     //Debug.Break();
                 }
             }
         }
     }
     protected virtual void ComputeVelocity()
     {
 
     }
     private void MoveHorizontal(ref Vector2 move)
     {
 
     }
 
     private void MoveVertical(ref Vector2 move)
     {
 
     }
     private void ClimbingSlope(ref Vector2 velocity,float slopeAngle)
     {
         float moveDistance = Mathf.Abs(velocity.x);
         float climbingVelocityY = Mathf.Sin(slopeAngle * Mathf.Deg2Rad) * moveDistance;
         if (velocity.y <= climbingVelocityY)
         {
             
             velocity.y = climbingVelocityY;
             velocity.x = Mathf.Cos(slopeAngle * Mathf.Deg2Rad) * moveDistance * Mathf.Sign(velocity.x);
             //Vector2 rayOrigin = Mathf.Sign(velocity.x) == -1 ? origins.bottomLeft : origins.bottomRight;
             //RaycastHit2D hit = Physics2D.Raycast(rayOrigin,velocity,)
             collisons2D.down = true;
             collisons2D.climbingSlope = true;
             collisons2D.slopeAngle = slopeAngle;
             //velocity.x -= tmp * directionX;
 
         }
         Debug.Log("CLIMBINGVELOCITY VELOCITY:" + velocity);
         //Debug.Break();
     }
     public struct Collisions
     {
         public bool left, right;
         public bool up, down;
         public float slopeAngle;
         public bool climbingSlope;
         public float slopeAngleOld;
         public void Reset()
         {
             left = right = false;
             up = down = false;
             climbingSlope = false;
             slopeAngleOld = slopeAngle;
             slopeAngle = 0;
         }
     }
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by sztobar · Nov 16, 2020 at 08:22 AM

You can google Update vs FixedUpdate unity and get a ton of different answers, but since you asked here, let me try to describe it here for you.

yes - FixedUpdate should be used for physics, and your code is correct by calling raycasts and doing stuff with rigidbody2d there.

If you had a simple code like that:

 void Update() {
   transform.Translate(velocity * Time.deltaTime);
 }
 void FixedUpdate() {
   transform.Translate(velocity * Time.fixedDeltaTime);
 }

Update can be called with a different Time.deltaTime and that means that if a player computer gets slow for a moment, it will lag your game and call Update with a potentially huge Time.deltaTime. That means that you could by accident overshoot your physics-related code because suddenly rather than moving by eg. one pixel you move by 20 pixels. In the same time, FixedUpdate is always runned with constant Time.fixedDeltaTime and it can be called multiple times in one frame. So instead of having one long Update frame it would result in multiple FixedUpdate calls. Instead of moving by 20 pixels, you would call 20 times FixedUpdate and your code could react to the changed position of main player for each pixel that he moved.

Hope this example clarified it a little.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image HappyFoots · Nov 17, 2020 at 03:15 PM 0
Share

@sztobar . Thank you for the answer. Yes, your explanation helped me figure it out.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

233 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

2D Top-Down Character: How to make my character move using physics? 1 Answer

How Do I make my character move? 0 Answers

How to move rigidbodies with 2D Character controller (No rigidbody) 1 Answer

How can I slow the movement of a single rigidbody2D? 2 Answers

I want my player to walk through walls 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges