- Home /
Raycast doesnt detect object in front of rigidbody (player is stuck on wall)
I know this question has been asked quite frequently but any of the other threads havent quite seemed to settle this issue for me.
My player is controlled by physics and a rigidbody. When he collides with a wall mid jump and continuesly applies forward motion he will be stuck on the side of said wall.
I figured my solution to this problem would be to reset his velocity towards the wall but something is wrong with my raycast since my player never detects the wall.
!! Update: I did some debugging with the raycast and it seems to me that it is only cast when im standing still. Not really sure why.
If somebody could comment on my (newbie) code and help me find out what my error is that would be greatly appreciated.
My player has a mass of 1, he is scaled at 0.1 on all axis.
this is how he moves:
[RequireComponent(typeof(PlayerPhysics))]
public class PlayerController : MonoBehaviour {
private float walkSpeed = 4;
private float runSpeed = 8;
public float acceleration = 30;
private Vector3 jumpHeight;
private float distToGround;
private float targetSpeed;
private float currentSpeed;
private Vector3 amountToMove;
private PlayerPhysics playerPhysics;
//Playerstates
private bool isGliding;
// Use this for initialization
void Start () {
playerPhysics = GetComponent<PlayerPhysics>();
jumpHeight = new Vector3(0, 8, 0);
distToGround = collider.bounds.extents.y;
}
// Raycast under the player to detect if he is grounded
private bool IsGrounded()
{
return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
}
// Update is called once per frame
void Update () {
// Choppermode During jump
if (isGliding)
{
rigidbody.drag = 10;
}
else
{
rigidbody.drag = 0;
}
}
void FixedUpdate () {
// Player Movement
#region Player Movement
float speed = (Input.GetButton("Run"))?runSpeed:walkSpeed;
targetSpeed = Input.GetAxisRaw("Horizontal") * speed;
currentSpeed = IncrementTowards(currentSpeed, targetSpeed, acceleration);
amountToMove.x = currentSpeed;
playerPhysics.Move(amountToMove);
#endregion
// Player Jumping
if (!IsGrounded() && Input.GetButton("Glide"))
{
isGliding = true;
}
else
{
isGliding = false;
}
// Player Jump
if (IsGrounded() && Input.GetButtonDown("Jump"))
{
rigidbody.AddForce(jumpHeight, ForceMode.Impulse);
}
}
// Increase n towards target by speed
private float IncrementTowards(float n, float target, float a) {
if (n == target) {
return n;
}
else {
float dir = Mathf.Sign(target - n); // must n be increased or decreased to get closer to target
n += a * Time.deltaTime * dir;
return (dir == Mathf.Sign(target-n))? n: target; // if n has now passed target then return target, otherwise return n
}
}
}
this is how i cast my ray to detect objects in front of him:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(BoxCollider))]
public class PlayerPhysics : MonoBehaviour {
private BoxCollider collider;
private Vector3 s;
private Vector3 c;
private Vector3 originalSize;
private Vector3 originalCentre;
private float colliderScale;
private int collisionDivisionsY =10;
private float skin = .01f;
Ray ray;
RaycastHit hit;
// Use this for initialization
void Start () {
collider = GetComponent<BoxCollider>();
colliderScale = transform.localScale.x;
originalSize = collider.size;
originalCentre = collider.center;
SetCollider(originalSize,originalCentre);
}
public void Move(Vector3 amountToMove)
{
float deltaX = amountToMove.x;
Vector2 p = transform.position;
// Check collisions left and right
for (int i = 0; i<collisionDivisionsY; i ++)
{
float dir = Mathf.Sign(deltaX);
float x = p.x + c.x + s.x/2 * dir;
float y = p.y + c.y - s.y/2 + s.y/(collisionDivisionsY-1) * i;
ray = new Ray(new Vector2(x,y), new Vector2(dir,0));
Debug.DrawRay(ray.origin,ray.direction);
if (Physics.Raycast(ray,out hit,Mathf.Abs(deltaX) + skin))
{
// Get Distance between player and object on xaxis
float dst = Vector2.Distance (ray.origin, hit.point);
// Initiate players movement according to collision
if (dst > skin)
{
Debug.Log("should be walkin");
rigidbody.MovePosition(rigidbody.position + amountToMove * Time.deltaTime);
}
else
{
Debug.Log("should stop");
rigidbody.MovePosition(rigidbody.position + new Vector3(0, amountToMove.y, 0) * Time.deltaTime);
}
break;
}
}
}
// Set collider
public void SetCollider(Vector3 size, Vector3 centre) {
collider.size = size;
collider.center = centre;
s = size * colliderScale;
c = centre * colliderScale;
}
public void ResetCollider() {
SetCollider(originalSize,originalCentre);
}
}
Answer by mattssonon · Nov 07, 2013 at 02:24 PM
Are you sure you want to cast the ray in the direction Vector3.forward
? Try changing it to transform.forward
so it follows the object's forward direction.
Hi. Thank you for looking at my code. Unfortunately that was not the issue here. Ive updated the way my collision is detected to be more precise but im still having the same issue.
Your answer
Follow this Question
Related Questions
airplane collision detection problem 1 Answer
Surface with hole and Raycast - Which collider 1 Answer
Make Ray hit own collider 1 Answer
What is the best way to prevent a physics object from going through thin colliders? 2 Answers
Issue with adding force and lerping position? Possible unity bug? 0 Answers