VR teleportation: performance issues with LineCasts, looking for better solution

I’m trying to make a script to teleport in VR. The idea is simple, a parabola comes out of your hand when you press a certain button and when you release it you find yourself where the parabola collided with the terrain.
I came up with a fully functional script that does exactly what I want it to do, except when I press the button, the framerate drops for a second from 90 to 15 and goes back to 90 while I’m holding the button, what have I done wrong? Here’s my code :slight_smile: Thanks a lot in advance!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SinglePlayerTeleport : MonoBehaviour
{
    public float v0;
    float g = 9.81f;
    LineRenderer line;
    float alpha;
    public float step;
    public Transform hand;

    public int Resolution;
    public Transform colDet;
    public Transform Player;
    RaycastHit hit = new RaycastHit();
    public Color activeStart;
    public Color activeEnd;
   
    // Start is called before the first frame update
    void Start()
    {
        line = GetComponent<LineRenderer>();

    }

    // Update is called once per frame
    void Update()
    {
        if (OVRInput.Get(OVRInput.Button.SecondaryThumbstickUp))
        {
           
            line.enabled = true;
            transform.position = hand.position;
            transform.eulerAngles = new Vector3(0, hand.eulerAngles.y, 0);
            alpha = -hand.localEulerAngles.x;

            for (int i = 0; i < line.positionCount; i++)
            {
                Vector3 vec = new Vector3(0, CalcPar(line.GetPosition(i).z, v0, alpha * Mathf.Deg2Rad), i * step);
                line.SetPosition(i, vec);
            }




            //Debug.DrawLine(transform.TransformPoint(line.GetPosition(4)), transform.TransformPoint(line.GetPosition(5)),Color.red);

            for (int i = 0; i < line.positionCount - 1; i++)
            {
                Vector3 vec = transform.TransformPoint(line.GetPosition(i));
                Vector3 nvec = transform.TransformPoint(line.GetPosition(i + 1));

                if (Physics.Linecast(vec, nvec))
                {
                    Physics.Linecast(vec, nvec, out hit, 1 << 10);

                }



            }

            if (hit.point == Vector3.zero)
            {
                line.startColor = Color.red;
                line.endColor = Color.red;
                colDet.gameObject.SetActive(false);
            }
            else
            {
                colDet.gameObject.SetActive(true);
                line.startColor = activeStart;
                line.startColor = activeEnd;
                colDet.position = hit.point;

            }





        }
        else
        {
            line.enabled = false;

            if (OVRInput.GetUp(OVRInput.Button.SecondaryThumbstickUp) && hit.point != Vector3.zero)
            {
                var newpos = colDet.position;
                colDet.gameObject.SetActive(false);

                var adj = new Vector3(Player.localPosition.x, 0, Player.localPosition.z);

                transform.parent.position = newpos - adj;


            }

        }
    }





float CalcPar(float x, float v0, float alpha)
{
    var v0x = v0 * Mathf.Cos(alpha);
    var v0y = v0 * Mathf.Sin(alpha);
    return ((x / v0x) * (v0y - (g / 2) * (x / v0x)));
}
}

If you have a performance issue then use the profiler provided as this’ll obviously answer your question and tell you where your time is being spent. Your code looks like pretty brute force stuff so it’s not unexpected it has the potential to be slow.

There could be thousands of “positionCount” (only you know that) and you’re iterating them all doing work on each. Not only that but for some reason you’re performing a physics query on each, twice!! It should be clear that asking if a line-cast hits sometime requires it to perform the query and you’re doing that without any filtering of layer-mask too. Then if it returns true you do it again but this time get the results but then throw them away if you get multiple hits and only return the last hit you had. If you’re only interested in the first hit then start using only a single check and break out the loop when you detect it.

Beyond that, you’re probably just iterating too many points but you debugging and profiling can determine that. It’s certainly not going to be a performance issue with Linecasts.

Thanks for the answer.
The positions are actually like five or so, so I don’t think that’s the problem. I tried to check the line cast hit only once, but for some reason it does not work unless I check it twice.
Beyond that, the framerate only drops at the moment I press the button, and then it goes back to 90 fps while I’m holding it. It’s fairly obvious that it’s not a linecast performance problem, you’re right. I’ll check the profiler, thanks for now.

Something is wrong here if that’s the case.

1 Like