I have code when I press arrow keys my capsule transform instantly turns to desired direction and then moves in that direction.
All that works good but when I’m in tight space between two skinny walls and I press key to turn it will sick through that wall and if I keep holding the key down it will eventually wobble through the wall and to the other side.
What I’m trying to achieve is to have the capsule be only able to turn and move in open direction - kind of like submarine in narrow space.(if it makes any sense)
I have Colliers on both of them - tried Rigid bodies and changing collision detection but nothing seems to work.
Here is part of my code.
if (Input.GetKey ("down"))
{
transform.eulerAngles = Vector3(0, 0, 90);
transform.Translate(Vector3.right * moveSpeed);
}
Thank you for any suggestions.
In my experience the best way to deal with this kind of thing is to use Physics.RayCast out the front of your gameObject (assuming the object is always facing the direction it is moving).
You will also need a RayCastHit variable to determine what your raycast hit if anything. You also may need to ignore certain colliders with a layerMask so that your ray only hits the objects you want to test for.
Example:
Ray rayForward = new Ray (playerTransform.position, playerTransform.forward);
RaycastHit rayHitForward;
GameObject rayHitForwardObject;
string rayHitString;
void Update()
{
//1.75 is the distance you want to stop moving if u hit wall
if (Physics.Raycast(rayForward, out rayHitForward, 1.75f))
{
rayHitForwardObject = rayHitForward.collider.gameObject;
rayHitString = rayHitObject.name;
}
if (rayHitString.name == "Wall")
{
//disable your forward movement
}
}
I tried raycasting in the direction that i move. It works fairly OK… But If the ray misses, then part of our character gets into teh cube… For that i had to use 5 raycasts … From teh 4 corners of my bounding box and the centre, and if even one of them hits, then don’t move. But this doesn’t work while rotating… It just slices into teh cube. After a lot of trial and error, I just found the method that works to my satisfaction… Ghost object
I instantiate a cube of teh same sie of my mesh bounds, and make it invisible. So, whenever i want to move, or turn, or fall, I first move teh ghost object, and check if it collides with anything, If not, then proceed with teh rotation…
I make similar calls for Moving and falling (in different contexts)
public bool CharCtrlExtRotColliding(Quaternion rot)
{
bool retval = false;
Quaternion oldRot = ghostChar.transform.rotation;
var hitColliders = Physics.OverlapSphere(ghostChar.GetComponent<MeshRenderer>().transform.position, _extents.z + _extents.x, ~(1 << LayerMask.NameToLayer("Ignore Raycast")));
for (var i = 0; i < hitColliders.Length; i++)
{
if (hitColliders*.collider.gameObject.tag == "Floor") continue; //ToDo: Put Floor in layer to ignore raycast*
ghostChar.transform.rotation = rot;
if (ghostChar.GetComponent().bounds.Intersects(hitColliders*.bounds))*
retval = true;
}
ghostChar.transform.rotation = oldRot;
return retval;
}