Vector2 Reflect works only in some cases
Hi all,
I am trying to add a feature in my 2D top-down game where when the player hits a wall while dashing to bounce off from it in a reflective manner:
I am using rigidbody2D and boxcollider2d for the player and for the wall - tilemapcollider2d, rigidbody2d compositecollider2d.
I've implemented a way to do it, but it only works in some cases:
*the right wall, when I am coming from bottom and right
*the bottom wall, when I am coming from top and left, but only for part of the wall
I don't understand why it doesn't work 100%. It seems like it changes the reflection based on where the player is in the box. The code I have used is this (in fixed update):
public class PlayerMovement : MonoBehaviour
{
public float movementSpeed;
public Rigidbody2D rigidBody2D;
private Vector2 movementVector;
private Vector2 mousePosition;
public Camera cam;
//dashing properties
public bool isdashing = false;
private float dashTime;
private bool canDash = true;
public float dashCooldown;
public float movementSpeedDashMult;
public float dashingTime;
private bool hasHitWall=false;
private Collider2D playerColl;
private Collider2D wallColl;
private Vector2 movementVectorForDash;
void Start() {
playerColl = GetComponent<BoxCollider2D>();
wallColl = GameObject.Find("Grid/Walls").GetComponent<CompositeCollider2D>();
}
void Update() {
movementVector.x = Input.GetAxisRaw("Horizontal");
movementVector.y = Input.GetAxisRaw("Vertical");
mousePosition = cam.ScreenToWorldPoint(Input.mousePosition);
if(Input.GetKeyDown(KeyCode.Space)){
StartCoroutine(Dash());
}
}
void FixedUpdate() {
if(isdashing) {
dashTime -= Time.deltaTime;
if(dashTime >= 0) {
if(playerColl.IsTouching(wallColl)) {
RaycastHit2D[] hitInfo = Physics2D.RaycastAll(transform.position,movementVector.normalized,1f);
for(int i = 0;i<hitInfo.Length;i++) {
if(hitInfo[i].collider.name == "Walls") {
movementVectorForDash = Vector2.Reflect(movementVector.normalized,hitInfo[i].point);
break;
}
}
hasHitWall=true;
}
if(hasHitWall) rigidBody2D.MovePosition(rigidBody2D.position + movementVectorForDash.normalized * movementSpeed * movementSpeedDashMult * Time.fixedDeltaTime);
else rigidBody2D.MovePosition(rigidBody2D.position + movementVector.normalized * movementSpeed * movementSpeedDashMult * Time.fixedDeltaTime);
}
else {
isdashing=false;
hasHitWall=false;
GetComponent<TrailRenderer>().emitting=false;
}
}
else {
rigidBody2D.MovePosition(rigidBody2D.position + movementVector.normalized * movementSpeed * Time.fixedDeltaTime);
}
Vector2 lookingDirection = mousePosition - rigidBody2D.position;
float angle = Mathf.Atan2(lookingDirection.y,lookingDirection.x) * Mathf.Rad2Deg-90f;
rigidBody2D.rotation = angle;
}
IEnumerator Dash() {
if(canDash){
GetComponent<TrailRenderer>().emitting=true;
FindObjectOfType<AudioManager>().playSound("dash");
//dashEffect.SetActive(true);
//cam.GetComponent<Animator>().SetTrigger("shakeIt");
dashTime=dashingTime;
isdashing = true;
canDash=false;
//yield return new WaitForSeconds(0.6f);
//dashEffect.SetActive(false);
//yield return new WaitForSeconds(dashCooldown-0.6f);
yield return new WaitForSeconds(dashCooldown);
canDash=true;
}
}
}
Answer by AntonTsirov · Aug 30, 2020 at 10:37 AM
Ahh, I think I got it. Instead of hitInfo[i].point i should use hitInfo[i].normal
Your answer
Follow this Question
Related Questions
Rotating weapon in top-down 2D 0 Answers
Vector2 Reflect 0 Answers
Render reflections on invisible object. 0 Answers
Dividing my game into rooms 1 Answer
Why is my player and camera only moving in the scene view? 0 Answers