the problem I am having is when I run full speed (i.e. pressing a and w and looking 45 degrees to the right it doesn't use .normalized on purpose) into a wall or anything else it allows the player to go through it, so my code is
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
Vector3 moveDirection = m_Input;
moveDirection = transform.TransformDirection(moveDirection);
rb.MovePosition(transform.position moveDirection * moveSpeed);
and moveSpeed
is set to 0.2
. I have checked and all of the colliders are not triggers. any help would be greatly appreciated
CodePudding user response:
First off do double check
- All your colliders & rigidbody are 3d
- Everything is on the same layer (or your layers are set to interact with each other)
- Your rigidbody is attached to the same game object as your collider
However, it seems that your issue is that your rigidbody
is set to be kinematic (as Rigidbody.MovePosition is intended to be used by kinematic rigidbody's only)
If your rigidbody
is set to kinematic
then no forces (such as collider normal forces) will be applied to your object, so it will be able to pass through walls.
Solution
The easiest way to avoid this is by making sure your rigidbody is set to non-kinematic, and moving it via Rigidbody.velocity
.
Something similar to:
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0,
Input.GetAxis("Vertical"));
Vector3 moveDirection = m_Input;
moveDirection = transform.TransformDirection(moveDirection);
rb.velocity = (moveDirection * moveSpeed);
This should move your character according to physics and allow for the correct interactions with colliders.
Also, you should be aware if you ever do want to move a rigidbody like that, you should be sure to do so in FixedUpdate
and scale movement by Time.FixedDeltaTime
.
CodePudding user response:
now the jump is broken this is the full script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FPSMovement : MonoBehaviour
{
public Rigidbody rb;
public GameObject cam;
Vector2 rotation = Vector2.zero;
public float sensitivity = 10f;
public string xAxis = "Mouse X";
public string yAxis = "Mouse Y";
public float OmoveSpeed;
public float SprintSpeed;
public float moveSpeed;
public float jumpVar;
public bool Grounded = false;
public Vector3 slideScale;
public Vector3 normalScale;
public Vector3 dir;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
moveSpeed = OmoveSpeed;
slideScale = new Vector3(1, 0.5f, 1);
normalScale = new Vector3(1, 1, 1);
}
// Update is called once per frame
void FixedUpdate()
{
dir = rb.velocity;
// Should be cross platform movement
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
Vector3 moveDirection = m_Input;
moveDirection = transform.TransformDirection(moveDirection);
rb.velocity = (moveDirection * moveSpeed);
// Sprinting
if (Input.GetKey(KeyCode.LeftControl))
{
moveSpeed = SprintSpeed;
}
else
{
moveSpeed = OmoveSpeed;
}
// Jumping
if (Input.GetKey(KeyCode.Space))
{
if (Grounded)
{
rb.velocity = new Vector3(0, jumpVar, 0);
Grounded = false;
}
}
// TO-DO: Sliding
// Camera Rotation
rotation.x = Input.GetAxis(xAxis) * sensitivity;
rotation.y = Input.GetAxis(yAxis) * sensitivity;
rotation.y = Mathf.Clamp(rotation.y, -90, 90);
var xQuat = Quaternion.AngleAxis(rotation.x, Vector3.up);
var yQuat = Quaternion.AngleAxis(rotation.y, Vector3.left);
transform.localRotation = xQuat;
cam.transform.localRotation = yQuat;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "Ground")
{
Grounded = true;
}
}
private void OnCollisionExit(Collision collision)
{
Grounded = false;
}
}