user11458208
user11458208

Reputation:

Setting limit of line renderer distance?

I am using a line renderer that has a free line that goes to long distances when a raycast is casted. However I want to limit the distance to lets say x,y,z = 5 no matter how long the line should be depending on the raycast. How do I use Mathf.Clamp() function in this script for my line renderer to limit a distance of 5. So that I can hide the line after it has crossed the distance limit by keeping the raycast activated? So that only 1/4th of the line is visible but it still collides with a collider?

private LineRenderer _lineRenderer;

    [Tooltip("Maximum range for aiming.")]
    public float Range = 100;

    /// <summary>
    /// Return the set of points that represent the aiming line.
    /// </summary>
    /// <param name="points"></param>

    public override void GetPoints(List<Vector3> points)
    {
        Ray aimRay;
        LocomotionTeleport.InputHandler.GetAimData(out aimRay);
        points.Add(aimRay.origin);
        points.Add(aimRay.origin + aimRay.direction * Range);
    }

private void UpdateAim(Data obj)
    {
        _lineRenderer.sharedMaterial.color = obj.TargetValid ? new Color32(107, 202, 23, 255) : new Color32(202, 61, 23, 255);

        var points = obj.Points;
        
        _lineRenderer.positionCount = points.Count;
        
        for (int i = 0; i < points.Count; i++)
        {
            _lineRenderer.SetPosition(i, points[i]); //Limit distance of line 
            float _Distance = Vector3.Distance(points[0],points[1]);
            Debug.Log(""+_Distance);
        }
    }

Upvotes: 1

Views: 1385

Answers (3)

Furkan Nebioğlu
Furkan Nebioğlu

Reputation: 74

I solved it


if (Input.GetMouseButton(0) && isLineStarted)
        {
            if (line.positionCount > MaxCapacity)
            {
                Vector3[] linePositions = new Vector3[line.positionCount];
                List<Vector3> newPos = new List<Vector3>();
                line.GetPositions(linePositions);
                newPos = linePositions.ToList();
                newPos.RemoveAt(0);
                linePositions = newPos.ToArray();
                line.SetPositions(linePositions);
            }
            
            Vector3 currentPos = GetWorldCoordinate(Input.mousePosition);
            float distance = Vector3.Distance(currentPos, line.GetPosition(line.positionCount - 1));
            if (distance > minimumVertexDistance)
            {
                UpdateLine();
            }
        }

Upvotes: 0

derHugo
derHugo

Reputation: 90659

As I understand you already know you get always exactly two points as feedback:

  • points[0] origin of the raycast
  • points[1] end/hitpoint of the ray.

In order to limit this to a certain distance simply do

public float maxDisplayLength = 5f;

public Color validColor = new Color32(107, 202, 23, 255);
public Color invalidColor = new Color32(202, 61, 23, 255);

// would be enough to do this only once
private void Start()
{
    _lineRenderer.positionCount = 2;
}

private void UpdateAim(Data obj)
{
    _lineRenderer.sharedMaterial.color = obj.TargetValid ?  validColor: invalidColor;

    var points = obj.Points;

    if(vector.magnitude > maxDisplayLength)
    {
        var direction = (points[1] - points[0]).normalized;

        // Fix the second/end point to a position in the same direction 
        // as originally but maxLength distance from origin
        points[1] = points[0] + direction * maxDisplayLength;
   }

    _lineRenderer.SetPositions(points);
}

As said SetPositions in one go is more efficient then assigning them one by one.


ACTUALLY

Now that you added the rest of the code it seems that the

public float Range = 100;

anyay does not change how the raycast works and is only used for the LineRenderer.

... so it should be enough to only set the Range to your target max length since the same calculation as I suggested is already done in

points.Add(aimRay.origin);
points.Add(aimRay.origin + aimRay.direction * Range);

Upvotes: 1

user11458208
user11458208

Reputation:

Since there are only two points for a line renderer (points[0] and points[1]), one does not need a loop to begin with. The user can use Mathf.Clamp() function after calculating the distance between the two points. The user derHugo's code is more structured. This is only an alternate answer.

    private void UpdateAimData(LocomotionTeleport.AimData obj)
    {
        _lineRenderer.sharedMaterial.color = obj.TargetValid ? new Color32(107, 202, 23, 255) : new Color32(202, 61, 23, 255);

        var points = obj.Points;
        //        Debug.Log("AimVisualLaser: count: " + points.Count);
        _lineRenderer.positionCount = points.Count;
        //_lineRenderer.SetVertexCount(points.Count);
        for (int i = 0; i < points.Count; i++) //Not required
        {
            _lineRenderer.SetPosition(i, points[i]);

            Vector3 dir = points[1] - points[0];
            float dist = Mathf.Clamp(Vector3.Distance(points[0], points[1]), 0, DistanceLimit_Float);
            points[1] = points[0] + (dir.normalized * dist);

            Debug.Log(""+dist);
        }
    }

Upvotes: 1

Related Questions