1
\$\begingroup\$

I created a simple scene, with a box that serves as the ground, and a capsule that serves as the player. I added to the player a RigidBody, and a component that should move it using AddForce:

private void FixedUpdate() {
    rb = GetComponent<Rigidbody>();
    float horizontal = Input.GetAxis("Horizontal");
    rb.AddForce(new Vector3(horizontal * forceSize, 0, 0), ForceMode.Force);
}

However, instead of moving straight along the ground, my capsule rolls over its head:

enter image description here

I tried to mark the checkbox near Freeze Rotation: Z in my RigidBody component, but then the capsule stopped moving altogether.

What is the correct way to apply force to the capsule?

EDIT: Initially, the physic material on both the player's collider and the ground collider was None. Now, I changed it to a new material with dynamic friction and static friction 0, and it moves straight (even with gravity and without freezing the Z rotation). However, if I even slightly increase either type of friction in either one of the materials, the player falls on its face again. Why does friction have this effect on the player? And how can I move the player correctly when there is positive friction?

\$\endgroup\$
7
  • 2
    \$\begingroup\$ Freezing the rotation of the capsule should work. Maybe you have a physics material on the capsule and/or floor with too much friction? \$\endgroup\$
    – Philipp
    May 12, 2020 at 8:42
  • \$\begingroup\$ I am not sure if freezing the rotation will work, as it may be blocking the force applied on rigid body, rigid body will fall due to gravity, if you don't need gravity in your project, disabling the gravity may work for you. \$\endgroup\$
    – Kharak
    May 12, 2020 at 9:22
  • \$\begingroup\$ Freeze rotation and use Rb.movePosition? \$\endgroup\$
    – Jay
    May 12, 2020 at 9:39
  • \$\begingroup\$ @Philipp My ground object has a box collider and my player has a capsule collider, and in both colliders, the Material field says "None (Physic Material)". \$\endgroup\$ May 12, 2020 at 13:41
  • 1
    \$\begingroup\$ @ErelSegal-Halevi the standard laws of physics say that if a forward force is applied to the middle of an object, and a friction force is applied to the bottom of an object, there will be a net torque that tends to make the object tip forward. If that's not the behaviour you want, then you need to either restrict the rotation (like the object were on a track), or reduce the friction, or adjust where you apply forces, or apply a counteracting torque. \$\endgroup\$
    – DMGregory
    May 12, 2020 at 14:44

2 Answers 2

1
\$\begingroup\$

I tried to set up a demo project to test around and found a simple approach based on rotation constraints as suggested by other users, and the AddForce() function as you needed it.

I applied a zero-friction material to both the capsule and the cube, and later found a nice value of 0.2 for one of the two only in Average combine mode (alternatively: 0.1 for both, but this is up to you).

Physics materials

The capsule's RigidBody component can be set as you wish, as long as you turn on Freeze Rotation Constraints for both the X and Z axes so that the capsule will always stand upwards. That's because your character-like collider isn't supposed to be rotating, except for on-spot turning: many movements are just cosmetic issues that you can deal with animations. It is only in charge of managing physics movements around your world.

Capsule rigidbody setup

Finally, I attached a script to the capsule object, which is a slightly edited version of your own code:

using UnityEngine;

public class CapsuleController : MonoBehaviour {
    public float forceSize;
    Rigidbody rb;

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

    void Update() {
        float horizontal = Input.GetAxis("Horizontal");
        rb.AddForce(new Vector3(horizontal * forceSize, 0f, 0f), ForceMode.Acceleration);
    }
}

This way, AddForce() applies a force in ForceMode.Acceleration mode (that is, same acceleration for everyone regardless of their mass) and the internal physics solver will step physics forward taking rotation constraints into account. The final result is a nice movement without the capsule tripping and tumbling down.

\$\endgroup\$
0
\$\begingroup\$

Either freeze rotation or use

GetComponent<Rigidbody>().MovePosition()
\$\endgroup\$
4
  • \$\begingroup\$ But my goal is to move the player physically, using forces. MovePosition does not do that \$\endgroup\$ May 12, 2020 at 13:48
  • \$\begingroup\$ Why you don't want to freeze the rotation then? \$\endgroup\$ May 12, 2020 at 14:11
  • \$\begingroup\$ When I freeze the rotation and use AddForce, the player does not move at all. \$\endgroup\$ May 12, 2020 at 14:11
  • \$\begingroup\$ Then you can try overwrite the rotation after the line with AddForce. \$\endgroup\$ May 12, 2020 at 14:16

You must log in to answer this question.

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