+1
Cannot Reproduce

AOT Error (scriptable Object: A local variable cannot be used before it is declared)

Elin 11 months ago updated by Lazlo Bonin (Lead Developer) 9 months ago 5

I have another unusual problem. To my dismay a customer now wants an iOS app of the app, which was developed only for PC.
The whole app is strongly based on scriptable objects. These are assigned as object variables on a disabled UI element.

When I want to generate AOT I get a lot of errors which are all due to my scriptable object.

For example, my scriptable object is called Hotspot: 

Error message: Assets/Plugins/Ludiq/Ludiq.Core/Generated/AotStubs.cs(4108,42): error CS0841: A local variable `target' cannot be used before it is declared

Code:
// Hotspot.Properties
[UnityEngine.Scripting.PreserveAttribute()]
public static void Hotspot_Properties()
{
global::Hotspot target = default(global::Hotspot);
global::UnityEngine.Sprite accessor = target.Properties;
target.Properties = default(global::UnityEngine.Sprite);
global::Ludiq.InstanceFieldAccessor optimized = new global::Ludiq.InstanceFieldAccessor(default(global::System.Reflection.FieldInfo));
optimized.GetValue(default(global::Hotspot));
optimized.SetValue(default(global::Hotspot), default(global::UnityEngine.Sprite)); -> in this line is the first Error
}

The funny thing is when I create a new project in the same Unity version with the same Bolt version my Scriptable object is integrated and set in the Bolt setup types it works without problems.

Does someone had a simular problem?
I tried reimporting bolt, update units, unity restarts, deleting bolt restarting unity fresh bolt install, but nothing worked.

Bolt Version:
1.4.1
Unity Version:
2018.2.5
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):
Pending Review

Hi Elin,

Thanks for the report. It seems like the AOT stub generator skips declaring the optimized accessor, but still tries to call it afterwards. I'll look into what may be causing this.

Can you paste the method declaration of Hotspot.Properties?

Its very basic. I'm just getting strings and two sprites from my scriptable object.


using System.Collections;

using System.Collections.Generic;

using UnityEngine;

[CreateAssetMenu(fileName = "New Hotspot", menuName = "Client/Hotspot")]

public class Hotspot : ScriptableObject {

public string Titel;

public string OverlayTitel;

public string OverlaySubTitel;

public Sprite Properties;

public Sprite Benefits;

public string CMName;

public string HighlightMeshName;

}

Hi Elin,

Looking at this again, it seems that the error is caused by the other one: Type or namespace name Hotspot could not be found. Is there any chance it's declared in an editor-only folder (anything under /Editor/) or in an assembly definition that is not included in builds?

Nope. It's not in a editor folder and I didn't added it to the type options, because the type scriptable object provided every option I needed.

Hmm... I deleted every line in the AOT file that is related to my scriptable object and now it seems to be working. 

Cannot Reproduce

Hi Elin!

Sorry for the very late reply on this.

I tried reproducing the issue but wasn't able.

  1. Create a script called Hotspot.cs with the exact code you pasted
  2. Create a macro graph that logs Hotspot.properties on Start
  3. Run AOT Pre-Build

The generated code for the accessor is this:

        // Hotspot.Properties
        [global::UnityEngine.Scripting.PreserveAttribute()]
        public static void Hotspot_Properties()
        {
            global::Hotspot target = default(global::Hotspot);
            global::UnityEngine.Sprite accessor = target.Properties;
            target.Properties = default(global::UnityEngine.Sprite);
            global::Ludiq.InstanceFieldAccessor<Hotspot, UnityEngine.Sprite> optimized = new global::Ludiq.InstanceFieldAccessor<Hotspot, UnityEngine.Sprite>(default(global::System.Reflection.FieldInfo));
            optimized.GetValue(default(global::Hotspot));
            optimized.SetValue(default(global::Hotspot), default(global::UnityEngine.Sprite));
        }

Which corresponds to what you posted, but is actually perfectly valid C#.

Here, target is declared before it is used later.

The error I think comes from the fact that Hotspot is not found as a type (the error console log error). That would mean that it's not in an assembly that can be found by the compiler (usually, these are editor-only assemblies, or user defined assembly definition files that do not include the target platform). Please make sure that isn't the case.

If you still experience the issue and find a way to reproduce it consistently, please let me know by commenting here again!