'Unity3D Player walking through and on the Stone

Hello guys my Player is walking on the Stone and through the Stone. The Player called Champ has a Box Collider and the Stone has a Mesh Collider. Also the Player has Rigidbody. I tried everthing i found but nothing helped me with my problem.

MovePlayer.cs Script

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

public class MovePlayer : MonoBehaviour
{

    Rigidbody rb;

    public float speed = 10f;
    private Vector3 moveDirection;
    public float rotationSpeed = 0.05f;

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

    void Update()
    {
        moveDirection = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")).normalized;
    }

    void FixedUpdate()
    {
        rb.MovePosition(rb.position + transform.TransformDirection(moveDirection * speed * Time.deltaTime));
        RotatePlayer();
    }

    void RotatePlayer()
    {
        if (moveDirection != Vector3.zero)
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(moveDirection.normalized), rotationSpeed);
        }
        transform.Translate(moveDirection * speed * Time.deltaTime, Space.World);
    }

}

Player Settings in Inspector

Stone Settings in Inspector

Scene Preview

Thank you for help guys! :)



Solution 1:[1]

So guys i found out the Solution with the help of the guys posted above.

The problem was that my player speed was too high in the Code the speed was on float 10, but i changed the velocity in the Unity Inspector of Player to float 50.

So my first step to solve the problem was to set the speed down to float 10, but i still wanted to move with a speed of 50f...

The Solution for this problem was that in Unity 2020.3.24f1 and higher (probably lower) you can go to Edit>Project Settings>Physics and set the "Default Max Depenetration Velocity" to the speed you want the objects stopping and not going through. In my case i wanted to move with speed = 50f so i needed to change Default Max Depenetration Velocity to 50.

I hope i can help someone with this Answer in future!

Best Wishes Max G.

Solution 2:[2]

Tested your code and collisions seem to be working fine on my end.

Tested it by adding the script to a GameObject with box collider and creating a small level using cubes. Also made a wall that I modified to use mesh-collider instead of box collider. Player collided normally with objects in the scene.

You should double check your Layer collision matrix from Project Settings > Physics whether you've set layers player and wall to collide.

  1. You could also try adding new cube to the scene and setting its layer to wall to see if player collides with it. If it does then the there might be issues with the mesh of the stone.
  2. If not then I would disable animator and Gravity Body components from the player to make sure they're not interfering with the collisions

Rigidbody.MovePosition basically makes the player teleport which can cause unexpected behaviors. It's generally recommended to use Rigidbody.AddForce instead. For precise movement ForceMode.VeloictyChange can be used.

public float maxVelocityChange = 5.0f;

void moveUsingForces(){

    Vector3 targetVelocity = moveDirection;
    // Doesn't work with the given RotatePlayer implementation.
    // targetVelocity = transform.TransformDirection(targetVelocity);
    targetVelocity *= speed;

    // Apply a force that attempts to reach our target velocity
    Vector3 velocity = rb.velocity;
    Vector3 velocityChange = (targetVelocity - velocity);
    velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
    velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
    velocityChange.y = 0;
    rb.AddForce(velocityChange, ForceMode.VelocityChange);
}

Solution 3:[3]

In this code you have applied motion twice and the problem is that transform.Translate is used. Remember that Rigidbody class methods are sensitive to colliders and recognize them, but transform is not the same and only applies a point-to-point shift. To solve the problem, I think you will not need a duplicate motion code with translate in the rotate section.

void RotatePlayer()
{
    if (moveDirection != Vector3.zero)
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(moveDirection.normalized), rotationSpeed);
    }
    // removed translate
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Maximilian Grinik
Solution 2
Solution 3 KiynL