- Home /
player enters in the gameObjects and get pushed
I'm having some problems with my game:
1st- The player slightly enters inside others objects: https://youtu.be/yLlbnRivpME
2nd- When the player pushes a box towards a wall and stop pushing, he receives an opposite force that only stops when the player hits another object. (in the video you can see me trying to go forwards but always getting pushed away.) https://youtu.be/jOuKTFYy3Gs
3rd- When the players is pulling a box and touches a wall, the box receives an opposite force. https://youtu.be/p6BtOvL-eTI
Player controller script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerController : MonoBehaviour
{
Rigidbody rb;
public GameObject player;
private GameObject box;
public float speed = 5f;
public float impulseY = 5f;
public float x, y, z;
public bool isPushing = false;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode.D))
{
if (isPushing == false)
{
player.transform.rotation = Quaternion.Euler(0, 0, 0);
transform.Translate(Vector3.right * speed * Time.deltaTime);
x = 1;
}
else
{
if (player.transform.rotation == Quaternion.Euler(0, 0, 0))
{
transform.Translate(Vector3.right * speed * Time.deltaTime);
}
else
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
}
}
if(Input.GetKey(KeyCode.A))
{
if(isPushing == false)
{
player.transform.rotation = Quaternion.Euler(0, 180, 0);
transform.Translate(Vector3.right * speed * Time.deltaTime);
x = -1;
}
else
{
if(player.transform.rotation == Quaternion.Euler(0, 180, 0))
{
transform.Translate(Vector3.right * speed * Time.deltaTime);
}
else
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
}
}
}
void Update()
{
//groundcheck
Debug.DrawRay(player.transform.position + new Vector3(-0.2f, 0, 0), new Vector3(0, -1, 0), Color.red);
Debug.DrawRay(player.transform.position, new Vector3(0, -1, 0), Color.red);
Debug.DrawRay(player.transform.position + new Vector3(+0.2f, 0, 0), new Vector3(0, -1, 0), Color.red);
//pushableCheck
Debug.DrawRay(player.transform.position, new Vector3(x, y, z), Color.red);
if (Input.GetKeyDown("space") && GroundCheck() && isPushing == false)
{
rb.AddForce(new Vector3(0, impulseY, 0), ForceMode.Impulse);
}
if (Input.GetKeyDown(KeyCode.LeftShift) && PushableObject() && GroundCheck())
{
box.GetComponent<Rigidbody>().isKinematic = false;
box.gameObject.transform.parent = player.transform;
isPushing = true;
}
if ((Input.GetKeyUp(KeyCode.LeftShift) && isPushing) || (isPushing && !PushableObject()))
{
if (!BoxGroundCheck(box))
{
box.gameObject.transform.parent = null;
StartCoroutine("KeepNotKinematic");
}
else
{
box.GetComponent<Rigidbody>().isKinematic = true;
box.gameObject.transform.parent = null;
}
isPushing = false;
}
}
bool GroundCheck()
{
RaycastHit hit;
float distance = 0.5f;
Vector3 dir = new Vector3(0, -1);
bool isGrounded;
if(Physics.Raycast(player.transform.position, dir, out hit, distance) || Physics.Raycast(player.transform.position + new Vector3(-0.2f, 0, 0), dir, out hit, distance) || Physics.Raycast(player.transform.position + new Vector3(+0.2f, 0, 0), dir, out hit, distance))
{
isGrounded = true;
}
else
{
isGrounded = false;
}
return isGrounded;
}
bool BoxGroundCheck(GameObject bx)
{
RaycastHit hit;
float distance = 0.5f;
Vector3 dir = new Vector3(0, -1);
bool isGrounded;
if (Physics.Raycast(bx.transform.position, dir, out hit, distance) || Physics.Raycast(bx.transform.position + new Vector3(-0.2f, 0, 0), dir, out hit, distance) || Physics.Raycast(bx.transform.position + new Vector3(+0.2f, 0, 0), dir, out hit, distance))
{
isGrounded = true;
}
else
{
isGrounded = false;
}
return isGrounded;
}
bool PushableObject()
{
RaycastHit hit;
float distance = 1f;
bool isPushable;
if (Physics.Raycast(player.transform.position, new Vector3(x, y, z), out hit, distance))
{
if (hit.collider.gameObject.tag == "Box")
{
isPushable = true;
box = hit.collider.gameObject;
}
else
{
isPushable = false;
}
}
else
{
isPushable = false;
}
return isPushable;
}
IEnumerator KeepNotKinematic()
{
while(!BoxGroundCheck(box))
{
box.GetComponent<Rigidbody>().isKinematic = false;
BoxGroundCheck(box);
yield return null;
}
}
}
Every gameObject has attached this:
Answer by unity_ek98vnTRplGj8Q · Oct 07, 2020 at 09:34 PM
1st - To fix your player moving inside objects use Rigidbody.Move instead of transform.translate. When you use Transfrom.Translate, you are fighting against the physics system, because transform.translate will move you inside of an object, leaving it up to the physics system to try to push you out of the object. Using Rigidbody.Move will check for collisions as its moving you, so it never moves you inside of another object.
This may be enough to fix your other two issues. These are caused by the physics system pushing you out of the object that you are inside of, therefore applying force to you and sending you or the box sliding away from the wall. If this is still occurring you can always try bumping up the friction settings on your physics materials or even adding some linear drag to the rigidbodies.
I tried to use rigidbody.$$anonymous$$ovePosition, but it didn't work. Actually, it kept the same as translate, and the box needs to collide with the player to get pushed.