0
\$\begingroup\$

I'm making a very peculiar outrun clone. I need the player to move forward automatically while being able to change his position on the road in his local X axis.

I made infinitely generated road and placed dolly track in the middle of the road. The track is swapping waypoints for the new ones every 3 map chunks. Like here: Is it possible to add new waypoints to Dolly Track in Unity CinemachineVirtualCamera on the go?

Translation movement

For now I have made the effect you see above using transfrom.translation. The problem is that if I wanted to collide with something on the edge of the road (like a barrier) I couldn't do that. I go right through any collider. I checked the collision with Debug.Log and it certainly fires.
I think I need rigidBody related movement like AddForce etc.

Currently I have a cart attached to the dollyTrack. The track moves the cart along the path. Camera is looking at the cart and following it. I made "player" a child of the cart, however player didn't move with it for some reason, so I made a script that moves player to the point that is 8 units forward in relation to the camera. It uses RigidBody.Move().

The problem:
I don't know how to simultaneously move player forward and allow him for movement to the sides and be able to collide with lets say - a wall on the side. When I try to make the side movement use RigidBody instead of translation it stops working at all. My theory is that forward movement takes precedence and side movement just doesn't occur.

This is the code I tinker with for player movement:

void MoveV2(bool accelerate, bool brake, float turnInput)
    {
        turnInputView = turnInput;

        bool pastRightScreenEdge = Camera.main.WorldToScreenPoint(transform.position).x >= Screen.width;
        bool pastLeftScreenEdge = Camera.main.WorldToScreenPoint(transform.position).x <= 0;


        float accelerationCurveCoeff = 5;
        float maxSpeed = m_FinalStats.TopSpeed;
        float accelPower = m_FinalStats.Acceleration;

        float currentSpeed = Rigidbody.velocity.magnitude;
        float accelRampT = currentSpeed / maxSpeed;
        float multipliedAccelerationCurve = m_FinalStats.AccelerationCurve * accelerationCurveCoeff;
        float accelRamp = Mathf.Lerp(multipliedAccelerationCurve, 1, accelRampT * accelRampT);

        float finalAccelPower = accelPower;

        float finalAcceleration = finalAccelPower * accelRamp;
        bool wasOverMaxSpeed = currentSpeed >= maxSpeed;




        turnInput = turnInput / 2; // So it doesn't bounce back so hard ? 

        if (!pastLeftScreenEdge)
        {
            if (turnInput < 0)
            {
                Rigidbody.AddRelativeForce(-transform.right * turnInput, ForceMode.Force);
                Rigidbody.velocity = -transform.right * turnInput *10;
            }
        }
        else
        {
            Rigidbody.velocity = -transform.right;
        }

        if (!pastRightScreenEdge)
        {
            if (turnInput > 0)
            {
                Vector3 fwd = transform.right;
                Vector3 movement = fwd * finalAcceleration * turnInput;

                //transform.Translate(turnInput, 0, 0);
                if (wasOverMaxSpeed)
                    movement *= 0.0f;

                Vector3 newVelocity = Rigidbody.velocity + movement * Time.fixedDeltaTime;
                newVelocity.y = Rigidbody.velocity.y;

                Rigidbody.velocity = newVelocity;
            }
        }
        else
        {
            Rigidbody.velocity = -transform.right;
        }
        //transform.Translate(turnInput, 0, 0);

    }

I tried different ways for left and right side movement but neither of them work. Is there a way to produce movement I need with RigidBody ? Alternatively just to make player collide with walls that might be on the sides of the road ?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Hey SirResnick2 :)

Good news regarding your movement - you can keep your movement code.

Ensure that isKinematic is checked on your players rigidbody.

When the rigidbody isKinematic forces, collisions or joints will not affect the rigidbody anymore - but OnTriggerEnter will still be called!

This means:

  1. Add the rigidbody to the player and enable isKinematic

  2. Add a collider to any barrier and enable the isTrigger

  3. Add a script to those barriers with following code

    private void OnTriggerEnter(Collider other) { // damage player }
    

When you want to move your rigidbody you go like this:

// We execute this in our FixedUpdate-Method
// Create our move vector
Vector3 move = new(Input.GetAxis("Horizontal") * moveSpeed, 0, forwardForce);
// Apply our move vector
yourRigidbody.velocity += move; // use this
yourRigidbody.AddForce(move); // or this
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hey - Thanks for giving me some of your time ! What I need however is to actually use RigidBody movement to ensure that collisions can occur between the player and a wall. As for now I confined player to a screen view by translating him in the opposite direction if he tries to pass. Sadly it produces stutter. So I wanted to use actual colision with invisible wall to make it smooth. As for now activating isKinematic makes player to stop moving forward. because the forward movement is done by RigidBody.Move() \$\endgroup\$ Feb 8 at 16:32
  • \$\begingroup\$ Oops, I apologize sincerely! To ensure independent movement regardless of the frame rate, you can manipulate a Rigidbody like this within the FixedUpdate method. _rigidbody.velocity += new Vector3(Input.GetAxis("Horizontal"), 0, YourForwardForce) You can also add a multiplier to the horizonal axis. \$\endgroup\$ Feb 8 at 16:50
1
\$\begingroup\$

While aleqzander's answer was useful it wasn't explicitly the solution.

What solved my problem was using Joints. I connected the player to the dolly cart that travels through CinemachineSmoothPath by customizable joint. It allowed the player to follow the cart while being able to move freely to the sides and collide with everything as rigidbody object.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .