I've been trying to get this working for about 2 hours now and as far as I'm concerned, it is working entirely, other than one thing.
The problem is that when my player is in the air, and they move right and collide with a wall, they simply collide. Simple. But when the player is moving left, and more commonly left and down or left straight after falling off a ledge and hitting a wall, they will almost always become grounded.
What is confusing me is that the left and right move scripts are exactly the same, with a few variables changed so that they are designed to go in opposite directions. My grounded check is also centered, so I don't imagine it could be happening to the left direction due to it being offset.
If anyone could help I would greatly appreciate it! Here is the script:
using UnityEngine;
using System.Collections;
public class Move : MonoBehaviour
{
public RaycastHit2D groundhit;
public float groundeddistance;
public bool grounded;
public float fallspeed;
public RaycastHit2D uphit;
public bool upblocked;
public float upspeed;
public float jumpcount;
public float fallspeedpubset;
public bool leftblock;
public bool rightblock;
public float sidespeed;
public RaycastHit2D lefthit;
public RaycastHit2D righthit;
public float leftreach;
public float rightreach;
public bool jumping;
public bool gravity;
public float groundedwidth;
public float upreach;
public float jumpcountmax;
public float repeatratejump;
public bool cantground;
public float leftclimbcount;
public float rightclimbcount;
public float leftclimbcountstoper;
public float rightclimbcountstoper;
// Update is called once per frame
void Update()
{
fallspeed = fallspeedpubset;
if (cantground == false)
{
groundhit = Physics2D.BoxCast(transform.position, new Vector2(transform.localScale.x - groundedwidth, transform.localScale.y), transform.eulerAngles.z, Vector2.down, groundeddistance);
if (Physics2D.BoxCast(transform.position, new Vector2(transform.localScale.x - groundedwidth, transform.localScale.y), transform.eulerAngles.z, Vector2.down, groundeddistance) && groundhit.transform.tag == "Terrain")
{
grounded = true;
}
else { grounded = false; }
}
if (grounded == false && gravity) { transform.position = new Vector2(transform.position.x, transform.position.y - fallspeed); } else { }
lefthit = Physics2D.BoxCast(new Vector2(transform.position.x - transform.localScale.x / 2, transform.position.y), new Vector2(0.01f, transform.localScale.y - 0.04f), transform.eulerAngles.z, Vector2.left, leftreach);
if (Physics2D.BoxCast(new Vector2(transform.position.x - transform.localScale.x / 2, transform.position.y), new Vector2(0.01f, transform.localScale.y - 0.04f), transform.eulerAngles.z, Vector2.left, leftreach) && lefthit.transform.tag == "Terrain")
{
leftblock = true;
}
else { leftblock = false; }
righthit = Physics2D.BoxCast(new Vector2(transform.position.x + transform.localScale.x / 2, transform.position.y), new Vector2(0.01f, transform.localScale.y - 0.04f), transform.eulerAngles.z, Vector2.right, rightreach);
if (Physics2D.BoxCast(new Vector2(transform.position.x + transform.localScale.x / 2, transform.position.y), new Vector2(0.01f, transform.localScale.y - 0.04f), transform.eulerAngles.z, Vector2.right, rightreach) && righthit.transform.tag == "Terrain")
{
rightblock = true;
}
else { rightblock = false; }
uphit = Physics2D.BoxCast(new Vector2(transform.position.x, (transform.position.y + transform.localScale.y / 2) + 0.01f), new Vector2(transform.localScale.x - groundedwidth, 0.01f), transform.eulerAngles.z, Vector2.up, upreach);
if (Physics2D.BoxCast(new Vector2(transform.position.x, (transform.position.y + transform.localScale.y / 2) + 0.01f), new Vector2(transform.localScale.x - groundedwidth, 0.01f), transform.eulerAngles.z, Vector2.up, upreach) && uphit.transform.tag == "Terrain")
{
upblocked = true;
}
else { upblocked = false; }
if (Input.GetKey("d") && rightblock == false)
{
transform.position = new Vector2(transform.position.x - sidespeed, transform.position.y);
}
else if (Input.GetKey("a") && leftblock == false)
{
transform.position = new Vector2(transform.position.x + sidespeed, transform.position.y);
}
//if(grounded && Input.GetButtonDown("Jump")) { grounded = false; cantground = true; jumping = true; }
if (grounded && Input.GetKeyDown("w") && upblocked == false) { InvokeRepeating("Jump", 0, repeatratejump); }
if (grounded) { rightclimbcount = 0; leftclimbcount = 0; }
//if (grounded == false && lefthit && Input.GetKey("a") && leftclimbcount <= leftclimbcountstoper && Input.GetKey("w") == false) { gravity = false; leftclimbcount = leftclimbcount + 1; upblocked = true; } else if(jumping == false) { gravity = true; }
//if (grounded == false && righthit && Input.GetKey("d") && rightclimbcount <= rightclimbcountstoper && Input.GetKey("w") == false) { gravity = false; rightclimbcount = rightclimbcount + 1; upblocked = true; } else if (jumping == false) { gravity = true; }
}
void Jump()
{
jumping = true;
gravity = false;
fallspeed = 0;
if (upblocked == false)
transform.position = new Vector2(transform.position.x, transform.position.y + upspeed);
jumpcount += 1;
if (jumpcount >= jumpcountmax) { CancelInvoke(); gravity = true; jumpcount = 0; jumping = false; }
}
}
RayCast2D
by performing aPhysics2D.BoxCast()
, before immediately performing the samePhysics2D.BoxCast()
to check the resultingRayCast2D
for anif
statement? You literally just stored the value. Why don't you just check theRayCast2D
variable, instead of performing the samePhysics2D.BoxCast()
again? You do this quite a bit (as well as similar instances where you could benefit from storingnew Vector2
once instead of calling it twice), which would have some sort of impact on your overall performance. \$\endgroup\$