LineRendered / Raycast not matching over distance

I have two bits of code that should be doing the same thing but are very much not doing the same thing.

lr.SetPosition(0, transform.position);
lr.SetPosition(1, transform.up.normalized * 999f);

and

RaycastHit2D[] hits = Physics2D.CircleCastAll(transform.position, laserFireWidth, transform.up, 999f, ~(1 << LayerMask.NameToLayer("Ship")));

As I get close to 100 units away from the source of the linerenderer, it always seems to be to the left of my player. Significantly so, too. See attached picture.


However, the ray will hit me and do damage. So clearly the ray is working fine, as it should be looking at the player. The line should be doing the same thing as the ray, but it’s not. It’s off a little.

Why?

Edit: Full source code for the controller below:

    public WormHead player;
    public float speed = 3f;
    public float turnSpeed = 5f;

    float angle = 0f;
    Vector2 targetDirection = Vector2.zero;

    public float timeBetweenShots = 10f;
    public float timeBetweenChargeAndShoot = 0.5f;
    float timeOfLastShot;

    Rigidbody2D rb;
    LineRenderer lr;
    public Object explosionPrefab;
    public float laserFireWidth = 0.42f;
    public float laserChargeWidth = 0.1f;
    public float currentWidth = 0f;

    public AudioSource chargeSound;
    public AudioSource shootSound;

    public RectTransform warner;

    SpriteRenderer sr;

    // Use this for initialization
    void Start() {
        sr = GetComponent<SpriteRenderer>();
        rb = GetComponent<Rigidbody2D>();
        timeOfLastShot = Time.time;
        lr = GetComponent<LineRenderer>();
        lr.widthMultiplier = 0f;
        StartCoroutine("TrackPlayer");
        warner.SetParent(GameObject.FindGameObjectWithTag("Canvas").transform);
    }

    // Update is called once per frame
    void Update () {
        lr.SetPosition(0, transform.position); ////////////////////////////////////////THIS AREA////////////////
        lr.SetPosition(1, transform.up * 999f); ////////////////////////////////////////THIS AREA////////////////
        if(sr.isVisible) {
            warner.gameObject.SetActive(false);
        } else {
            warner.gameObject.SetActive(true);
        }
    }

    IEnumerator TrackPlayer() {
        while(Time.time < timeOfLastShot + (timeBetweenShots - timeBetweenChargeAndShoot)) {
            targetDirection = (transform.position - player.transform.position).normalized;
            angle = Mathf.Atan2(targetDirection.y, targetDirection.x) * Mathf.Rad2Deg;
            angle += 90f;
            transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.AngleAxis(angle, Vector3.forward), turnSpeed * Time.deltaTime);
            //transform.Rotate(0f, 0f, 90f);

            lr.widthMultiplier = laserChargeWidth;

            yield return null;
        }
        StartCoroutine("ChargeShotAndFire");
    }

    IEnumerator ChargeShotAndFire() {
        chargeSound.Play();
        while(Time.time < timeOfLastShot + timeBetweenShots) {
            lr.widthMultiplier = 0f;
            yield return null;
        }
        timeOfLastShot = Time.time;
        shootSound.Play(); ////////////////////////////////////////THIS AREA////////////////
        RaycastHit2D[] hits = Physics2D.CircleCastAll(transform.position, laserFireWidth, transform.up, 999f, ~(1 << LayerMask.NameToLayer("Ship")));
        foreach(RaycastHit2D hit in hits) {
            hit.transform.SendMessage("TakeDamage", SendMessageOptions.DontRequireReceiver);
        }
        StartCoroutine("Cooldown");
    }

    IEnumerator Cooldown() {
        while(Time.time < timeOfLastShot + 2f) {
            lr.widthMultiplier = Mathf.Lerp(laserFireWidth, 0f, (Time.time - timeOfLastShot) * 2f);
            yield return null;
        }
        StartCoroutine("TrackPlayer");
    }

    public void SetPlayer(WormHead newPlayer) {
        player = newPlayer;
    }

    private void FixedUpdate() {
        rb.velocity = transform.up * speed;
    }

    private void OnDestroy() {
        if(!isQuitting)
            warner.SendMessage("Die", SendMessageOptions.DontRequireReceiver);
    }

    bool isQuitting = false;
    private void OnApplicationQuit() {
        isQuitting = true;
    }

    public void TakeDamage() {
        warner.SendMessage("Die", SendMessageOptions.DontRequireReceiver);
        Instantiate(explosionPrefab, transform.position, transform.rotation);
        List<SpriteSlicer2DSliceInfo> slices = new List<SpriteSlicer2DSliceInfo>();
        SpriteSlicer2D.ExplodeSprite(gameObject, 5, 2f, false, ref slices);
        foreach(SpriteSlicer2DSliceInfo slice in slices) {
            foreach(GameObject obj in slice.ChildObjects) {
                if(!obj.GetComponent<SplitOnDamage>())
                    obj.AddComponent<SplitOnDamage>();
            }
        }
    }

Edit: As this code was used for a game jam game, we’ve gone ahead and submitted the game with this bug still in it. You can witness this bug yourself here: EAT by Unibear Studio

I would absolutely love to fix this. Can anyone help?

I have it checked but it is still having the problem.

–

1 Answer

1

My guess its because its a CircleCast, and the circle is hitting the player. I don’t know what your width is set to, so I could be wrong. Good luck in the Jam, I entered the compo, barely finished in time.

Hey Maybe you can help me with something. My pictures wont show up on my Game Page.

https://ldjam.com/events/ludum-dare/38/$18119

Refer to the second video here: https://ldjam.com/news It should get you on your way. I think you have to upload them using the built in uploader.

–

Is your player a child of something? Maybe its targeting its parent, which doesn't have the same position as the player? And thank you.

–