Hot to create a physics-based player movement controller for a ski game?

I’m fairly new to unity and I’m creating a basic 3D skiing simulator.

I’m having trouble with moving the character in the direction it is facing, while still using a RigidBody 3D. The character is also bouncing on the terrain and I would like to remove that as well.

How do I do that?

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

public class PlayerMovementWithRotate : MonoBehaviour
{
    public float acceleration = 0.0f;
    float rotation = 0.0f;
    float accelerationReal;
    public Rigidbody rb;

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

        //multiply by speed (average of 3 vectors)
        accelerationReal =  acceleration * ((rb.velocity.x + rb.velocity.y + rb.velocity.z) / 3);
        //Rotate the player based off input
        transform.Rotate(transform.up, 100.0f * Time.deltaTime * rotation, Space.World);
        //Move the player
        transform.Translate(transform.forward * acceleration * Time.deltaTime, Space.World);
    }
}

Thank you so much to anyone who can help :slight_smile:

If you need a physics-based simulation, you need to work with RigidBody, not Transform.

Search for rigidbody.velocity, rigidbody.AddForce, rigidbody.MoveRotation, etc. Also, you must do this in FixedUpdate instead of Update, and use fixedDeltaTime instead of deltaTime.

If you manipulate the Transform in a body with Physics, you create a conflict in the movement. While the transform sets in a way, the physics system sets in another, probably causing weird behaviour, like your bouncing character.

Do the physics stuff in FixedUpdate, but I recommend you get the Input in Update (more weird behaviour alert).

Might sound weird at first but you could try using WheelColliders. If you think about it, skis aren’t that different from wheels. They both have a lot of friction on one axis and almost none on the other and they both have a kind of suspension. I would try giving each ski two or more wheel colliders like in-line skates.

Alternatively, use a PhysicMaterial with bounciness 0 and bounce combine Minimum and a very low friction on the skier. Then apply a force to prevent slipping sideways too much, for example like this:

void FixedUpdate() {
   var right = transform.right;
   var slip = Vector3.Dot(rigidbody.velocity, right);
   rb.AddForce(-slip * slip * sidewaysDrag * right, ForceMode.Acceleration);
}

As a general note, avoid using transform.Translate for physics-based motion but instead try to do everything by applying forces to the rigidbody in FixedUpdate. That way you allow the physics engine to control the motion and properly simulate acceleration, collisions, friction and drag.

Thank you, I’ll avoid using transform!