Hello, I am having difficulty creating an open world parkour style game which involves the player running at high speeds. The problem is that the player can very easily go through the walls simply by running into them (even when going at relatively “low” speeds. I am using walls that I made in blender and am using a mesh collider on them. The player is controlled by a rigidbody and this script.
using UnityEngine;
using System.Collections;
public class Movement : MonoBehaviour
{
public float XSensitivity = 2;
public float xRot;
public float movespeed;
private Rigidbody selfridge;
public void Start()
{
selfridge = GetComponent<Rigidbody>();
}
public void Update()
{
xRot = Input.GetAxis("Horizontal");
xRot = xRot / XSensitivity;
transform.Rotate(0, xRot, 0);
//Handles Left/Right Mouselook also rotates player
if (Input.GetButton("Forwards"))
{
selfridge.AddForce(transform.forward * movespeed);
}
if (Input.GetButton("Backwards"))
{
selfridge.AddForce(-transform.forward * movespeed);
}
}
}
Any suggestions on how to fix this problem would be greatly appreciated.
Thanks
Also, adding a Rigidbody component that isn’t Kinematic is you entering a contract telling Unity that you want the Rigidbody component to drive the Transform component. Unfortunately, you’re then modifying the Transform component yourself (transform.Rotate). You should stop doing that and drive the Rigidbody itself as you are when you use (selffridge.AddForce).
BY modifying the Transform you can cause overlaps of other colliders which the physics system is unable to stop; it can only solve them by continually trying to move it out of the overlap you caused. Often this is reported as ‘glitching’, ‘twitching’ or ‘jiggling’.
Rotate by adding torque, setting angular velocity or by using MoveRotation.
I tried this, but it did not work :(. Do you think that maybe my mouse look script is getting in the way?
using UnityEngine;
using System.Collections;
public class MouseLook : MonoBehaviour
{
public float YSensitivity = 2;
public float yRot;
public void Init()
{
}
public void Update()
{
yRot = Input.GetAxis("Vertical");
yRot = -yRot / YSensitivity;
transform.Rotate(yRot, 0, 0);
}
}
This script is attached to the Main Camera gameobject which is a child of the capsule object, which the previous script is attatched to. The camera, however, does not have a rigidbody component. BTW, the reason I have used moveRotate as opposed to addTorque or setting angular velocity is because I have frozen rotation on the Y asxis on the capsule object as otherwise, on the few occasions that it does collide with the walls, the player spins out of control.
Once again, any help would be gratly appreciated.
NeonEviscerator.
It’s hard for me to answer that. What I said before should cover your investigation. If you’re moving dynamic bodies by modifying the Transform then you are doing it wrong and causing overlaps and/or completely tunnelling. That can be position, rotation or scales changes.
You can also set the Rigidbody2D.collisionDetectionMode to one of the continuous detection modes however that won’t help if you are explicitly repositioning, rotating or scaling it via the Transform.
Related question, I hope I am not imposing. I just stared Unity and did the roll a ball tutorial. After finishing it, I decided to try adding a bounce-off effect and made a few changes to the scoring etc.
But, I have a problem: If I accelerate the ball reasonably quickly, it just flies right through the wall! However, the script works perfectly at slower speeds.
This code is from my player (ball) script. I can summarize the problem, as I have tried to debug it and tested the conditions where the ball falls off the map. Although this trigger is always called, sometimes the value of the normal vector (BounceNormal) appears as 0. I am not sure if it is because the position of the ball (RB.position) is registering as being the same as the ClosestPointOnBounds (RB.position) or something else.
I am under the impression that the surface of the sphere, not the center, should be triggering the event.
I believe OnTriggerEnter() is called during Update() while OnCollisionEnter() calls are related to FixedUpdate(). I would try changing the trigger to a collider.
Instead of the collider, you will get a Collision object when OnCollisionEnter() is called - this way, you can get the surface normal from the Collision object directly; and you can set the Rigidbodies collision detection mode to Continuous Dynamic or Dynamic which should give you the OnCollisionEnter() callback right before the object would hit the wall.
Note that this isn’t correct. All physics callbacks happen at the same time which is when the simulation step has finished. It’s part of the the simulation itself which is why you’ll get them when you manually step the simulation.