#LineRenderer lagging

1 messages · Page 1 of 1 (latest)

cursive anvil
#

I don't understand why, but my line completely breaks when in play mode, but feels good in scene view.
Code for lr:

_lr.SetPosition(0, transform.position);
_lr.SetPosition(1, _finalPos);
endPoint.position = _finalPos;
if (Physics.Raycast(transform.position, transform.forward, out var hit, Mathf.Infinity, layerMask:laserIgnoreMask))
{
    if (!hit.collider) return;
    if (hit.collider.CompareTag("Reflect"))
    {

    }
    _finalPos = hit.point;
}
else _finalPos = transform.forward * 1000;
past dew
#

In which update loop are you doing the racyast ? FixedUpdate ?

past dew
#

Do you have any physics or rigidbody involved ? Or do you have your cube and laser emitter parented to the camera ?

cursive anvil
#

Parented

past dew
#

You're probably updating your camera in LateUpdate, what happens here is you are updating the beam start and end position in the Update loop, but in LateUpdate the camera moves, the cube and the emitter too, so the beam is not connected to the emitter anymore

#

you can probably do your Raycast in LateUpdate

#

or you can set the LineRenderer to localspace, so the start position will be relative to the transform attached to it, but in this case you'll probably have the same issue with the end of the beam

cursive anvil
midnight rivet
#

Could you send a snippet of the code?
Maybe i can help.

rough blade
#

you can adjust the script execution order of the scripts, or you can explicitly run the camera update + line update steps

quasi cobalt
#

looks like there is easing or somekind of interpolation somewhere.
But yeah seeing the full code (not just some snippet) could help

cursive anvil
#

That was all the code in Update(). I made some changes so line could reflect, nothing extraordinary
Discord doesn't allow me to upload whole code because it's too long, without nitro

#
public class Laser : MonoBehaviour {
public Transform endPoint;
public LayerMask laserIgnoreMask;
public int maxReflections = 10;
public float maxDistance = 1000f;

private LineRenderer _lr;
private Vector3[] _positions;
private Vector3 _finalPos;
private int _currentPositions;

private void Start()
{
    _lr = GetComponent<LineRenderer>();
    _positions = new Vector3[maxReflections+1];
    endPoint = Instantiate(endPoint, transform.position, Quaternion.identity);
}

private void LateUpdate() // changed from Update()
{
    _lr.SetPosition(0, transform.position);
    CalculateLaserPath();
    UpdateLineRenderer();
    UpdateEndPoint();
}

private void CalculateLaserPath()
{
    _currentPositions = 1;
    var currentPosition = transform.position;
    var currentDirection = transform.forward;
    for (var i = 1; i < maxReflections; i++)
    {
        if (Physics.Raycast(currentPosition, currentDirection, out var hit, maxDistance, layerMask:laserIgnoreMask))
        {
            _positions[_currentPositions] = hit.point;
            _currentPositions++;
            if (hit.collider.CompareTag("Reflect"))
            {
                currentDirection = Vector3.Reflect(currentDirection, hit.normal);
                currentPosition = hit.point + currentDirection * 0.001f; //avoid self intersect
            }
            else break;
        }
        else
        {
            _positions[_currentPositions] = currentDirection * maxDistance;
            break;
        }
    }
}
private void UpdateLineRenderer()
{
    _lr.positionCount = _currentPositions;
    for (var i = 1; i < _currentPositions; i++)
        _lr.SetPosition(i, _positions[i]);
}
private void UpdateEndPoint()
{
    if (_currentPositions > 1)
    {
        endPoint.position = _positions[_currentPositions-1];
        return; 
    }
    endPoint.position = transform.forward * maxDistance;
}
}
cursive anvil
cursive anvil
#

Thanks ^^!

rough blade
#

These sorts of execution-order bugs can be very pernicious.

#

especially if you run into any kind of circular dependency

#

e.g. your character needs to look at an object, but that object is being posed on a spline that's moving around

#

Debug.DrawLine can be super helpful to visualize exactly where things were at specific points in the update loop

#

I wrote a class to let me draw gizmos, too

#
public class DebugDrawer : SingletonPrefab<DebugDrawer>
{
    private readonly List<Action> actionList = new();
    private int lastFrame = -1;

    private void OnDrawGizmos()
    {
        foreach (Action action in actionList) action.Invoke();
    }

    [Conditional("UNITY_EDITOR")]
    public void RequestAction(Action action)
    {
        if (Time.frameCount != lastFrame)
        {
            actionList.Clear();
            lastFrame = Time.frameCount;
        }

        actionList.Add(action);
    }
}
#

(SingletonPrefab instantiates a prefab when I ask for an instance of the class)

#

the Conditional attribute is cool -- it causes any RequestAction calls to be deleted from the built game

rough blade