Question by
Bairne · Dec 06, 2017 at 02:53 PM ·
raycast2d-platformerslopesphysics 2d
Handling Slopes
Hi Folks,
I'm a pretty newbie developer who's been using tutorial to expand their knowledge of game design etc.
I've recently started working with a Super Meat Boy style character controller, which is awesome! My one issue with it though is that it can't handle slopes.
I've tried a variety of suggested fixes from this forum, but haven't had any luck, and i'm afraid my inexperience is presenting a road block here.
If anyone can suggest a way to get the controller to handle slopes, that would be amazing! Thanks for all your help.
Current Controller:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
//floats and bools
public float MaxSpeed = 10;
public float Acceleration = 35;
public float JumpSpeed = 8;
public float JumpDuration;
public bool EnableDoubleJump = true;
public bool wallHitDoubleJumpOverride = true;
public bool facingRight = false;
//internal checks
bool canDoubleJump = true;
float jmpDuration;
bool jumpKeyDown = false;
bool canVariableJump = false;
//refs
private Renderer render;
private Rigidbody2D rigid2d;
// Use this for initialization
void Start () {
render = GetComponent<Renderer> ();
rigid2d = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void Update () {
float horizontal = Input.GetAxis ("Horizontal");
if (horizontal < -0.1f) {
if (rigid2d.velocity.x > -this.MaxSpeed) {
FlipPlayer ();
rigid2d.AddForce (new Vector2 (-this.Acceleration, 0.0f));
} else {
rigid2d.velocity = new Vector2 (-this.MaxSpeed, rigid2d.velocity.y);
}
}
else if (horizontal > 0.1f) {
if (rigid2d.velocity.x < this.MaxSpeed) {
rigid2d.AddForce (new Vector2 (this.Acceleration, 0.0f));
} else {
rigid2d.velocity = new Vector2 (this.MaxSpeed, rigid2d.velocity.y);
}
}
bool Grounded = isGrounded ();
float vertical = Input.GetAxis ("Vertical");
if (Grounded) {
canDoubleJump = true;
}
if (vertical > 0.1f) {
if (!jumpKeyDown) { //1st jump frame
jumpKeyDown = true;
if (Grounded || (canDoubleJump && EnableDoubleJump) || wallHitDoubleJumpOverride) {
bool wallHit = false;
int wallHitDirection = 0;
bool leftWallHit = isWallOnLeft ();
bool rightWallHit = isWallOnRight ();
if (horizontal != 0) {
if (leftWallHit) {
wallHit = true;
wallHitDirection = 1;
} else if (rightWallHit) {
wallHit = true;
wallHitDirection = -1;
}
}
if (!wallHit) {
if (Grounded || (canDoubleJump && EnableDoubleJump)) {
rigid2d.velocity = new Vector2 (rigid2d.velocity.x, this.JumpSpeed);
jmpDuration = 0.0f;
canVariableJump = true;
}
} else {
rigid2d.velocity = new Vector2 (this.JumpSpeed * wallHitDirection, this.JumpSpeed);
jmpDuration = 0.0f;
canVariableJump = true;
}
if (!Grounded && !wallHit) {
canDoubleJump = false;
}
}
}//2nd Jump Frame
else if (canVariableJump) {
jmpDuration += Time.deltaTime;
if (jmpDuration < this.JumpDuration / 1000) {
rigid2d.velocity = new Vector2 (rigid2d.velocity.x, this.JumpSpeed);
}
}
} else {
jumpKeyDown = false;
canVariableJump = false;
}
if (horizontal < 0.0f && facingRight == false) {
FlipPlayer ();
} else if (horizontal > 0.0f && facingRight == true) {
FlipPlayer ();
}
}
//Detects Grounding
private bool isGrounded(){
float lengthToSearch = 0.1f;
float colliderThreshold = 0.001f;
Vector2 linestart = new Vector2 (this.transform.position.x, this.transform.position.y - this.render.bounds.extents.y - colliderThreshold);
Vector2 vectorToSearch = new Vector2 (this.transform.position.x, linestart.y - lengthToSearch);
RaycastHit2D hit = Physics2D.Linecast (linestart, vectorToSearch);
return hit;
}
//Detects Wall Hits
private bool isWallOnLeft(){
bool retVal = false;
float lengthToSearch = 0.1f;
float colliderThreshold = 0.01f;
Vector2 linestart = new Vector2 (this.transform.position.x - this.render.bounds.extents.x - colliderThreshold, this.transform.position.y);
Vector2 vectorToSearch = new Vector2 (linestart.x - lengthToSearch, this.transform.position.y);
RaycastHit2D hitLeft = Physics2D.Linecast (linestart, vectorToSearch);
retVal = hitLeft;
if (retVal) {
if (hitLeft.collider.GetComponent<NoSlideJump> ()) {
retVal = false;
}
}
return retVal;
}
private bool isWallOnRight(){
bool retVal = false;
float lengthToSearch = 0.1f;
float colliderThreshold = 0.01f;
Vector2 linestart = new Vector2 (this.transform.position.x + this.render.bounds.extents.x + colliderThreshold, this.transform.position.y);
Vector2 vectorToSearch = new Vector2 (linestart.x + lengthToSearch, this.transform.position.y);
RaycastHit2D hitRight = Physics2D.Linecast (linestart, vectorToSearch);
retVal = hitRight;
if (retVal) {
if (hitRight.collider.GetComponent<NoSlideJump> ()) {
retVal = false;
}
}
return retVal;
}
void FlipPlayer(){
facingRight = !facingRight;
Vector2 localScale = gameObject.transform.localScale;
localScale.x *= -1;
transform.localScale = localScale;
}
}
Comment