Home > Software engineering >  Add force acting different ways in Unity using C#
Add force acting different ways in Unity using C#

Time:11-04

So ball is moving forwards on it's own with AddForce. Code works but only problem is that it's speed changes. It depends what size is the display. When MaximizeOnPlay is enabled ball moves too fast and when it's turned off ball moves slowly. Here's my PlayerContoller script(if RigidBody is needed just let me know and I will attach screenshot of it):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour
{

    private bool isGrounded = false;

    private Rigidbody _ourRigidbody;

    [SerializeField] private float verticalSpeed = 0.7f;

    void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }
    void OnCollisionExit(Collision other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            isGrounded = false;
        }
    }


    void Start()
    {
        _ourRigidbody = GetComponent<Rigidbody>();
    }


    void LateUpdate()
    {
        if (isGrounded)
        {
            verticalSpeed = 0.7f;
            _ourRigidbody.mass = 1;
        }
        if (!isGrounded)
        {
            verticalSpeed = -5;
            _ourRigidbody.mass = 90;
        }
        float verticalDelta = verticalSpeed * Time.fixedDeltaTime;
        Vector3 force = new Vector3(0, verticalDelta, verticalSpeed);
        _ourRigidbody.AddForce(force);
    }
}

CodePudding user response:

If you don't care about realistic physics and just want to have a constant speed, you could use _ourRigidbody.velocity(<your velocity vector>) instead.

If instead you want to ensure physics behaviour is deterministic, you'll have to use FixedUpdate as your controller loop. This ensures the requested force is applied in a fixed time interval. Example:

    void FixedUpdate() //This changed
    {
        if (isGrounded)
        {
            verticalSpeed = 0.7f;
            _ourRigidbody.mass = 1;
        }
        if (!isGrounded)
        {
            verticalSpeed = -5;
            _ourRigidbody.mass = 90;
        }
        float verticalDelta = verticalSpeed * Time.fixedDeltaTime;
        Vector3 force = new Vector3(0, verticalDelta, verticalSpeed);
        _ourRigidbody.AddForce(force);
    }

CodePudding user response:

LateUpdate is called every frame.

Within it you don't want to use Time.fixedDeltaTime which is the interval in which FixedUpdate is called but rather Time.deltaTime

The interval in seconds from the last frame to the current one

float verticalDelta = verticalSpeed * Time.deltaTime;

In general you should do physics related stuff rather in FixedUpdate. Even their Unity recommends to still use Time.deltaTime since

When this is called from inside MonoBehaviour.FixedUpdate, it returns Time.fixedDeltaTime.

so using Time.deltaTime you are always on the save side.

  • Related