简体   繁体   中英

How can i stop cube from rolling

i got a runner game and cube is my player, the problem is i can't stop cube from rolling. The ground is slippery(friction = 0) but it is still rolling. When i freeze rotation of y axis it seems like lagging so it doesn't work either. Please help me. There is my movement code

I changed values of mass and drag but it didn't help.

public Rigidbody rb;
public float forwardForce = 2000f;
public float sidewaysForce = 500f;
public float acceleration;
public PlayerMovement movement;

void FixedUpdate()
{
    rb.AddForce(0, 0, forwardForce * Time.deltaTime);
    forwardForce += Time.deltaTime * acceleration;

    if (Input.GetKey("d"))
    {
        rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
    }
    if (Input.GetKey("a"))
    {
        rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
    }

There are no error messages.

您可以尝试将Time.deltaTime替换为Time.fixedDeltaTime,因为它位于FixedUpdate中。

Okay so after trying to help you in the comments I have written a small demo of what you are trying to achieve so you can use it to try and find where you went wrong before and how I would go about doing what you are trying to do.

Cube Controls

using UnityEngine;

public class CubeControl : MonoBehaviour
{
    public Rigidbody rb;

    public float forwardForce = 2000f;
    public float sidewaysForce = 500f;
    public float acceleration = 1;

    void FixedUpdate()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime);
        forwardForce += Time.deltaTime * acceleration;

        //Using the in-built methods uses the keys you were but also the arrow keys
        float inputX = Input.GetAxis("Horizontal");

        //Check there is input
        if (Mathf.Abs(inputX) > float.Epsilon)
        {
            //set which force direction to use by comparing the inputX value
            float force = inputX > 0 ? sidewaysForce : -sidewaysForce;
            rb.AddForce(force * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

    }
}

There are a couple of changes there but they are commented to explain.

Camera Tracking

using UnityEngine;

public class CameraTracking : MonoBehaviour
{
#pragma warning disable 0649
    [SerializeField] private GameObject _cube;
#pragma warning restore 0649

    private Vector3 offset;

    void Awake()
    {
        offset = _cube.transform.position + transform.position;
    }

    void LateUpdate() {
        transform.position = _cube.transform.position + offset;
    }
}

It uses the initial offset between the cube and Camera that is setup before starting the pressing play.

Tip I recommend not using this but making the camera a child of the cube as this is something that you are calcualting each frame which you don't need too!

Path Generator

using UnityEngine;
using System.Collections;
public class PathGenerator : MonoBehaviour
{
#pragma warning disable 0649
    [SerializeField] private GameObject _path1;
    [SerializeField] private GameObject _path2;
    [SerializeField] private GameObject _cube;
#pragma warning restore 0649

    private float _cubeRepositionZDistance;

    private float _pathPositionX;
    private float _pathPositionY;

    //Distance center of path should be behind the cube;
    private float _resetDistanceFromCube = 25f;

    private void Awake()
    {
        // You could hard code this but this way you can change the length of each path segment and it will be updated here automatically.
        _cubeRepositionZDistance += _path1.transform.localScale.z / 2;
        _cubeRepositionZDistance += _path2.transform.localScale.z / 2;

        _pathPositionX = _path1.transform.position.x;
        _pathPositionY = _path1.transform.position.y;

        // Position path2 relative to path1.transform.position
        _path2.transform.position = new Vector3(_pathPositionX, _pathPositionY, _path1.transform.position.z + _cubeRepositionZDistance);

        StartCoroutine(PathRepositioner());
    }

    private IEnumerator PathRepositioner()
    {
        //Can change bool to something like !GameOver
        while (true)
        {
            if (_path1.transform.position.z < _cube.transform.position.z - _resetDistanceFromCube)
            {
                _path1.transform.position = new Vector3(_pathPositionX, _pathPositionY, _path2.transform.position.z + _cubeRepositionZDistance);
            }
            if (_path2.transform.position.z < _cube.transform.position.z - _resetDistanceFromCube) 
            {
                _path2.transform.position = new Vector3(_pathPositionX, _pathPositionY, _path1.transform.position.z + _cubeRepositionZDistance);
            }
            yield return null;
        }
    }

}

Doing it this way you are reusing the same 2 path segements and not creating clones all the time, you can change it to use 3 or more if needed.

Scene Setup

Position the cube and then position the path1 segement under the Cube.

Assign all required GameObjects to the scripts in the inspector.

Press Play!

Sidenote: It is recommended to move the path segements not the Cube(Player) when doing an endless runner like this but as you are new to this I suggest reading up on that when you get a chance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM