3

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)".

nmw01223
  • 1,611
  • 3
  • 23
  • 40
  • Can you include the code where you define `lineOfFlight`? – Remy Jun 18 '20 at 15:33
  • 1
    I have added it. – nmw01223 Jun 18 '20 at 15:38
  • Could you also add the relevant code as is? The code in the question wouldn't compile anyway (no return types, "...." etc). This makes it a lot harder for us to help you pin point the problem as in making the code compilable we may unknowingly fix the issue you are up against. – Remy Jun 18 '20 at 15:58
  • It's quite a big file and I don't want to chop it down as the problem may change. Here is a link to the whole file (https://drive.google.com/file/d/1MFS1-CKA1g6JiRcGiTQi1OpNl-j-bgBq/view?usp=sharing). Only a few lines are relevant: 50-51 - declaration of lineOfFlight, 114-117 - adding the LineRenderer in Awake(), and 236-246 - setting it up. The only compilation error is at 245 "'LineRenderer' does not contain a definition for 'SetPositions' ....". Thanks for your help. – nmw01223 Jun 18 '20 at 16:17
  • Btw you could simply do `lineOfFlight = new GameObject ("Line").AddComponent(); Debug.Log(lineOfFlight); ` – derHugo Jun 18 '20 at 16:25
  • Yes I know, but I am trying to see what is going wrong and where. – nmw01223 Jun 18 '20 at 16:29
  • I am just wondering if this could in any way be connected with my installing the Unity.UI.Extensions package? It does line drawing stuff too. I never used this (couldn't make it work for similar reasons), but I cannot work out how to uninstall it. Doesn't show up in package manager. – nmw01223 Jun 18 '20 at 16:31
  • I think you'll have to chop the code up yourself to only include the line renderer stuff in your script (or alternatively make a seperate script with just the line renderer stuff in it to see if the problem persists). it is the first step to debugging (making a minimal reproducable example https://stackoverflow.com/help/minimal-reproducible-example). I copied the file you linked, and cut out all the stuff that didn't have to do with the line renderer and it worked just fine for me. without a minrep it'll be very hard for us to help you further – Remy Jun 18 '20 at 16:42
  • OK, thanks. I've created a Test.cs, 65 lines long. It is shown in the main bit above and is absolutely minimal. Comes up with exactly the same error - no SetPositions() in LineRenderer. The editor (Visual Studio Code) shows the error, as does Unity on saving the file - both 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)" – nmw01223 Jun 18 '20 at 17:15

3 Answers3

2

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'

Remy
  • 4,843
  • 5
  • 30
  • 60
  • Thanks for your help on this - that is exactly what it was. Defining everything as UnityEngine.LineRenderer solved it. I think this may have come about by installing the Unity.UI.Extensions package - I had other similar problems that started then, though they do say everything of theirs is in their own namespace. I thought I had managed to remove it all, but maybe not. – nmw01223 Jun 18 '20 at 23:54
  • @nmw01223 just out of curiosity, was your IDE not throwing an error like `error CS0104: 'LineRenderer' is an ambiguous reference between 'SomePackage.LindeRenderer' and 'UnityEngine.LineRenderer'` (or something similar)? Usually they should be able to pick up on that. – Remy Jun 19 '20 at 06:20
  • Not 100% sure, but certainly don't remember seeing it. – nmw01223 Jun 20 '20 at 04:11
0

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

Patrick Kelly
  • 297
  • 2
  • 9
  • 1
    Thanks, but didn't help, I'm afraid. This is a compile time issue, so I don;t think a runtime race condition could come into it. Also adding a new component is an expensive process - wouldn't really want to do that in Update(). Thanks anyway. – nmw01223 Jun 18 '20 at 16:07
  • Ah fair I missed this was a compile time issue and not a runtime one. – Patrick Kelly Jun 18 '20 at 16:32
0

try to assign points count before setting positions

lineRenderer.positionCount = list.Count;
lineRenderer.SetPositions(list);
LeeRoyHero
  • 71
  • 2
  • 5