TransWikia.com

Unity 2017.3.of3 Raycast2D randomly misses objects

Game Development Asked by hesitatetowonder on January 15, 2021

2d up down platformer. Character has 2 Rays(one left one right) going down, when either Ray’s hit distance hits between -1 and 1 it should call a function which will change character direction from down to up. Works 1, 2, 3, 4, sometimes 6, sometimes into the teens times then character goes through the obstacle got placing character over an obstacle and hitting play with no changes gave a different amount of time before falling through the obstacle. I have tried changing the Time.time in fixedUpdate, placed movement in last update, varying degrees of success, I will post the current version of code, but it has gone through several revisions any ideas accepted. thanks

[RequireComponent (typeof (BoxCollider2D))]
public class YowiController : MonoBehaviour {

  BoxCollider2D yowiCollider;
  Vector2 rayDir, leftRay, rightRay, rayOrigin;

  public AudioSource jumpSound;

  bool jump;
  bool bounce;

  public float upTime;
  float looseTime;

  float bounceCount = 0;
  float gravity = 3f;
  float bounceHeight = 5f;
  float movementSpeed = 2f;
  float bounceTime = .03f;

  void Start () {
    yowiCollider = GetComponent<BoxCollider2D> ();
    rayDir = new Vector2 (0, -1);
    jump = false;
    bounce = false;
  }

  void Update () {
  }

  private void LateUpdate () {
    movement ();
  }

  void movement () {
    drawRays ();
    if (Input.GetKey (KeyCode.RightArrow)) {
      transform.Translate (Vector2.right * Time.deltaTime * movementSpeed);
    }
    if (Input.GetKey (KeyCode.LeftArrow)) {
      transform.Translate (Vector2.left * Time.deltaTime * movementSpeed);
    }
    if (!bounce) {
      transform.Translate (Vector2.down * Time.deltaTime * gravity);
      gravity += .02f;
    } else {
      Bounce ();
    }
  }

  void Bounce () {
    transform.Translate (Vector2.up * Time.deltaTime * bounceHeight);
    looseTime = bounceTime / 2;
    if (upTime < looseTime) {
      bounceHeight += .01f;
      looseTime--;
    } else {
      bounceHeight -= .01f;
    }
  }


  void drawRays () {
    Bounds bounds = yowiCollider.bounds;
    leftRay = new Vector2 (bounds.min.x, bounds.min.y);
    rightRay = new Vector2 (bounds.max.x, bounds.min.y);
    RaycastHit2D leftHit = Physics2D.Raycast (leftRay, rayDir * -1, .05f, 1 << 9);
    RaycastHit2D rightHit = Physics2D.Raycast (rightRay, rayDir * -1, .05f, 1 << 9);
    if (leftHit || rightHit) {
      RayHit (leftHit, rightHit);
    }
  }

  void RayHit (RaycastHit2D leftHit, RaycastHit2D rightHit) {
    if ((leftHit.distance < 1.1f) && (leftHit.distance > -1.1f)) {
      bounce = true;
      StartCoroutine (Bouncing ());
    } else if (rightHit.distance < 1.1f && rightHit.distance > -1.1f) {
      bounce = true;
      StartCoroutine (Bouncing ());
    } else {
      print ("No Joy");
    }
  }

  IEnumerator Bouncing () {
    yield return new WaitForSeconds (bounceTime);
    bounce = false;
  }
}

One Answer

At one point I tried switching the rays to the sprite(didn't work well) instead of the collider, so I move the setting the rays origins to start, this had the consequence of the rays not moving at all from their origin. Moved the origin to update and added a second set of rays in a separate function as a "backup". This seemed to do the trick, I commented out the second set of rays function and tested for 30 minutes with no misses, this is the updated code.

[RequireComponent (typeof (BoxCollider2D))]

public class YowiTest : MonoBehaviour {

BoxCollider2D yowiCollider;
RaycastHit2D firstLeftHit, firstRightHit;
RaycastHit2D secondLeftHit, secondRightHit;

Vector2 firstLeftRay, firstRightRay;
Vector2 secondLeftRay, secondRightRay;
Vector2 rayOrigin, velocity, rayDown;

Bounds bounds;

float midPoints;
float gravity = -.06f;
float movementSpeed = .01f;
float jump = .05f;

void Start () {
    yowiCollider = GetComponent<BoxCollider2D> ();
    rayDown = new Vector2 (0, -1);
    midPoints = (bounds.max.x - bounds.min.x) / 4;
}

void Update () {
    bounds = yowiCollider.bounds;
    movement ();
    drawRaysOne ();
    //drawRaysTwo ();
}

void movement () {
    Vector2 input = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical"));
    velocity.x = input.x * movementSpeed;
    velocity.y += gravity * Time.deltaTime;
    transform.Translate (velocity);
}

void drawRaysOne () {
    firstLeftRay = new Vector2 (bounds.min.x, bounds.min.y);
    firstRightRay = new Vector2 (bounds.max.x, bounds.min.y);
    firstLeftHit = Physics2D.Raycast (firstLeftRay, rayDown, .1f, 1 << 9);
    firstRightHit = Physics2D.Raycast (firstRightRay, rayDown, .1f, 1 << 9);
    Debug.DrawRay (firstRightRay, rayDown, Color.white);
    Debug.DrawRay (firstLeftRay, rayDown, Color.white);
    if (firstRightHit || firstLeftHit) {
        print ("First ray hit");
        velocity.y = jump;
    }
}

void drawRaysTwo () {
    secondLeftRay = new Vector2 (bounds.min.x + midPoints, bounds.min.y);
    secondRightRay = new Vector2 (bounds.max.x - midPoints, bounds.min.y);
    secondLeftHit = Physics2D.Raycast (secondLeftRay, rayDown, .1f, 1 << 9);
    secondRightHit = Physics2D.Raycast (secondRightRay, rayDown, .1f, 1 << 9);
    Debug.DrawRay (secondLeftRay, rayDown, Color.blue);
    Debug.DrawRay (secondRightRay, rayDown, Color.blue);
    if (secondRightHit || secondLeftHit) {
        print ("Second ray hit");
        velocity.y = jump;
    }
}

}

Answered by hesitatetowonder on January 15, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP