Move Player along normal of floor?
I wanted my player to be moved along the normal of my floor object. Something like this:
I don't want the movement to be straight all the time, as it is noticeable when going down slopes. I also want the player to jump perpendicular to the floor at all times. I also tried to implement a quick and dirty speed limiter to make sure it does not go too fast.
The code I have currently does the perpendicular jumping fine, but the left-right movement is a bit messed up. Also, I am currently controlling the player with the rigidbody component.
void Update()
{
if (active)
{
Vector2 velocity = Vector2.zero;
Vector2 sideVelocity = Vector2.zero;
Vector2 jumpVelocity = Vector2.zero;
Vector3 sub = new Vector3(0, 1, 0);
if (Input.GetKeyDown(KeyCode.W))
{
if (grounded)
{
Vector2 jumpVector = new Vector2(0, jump);
Vector2 normal = Vector2.zero;
RaycastHit2D hit = Physics2D.Raycast(transform.position-sub,-Vector2.up);
if (hit.collider != null)
{
Debug.Log( "name of raycast collider: "+ hit.collider.name);
Quaternion rot = hit.collider.transform.rotation;
normal = hit.normal;
normal.Normalize();
jumpVelocity = rot*jumpVector;
//velocity = jumpVelocity;
Debug.Log("velocity: " + rot * jumpVector);
}
}
else
{
jumpVelocity = Vector2.zero;
}
}
//Left Right Movement
if (Input.GetKey(KeyCode.A))
{
RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
if (hit.collider != null && grounded)
{
Debug.Log("name of raycast collider: " + hit.collider.name);
Quaternion rot = hit.collider.transform.rotation;
sideVelocity = rot*-speedVector;
}
else
{
sideVelocity = speedVector;
}
}
if (Input.GetKey(KeyCode.D))
{
RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
if (hit.collider != null && grounded)
{
Debug.Log("name of raycast collider: " + hit.collider.name);
Quaternion rot = hit.collider.transform.rotation;
sideVelocity = rot * speedVector;
}
else
{
sideVelocity = speedVector;
}
}
velocity = sideVelocity + rb.velocity;
if (velocity.x > maxXSpeed)
{
velocity.x = maxXSpeed;
}
if (velocity.x < -maxXSpeed)
{
velocity.x = -maxXSpeed;
}
if (velocity.y > maxYSpeed)
{
velocity.y = maxYSpeed;
}
if (velocity.y < -maxYSpeed)
{
velocity.y = -maxYSpeed;
}
rb.velocity = velocity;
}
}
thanks for the help!
Answer by noorsy · Sep 20, 2016 at 10:06 PM
I tweaked the code a bit, and the script works pretty well now. Keep in mind my game only has flat floor objects, so no curves, and I have not tested it on curved objects. My platform object is just a rectangle, which i duplicate and rotate for different game obstacles. Since i use quaternions for all of the calculations, the floor object must be rotated parallel to the surface the player object will be interacting with.
void Update()
{
if (active)
{
if (Input.GetKeyDown(KeyCode.W))
{
if (grounded)
{
RaycastHit2D hit = Physics2D.Raycast(transform.position-sub,-Vector2.up);
if (hit.collider != null)
{
Debug.Log( "name of raycast collider: "+ hit.collider.name);
Quaternion rot = hit.collider.transform.rotation;
jumpVelocity = rot*jumpVector;
Debug.Log("velocity: " + rot * jumpVector);
rb.velocity = rb.velocity + jumpVelocity;
}
}
else
{
jumpVelocity = Vector2.zero;
}
}
//Left Right Movement
if (Input.GetKey(KeyCode.D))
{
if (grounded)
{
Vector2 sideVector = new Vector2(0, speed);
RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
if (hit.collider != null)
{
Quaternion rot = hit.collider.transform.rotation;
rot = Quaternion.Euler(0, 0, 90) * rot;
sideVelocity = rot * -sideVector;
rb.velocity = rb.velocity + sideVelocity;
}
}
else
{
rb.velocity =new Vector2(rb.velocity.x+speed, rb.velocity.y);
}
}
if (Input.GetKey(KeyCode.A))
{
if (grounded)
{
Vector2 sideVector = new Vector2(0, speed);
RaycastHit2D hit = Physics2D.Raycast(transform.position - sub, -Vector2.up);
if (hit.collider != null)
{
Quaternion rot = hit.collider.transform.rotation;
rot = Quaternion.Euler(0, 0, 90) * rot;
sideVelocity = rot * -sideVector;
rb.velocity = rb.velocity + -sideVelocity;
}
}
else
{
rb.velocity = new Vector2(rb.velocity.x - speed, rb.velocity.y);
}
}
if (rb.velocity.x > 10)
{
rb.velocity = new Vector2(10, rb.velocity.y);
}
if (rb.velocity.x < -10)
{
rb.velocity = new Vector2(-10, rb.velocity.y);
}
}
}
//Check if Grounded
void OnCollisionEnter2D(Collision2D other)
{
string otherTag = other.gameObject.tag;
Debug.Log("collided");
if (other.gameObject.tag == "Floors")
{
Debug.Log("Hit floor");
grounded = true;
}
}
void OnCollisionStay2D(Collision2D other)
{
if (other.gameObject.tag == "Floors")
{
grounded = true;
}
}
void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.tag == "Floors")
{
Debug.Log("stopped Hit floor");
grounded = false;
}
}
Your answer
Follow this Question
Related Questions
I can't seem to rotate my character depending on what side he is running to (2D sidescroller) 0 Answers
[2D] How to stop 2 vectors from adding force on each other 0 Answers
Unity 2D Controller when active ignore another click 0 Answers
Issues with snake game in C# 2 Answers
How To Do Basic 2D Movement? 1 Answer