In platformers there is a player assist of sorts where if the player is right at the edge of a ceiling tile and jump, rather than hitting the ceiling and falling back down they will be moved out of the way and the jump will continue as if they didn't hit the ceiling. I figured the best way to accomplish this would be to use four raycasts on top of my character, two for the left side and two for right. One would be positioned at the very side of the character while another would be positioned near the middle. Then if the outer raycast returned true and the inner false, check another raycast to see how far I need to move the character out of the way so the character will not hit the ceiling.
This is what I came up with for an implementation. It runs in the fixed update loop. Also only the left side is demonstrated here, but the right side is the same with Vector3.left swapped for Vector3.right.
bool inner = Physics2D.Raycast(transform.position Vector3.left * innerCeilingAdjustmentOffset, Vector2.up, ceilingAdjustmentCheckDistance, groundLayer);
bool outer = Physics2D.Raycast(transform.position Vector3.left * outerCeilingAdjustmentOffset, Vector2.up, ceilingAdjustmentCheckDistance, groundLayer);
if (outer && !inner)
{
float distanceToMove =
Physics2D.Raycast(transform.position new Vector3(innerCeilingAdjustmentOffset, ceilingAdjustmentCheckDistance),
Vector2.left,
outerCeilingAdjustmentOffset,
groundLayer).distance;
transform.position = new Vector2(transform.position.x distanceToMove, transform.position.y);
}
My implementation does work in some cases which shows that I'm on the right track, but sometimes my character overshoots the mark and ends up further from the wall than I'd like and sometimes the distance check moves them too little resulting in the player hitting their head and falling back to the ground.
Here are examples of this behavior:
If anybody knows what I can do to fix this please let me know. Thank you!
CodePudding user response:
I'm not sure if the distance you're getting is correct 'cause I don't know the value of innerCeilingAdjustmentOffset and outerCeilingAdjustmentOffset variables. But have you tried to get the distance like they do in the official documentation? Like this:
if (outer && !inner)
{
RaycastHit2D hit =
Physics2D.Raycast(transform.position new Vector3(innerCeilingAdjustmentOffset, ceilingAdjustmentCheckDistance),
Vector2.left,
outerCeilingAdjustmentOffset,
groundLayer);
float distanceToMove = Mathf.Abs(hit.point.x - transform.position.x);
transform.position = new Vector2(transform.position.x distanceToMove, transform.position.y);
}
For reference: https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html