nmw01223
nmw01223

Reputation: 1723

Unity LineRenderer - unable to set positions

This links to my previous question about being unable to get a reference to a Unity LineRenderer. Got round that one temporarily, though still do not understand what the problem was. But now, having got the LineRenderer reference, cannot do anything with it.

The LineRenderer is being added programmatically and a reference obtained in Awake(), then later on demand, need to access it, add a load of points and display it. But I cannot - won't compile. The code is

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

    //////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////

    public class Test : MonoBehaviour
    {
        LineRenderer
                lineOfFlight;

        void Awake()
        {
            GameObject
                    lineObject = new GameObject("Line");

            lineOfFlight = lineObject.AddComponent<LineRenderer>();
        }

        void Start() { }

        void Update()
        {
            List<Vector3>
                    savedBuffer = new List<Vector3>();  //  added for test
            Vector3[]
                    positions = new Vector3[3000];
            int     index = 0;

            foreach (Vector3 m in savedBuffer)
                positions[index++] = new Vector3(index, index, index);

            lineOfFlight.SetPositions(positions);
        }

    }

It sets up OK in Awake().

The error is that lineOfFlight (type LineRenderer) has no method called SetPositions() - according to the Unity manual it does, I can find no method it does have that is any use for setting positions at all. All it has is the standard GameObject methods.

This is the Unity manual example (in Update()):

    LineRenderer lineRenderer = GetComponent<LineRenderer>();
    var points = new Vector3[lengthOfLineRenderer];
    var t = Time.time;
    for (int i = 0; i < lengthOfLineRenderer; i++)
    {
        points[i] = new Vector3(i * 0.5f, Mathf.Sin(i + t), 0.0f);
    }
    lineRenderer.SetPositions(points);

So what is different?

I am missing the point here - how is one supposed to access these components? I have found this problem before on other components - clearly I do not understand how to get at APIs in Unity.

The class derives from MonoBehaviour, and UnityEngine is included.

STOP PRESS:

Test file Test.cs created - just has the key bits in it - now shown above (replaced original example). Isn't going to do much (nothing in savedBuffer), but should compile? Comes up with exactly the same error on the line lineOfFlight.SetPositions(positions);.

I also tried GetComponent<LineRenderer>().SetPositions(positions); - exactly the same: "'LineRenderer' does not contain a definition for 'SetPositions' and no accessible extension method 'SetPositions' accepting a first argument of type 'LineRenderer' could be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]csharp(CS1061)".

Upvotes: 3

Views: 4843

Answers (3)

LeeRoyHero
LeeRoyHero

Reputation: 81

try to assign points count before setting positions

lineRenderer.positionCount = list.Count;
lineRenderer.SetPositions(list);

Upvotes: 1

Remy
Remy

Reputation: 5163

The code in your question works for me out of the box, so it must almost definitely be a conflict with another library or package that is using the same LineRenderer name.

Probably defining that you want to use the LineRenderer from the UnityEngine namespace will should fix your issue. (apart from getting rid of the other package, but you said you can't find it)

using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    UnityEngine.LineRenderer lineOfFlight;// <- Note the UnityEngine.Linerenderer
    void Awake()
    {
        GameObject lineObject = new GameObject("Line");

        lineOfFlight = lineObject.AddComponent<UnityEngine.LineRenderer>();// <- notice the UnityEngine.LineRenderer
    }

    // Update is called once per frame
    void Update()
    {
        List<Vector3> savedBuffer = new List<Vector3>();

        if (Input.GetKey(KeyCode.V))
        {
            if (true)
            {
                Vector3[] positions = new Vector3[30];
                int index = 0;

                foreach (Vector3 m in savedBuffer)
                    positions[index++] = new Vector3(index, index, index);

                lineOfFlight.SetPositions(positions);
            }
        }
    }
}

Normally an issue like this should be accompanied by the IDE throwing an error along the lines of

error CS0104: 'LineRenderer' is an ambiguous reference between 'SomePackage.LindeRenderer' and 'UnityEngine.LineRenderer'

Upvotes: 2

Patrick Kelly
Patrick Kelly

Reputation: 320

You may be able to resolve the issue but adding something along the lines of:

if(lineOfFlight == null)
{
     GameObject lineObject = new GameObject("Line");
     lineOfFlight = lineObject.AddComponent<LineRenderer>();
}

just below

if (recording.savedBuffer != null)
    {

to ensure lineOfFlight is being set correctly prior to being called by your Update() script. If this corrects your issue then there is a race condition causing Update() to be triggered for the object prior to Awake() being triggered

Upvotes: 0

Related Questions