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 /
avatar image
0
Question by Zacker · Jan 15, 2014 at 09:15 AM · physicscharactercontrollergravityframeratecharacter movement

Low fps issues for character movement

I have this CharacterMovement.cs script which works great for moving around my character except for in the cases of the frame rate being low. What happens is that when walking of e.g. a cliff the character does not just fall but also instead moves up and down in an irregular motion - and can even end up at a higher point than the cliff the character walked of. With decent framerates everything works perfectly.

If I had missed a *deltatime somewhere this would generally make physics behave slower on low end devices but in this case the gravity just becomes weird in a very irregular way.

Can anyone pinpoint the culprit?

 using UnityEngine;
 using System.Collections;
 
 /// <summary>
 /// This takes care of moving and animating a character. Can be plugged in with multiple different input methods.
 /// </summary>
 public class CharacterMovement : MonoBehaviour
 {
     [SerializeField] private float runSpeed = 5.0f;
 
     // How high do we jump when pressing jump
     [SerializeField] private float jumpHeight = 2f;
     [SerializeField] private float inAirControlAcceleration = 3.0f;
 
     [SerializeField] private float speedSmoothing = 10.0f;
     [SerializeField] private float rotateSpeed = 1000.0f;
 
     private CharacterController CharacterController;
     private CharacterState PlayerState;
     protected IInputMethod CurrentInput;
 
     // The gravity for the character
     private const float Gravity = 9.8f;
   
     private Vector3 InAirVelocity = Vector3.zero;
 
     // The current move direction in x-z
     private Vector3 MoveDirection = Vector3.zero;
     // The current vertical speed
     private float VerticalSpeed;
     // The current x-z move speed
     private float MoveSpeed;
     private float TargetSpeed;
 
     // The last collision flags returned from controller.Move
     private CollisionFlags CollisionFlags;
 
     private const float GroundedTimeout = 0.25f;
     private float LastGroundedTime = 0.0f;
 
     private const float MovementDistanceThreshold = 0.5f;
     // The coordinates which the player will walk towards
     private Vector3 TargetPosition;
 
     public bool isControllable = true;
 
     protected void Awake()
     {
         CharacterController = GetComponent<CharacterController>();
 
         MoveDirection = transform.forward;
         TargetPosition = transform.position;
     }
 
     private Vector3 GetInputDirection()
     {
         TargetPosition = CurrentInput.GetMoveTarget();
         if (TargetPosition != Vector3.zero)
         {
             Vector3 newDirection = TargetPosition - transform.position;
             newDirection.y = 0;
 
             if (newDirection.magnitude <= MovementDistanceThreshold)
             {
                 // This is to ensure that the controller actually reaches it goal
                 //Debug.Log("Reached movement target");
                 newDirection = Vector3.zero;
             }
 
             return newDirection.normalized;
         }
         return Vector3.zero;
     }
 
     private void UpdateSmoothedMovementDirection()
     {
         // Target direction relative to the camera
         Vector3 targetDirection = GetInputDirection();
 
         // Grounded controls
         if (IsGroundedWithTimeout())
         {
             /* if (isMoving != wasMoving)
                     lockCameraTimer = 0.0f;*/
 
             // Choose target speed
             TargetSpeed = 0f;
 
             // We store speed and direction seperately,
             // so that when the character stands still we still have a valid forward direction
             // moveDirection is always normalized, and we only update it if there is user input.
             if (targetDirection != Vector3.zero)
             {
                 MoveDirection = Vector3.RotateTowards(MoveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 0f);
                 MoveDirection = MoveDirection.normalized;
 
                 PlayerState = CharacterState.Running;
                 TargetSpeed = runSpeed;
             }
 
             // Smooth the speed based on the current target direction
             float curSmooth = speedSmoothing * Time.deltaTime;
 
             MoveSpeed = Mathf.Lerp(MoveSpeed, TargetSpeed, curSmooth);
 
             if (MoveSpeed < 0.1f)
             {
                 MoveSpeed = 0f;
             }
         }
         else
         {
             // In air controls
             InAirVelocity += targetDirection * Time.deltaTime * inAirControlAcceleration;
         }
     }
 
    
 
     private void CalculateVerticalSpeed()
     {
         if (isControllable) // don't move player at all if not controllable.
         {
             if (IsGroundedWithTimeout() && !Jumping)
             {
                 VerticalSpeed = 0.0f;
             }
             else
             {
                 VerticalSpeed -= Gravity * Time.deltaTime;
                 //VerticalSpeed -= Gravity;
             }
         }
     }
    
 
     private bool GetDirectionValidity()
     {
         // If the character controller registers a collision in the front
         return CollisionFlags != (CollisionFlags) 3 && CollisionFlags != (CollisionFlags) 7;
     }
 
     //private void 
     private void Update()
     {
         if (!isControllable)
         {
             // kill all inputs if not controllable.
             Input.ResetInputAxes();
         }
 
         CurrentInput.Update();
 
         UpdateSmoothedMovementDirection();
 
         CalculateVerticalSpeed();
 
         // Calculate actual motion
         //Debug.Log("Vertical speed is: " + VerticalSpeed);
         //Debug.Log("Inair vel: " + InAirVelocity);
         Vector3 movement = MoveDirection * MoveSpeed + new Vector3(0, VerticalSpeed, 0) + InAirVelocity;
         movement *= Time.deltaTime;
 
         // Move the controller
         CollisionFlags = CharacterController.Move(movement);
 
         if (!GetDirectionValidity())
             TargetPosition = transform.position;
 

         SetRotation(movement);
 
         if (CharacterController.isGrounded)
         {
             LastGroundedTime = Time.time;
             InAirVelocity = Vector3.zero;
             // We are in jump mode but just became grounded
             if (Jumping)
             {
                 Jumping = false;
                 PlayerState = CharacterState.Idle;
             }
         }
     }
 
     // Set rotation to the move direction
     private void SetRotation(Vector3 movement)
     {
         if (CharacterController.isGrounded)
         {
             transform.rotation = Quaternion.LookRotation(MoveDirection);
         }
         else
         {
             Vector3 xzMove = movement;
             xzMove.y = 0;
             if (xzMove.sqrMagnitude > 0.001f)
             {
                 transform.rotation = Quaternion.LookRotation(xzMove);
             }
         }
     }
 
    
     //The unity Charactercontroller is bugged and constantly toggles between isgrounded false/true
     //This fixes it
     private bool IsGroundedWithTimeout()
     {
         return LastGroundedTime + GroundedTimeout > Time.time;
     }
 }
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

0 Replies

· Add your reply
  • Sort: 

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

18 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

Related Questions

Gravity not working 1 Answer

Calculating linear speed at a point on a rotating platform 0 Answers

Gravity still being applied with unity CharacterController 0 Answers

i clip into my walls with a character controller 0 Answers

Can't get gravity to work on Character Controller 2 Answers


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