0
\$\begingroup\$

I'm pretty new to c# and Unity so I wouldn't be surprised if I had made some stupid mistakes, but as far as I know, I don't think I misused Time.deltaTime. Any help would be greatly appreciated.

Movement Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public CharacterController controller;

    public float speed = 12f;
    public float gravity = -9.81f;
    public float jumpHeight = 3f;

    public Transform groundCheck;
    public float groundDistance = 0.4f;
    public LayerMask groundMask;
    private float crouchMultiplier = 1f;

    private Vector3 velocity;
    private bool isGrounded;
    private bool isCrouched;
    private float velocityDecay = 1f;

    // Update is called once per frame
    void Update()
    {
        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

        if (isGrounded && velocity.y < 0)
        {
            velocity.y = -2f;
        }

        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Vector3 move = transform.right * x + transform.forward * z;

        controller.Move(move * speed * crouchMultiplier * velocityDecay * Time.deltaTime);
        
        Debug.Log(Time.deltaTime);
        
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
        }

        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            isCrouched = true;
            gameObject.transform.localScale = new Vector3(1, 1f, 1);
        }

        if (Input.GetKeyUp(KeyCode.LeftControl))
        {
            crouchMultiplier = 1f;
            gameObject.transform.localScale = new Vector3(1, 2f, 1);
            velocityDecay = 1;
            isCrouched = false;
        }

        if (isCrouched)
        {
            if (velocityDecay > 0.2f && isGrounded)
            {
                crouchMultiplier = 2.5f;
                velocityDecay *= 0.995f;
            }
        }




        velocity.y += gravity * Time.deltaTime;

        controller.Move(velocity * Time.deltaTime);
    }
}

Camera Script:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseLook : MonoBehaviour
{


    public Transform playerBody;
    public float mouseSensitivity = 100f;
    
    float xRotation = 0f;
        
    // Start is called before the first frame update
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    // Update is called once per frame
    void Update()
    {
        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90);
        
        transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
        playerBody.Rotate(Vector3.up * mouseX);
    }
}
```
\$\endgroup\$
  • \$\begingroup\$ Assuming the PlayerMovement script is on the same object as CharacterController, it looks to me like Vector3 move = transform.right * x + transform.forward * z; would cause your character to move faster the further they were from 0,0,0. Is that intentional behavior? Normally I would expect those to be something like Vector3.right and Vector3.forward. \$\endgroup\$ – Chris Mills-Price Jun 25 at 17:20
  • \$\begingroup\$ @ChrisMills-Price transform.right and transform.forward are relative to the transform's heading. They do not increase with distance from the world origin. Vector3.right and Vector3.forward are relative to the world (i.e. east and north respectively). \$\endgroup\$ – Kevin Jun 25 at 17:57
  • \$\begingroup\$ @Kevin Wow, absolutely. Not sure what I was thinking there, obviously nothing correct. :) \$\endgroup\$ – Chris Mills-Price Jun 25 at 19:04
0
\$\begingroup\$

Time.deltaTime is not always 100% accurate. It can sometimes be slightly off if the framerate is extremely high or low, or if you have modified Time.timeScale

Movement is usually better handled in FixedUpdate(). This syncs it with the physics engine and gives a more consistent experience regardless of framerate and timescale.

A good approach is to read input in the Update() function but apply motion in the FixedUpdate() function. An extremely simple example:

float speed = 5;
float horizontalInput = 0;

void Update() {
    horizontalInput = Input.GetAxis("Horizontal");
}

void FixedUpdate() {
    //You can use Time.deltaTime here and Unity will automatically
    //detect that it's in a FixedUpdate and give the appropriate value.
    //Or you can use Time.fixedDeltaTime if you prefer
    transform.position += transform.right * horizontalInput * speed * Time.deltaTime;
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I can't help but think this might be for a rigidbody as my player clips through some objects when I use this format. Either that or just bad implementation on my behalf \$\endgroup\$ – BasedSoup Jun 25 at 18:42
  • \$\begingroup\$ Setting position with transform.position does indeed clip through collisions. You'll want to use CharacterController.Move if you're using a character controller, or Rigidbody.MovePosition and related methods if using a rigidbody, to move in a collision-aware fashion. \$\endgroup\$ – DMGregory Jun 25 at 19:02
  • \$\begingroup\$ Awesome thanks, do you have any idea how the same would work with my camera, when i put the camera in fixedupdate its jittery \$\endgroup\$ – BasedSoup Jun 25 at 19:31
  • \$\begingroup\$ I didn't mean for the example to be used as-is; it's just a simple example of how you can tie Update() input with FixedUpdate() movement logic. If the camera is jittering when it collides with objects, that could be the positioning code fighting with the physics - e.g. your code tries to put the camera inside a wall, then the physics engine moves it, then your code tries to put it back in the wall... This can be tricky to fix and the best solution depends on your game. If it's jittering all the time, something else is wrong. If you can't figure out what, you might try LERPing the camera. \$\endgroup\$ – Kevin Jun 25 at 21:19
  • \$\begingroup\$ No I mean the camera sensitivity is also different based on framerate \$\endgroup\$ – BasedSoup Jun 25 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.