1

This is a C variable referencing question in Unity and not a gameobject reference question.

I need to get the address of newVar, as in &newVar. Is this possible in Unity? I have tried a number of searches and cannot find an answer.

There is documentation about how to do this in C but I need to do it in Unity.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Paul Moore
  • 136
  • 1
  • 16
  • 1
    Unity uses `C#`, not `C`. Can you explain why you think you need to do this and what problem you're trying to solve? Seems like a possible XY problem. – Retired Ninja Feb 16 '21 at 17:30
  • 1
    Does this answer your question? [C# memory address and variable](https://stackoverflow.com/questions/588817/c-sharp-memory-address-and-variable) – Alberto Casas Ortiz Feb 16 '21 at 17:36
  • I am using Archimatix for model generation. The process has variable exposure from with in the nodes to create variables listed for access within a runtimecontroller. They are by name. I have a need to put this in a table to reference by newVar[i] instead of writing code that talks to every exposed var explicitly. In my case I have 9 vars that have +5 functions dealing with them so this amount to a lot of code. – Paul Moore Feb 16 '21 at 17:37
  • @PaulMoore What type are these variables? Are they all, e.g., floats? – Ruzihm Feb 16 '21 at 18:16
  • @Ruzihm They are floats. – Paul Moore Feb 18 '21 at 02:26
  • @PaulMoore Did you find a solution to this? – Ruzihm Feb 25 '21 at 17:55

2 Answers2

1

I've never used Archimatix but looking at the manual I see online, it looks like this will work. In c#, lambdas capture variables by reference, so you can have the params read the result from a lambda to get an up-to-date variable.

public class ParamUpdater: MonoBehaviour {

    [SerializeField] AXModel model;

    List<AXParameter> params;
    List<Func<float>> paramGetters;

    // Use this for initialization
    void Awake () {

        // Establish refernces to AXModel parameters.

        Params = new List<AXParameter>();
        if (model != null)
        {
            Params.Add(model.getParameter("Engine.Param0"));
            Params.Add(model.getParameter("Engine.Param1"));
            // add more params here
        }

        paramGetters = new List<Func<float>>();
        
        // create default getters
        for (int i = 0 ; i < Params.Count ; i++)
        {
            paramGetters.Add(()=>0f);
        }
    }

    public void ConfigureParamGetter(int index, Func<float> getter)
    {
        paramGetters[index] = getter;
    }
  
    public void Recalculate()
    {
        for(int i = 0 ; i < Params.Count ; i++)
        {
            float curVal = paramGetters[i]();

            // Maybe a different method would be better? 
            // online API is very lacking...
            Params[i].initiatePARAMETER_Ripple_setFloatValueFromGUIChange(curVal);
        }  

        model.autobuild();
        recalculate();
    }
}

And then for example in a class where a float of interest lives, call ConfigureParamGetter with a Func that returns the variable. As mentioned before, the capture is done by reference, so it will always be up to date when called in ParamUpdater.

public class ImportantClass: MonoBehaviour
{
    [SerializeField] ParamUpdater paramUpdater;
 
    float importantFloat;
   
    // Use Start to call after ParamUpdater initializes in Awake
    void Start()
    {
        paramUpdater.ConfigureParamGetter(0, ()=>importantFloat);
    }

    // for example
    void Update() { importantFloat = Time.time; }
   
    // called whenever
    void DoRecalculate()
    {
        paramUpdater.Recalculate();
    }
}

Let me know if I made any syntax errors or any other problems, I can try and fix 'em.

Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • 1
    Thanks, @Ruzihim. This is pretty heavy C#. I had a suspicion I could get under the hood with Ax but reluctant to go there. Well further on in my project this access method has crept up again. It seems I am going deeper into than what was originally intended by the Devs but the access is there. This is a possible avenue for me. The real test would be if the access process is still viable should I regenerate the Ax real time controller. – Paul Moore Feb 26 '21 at 18:26
0

You require Pointers and the unsafe code keyword.

Classes in C# are already references, so not much use converting to pointers. IE a GameObject is already a reference type, and it already works like a pointer.

For other things, such as unmanaged types, you might use unsafe code and pointers.

So you can do things such as char* pc = &c;

Also remember to "Allow unsafe code" with File > Build Settings... => Click Player Settings => Code Setting => Allow 'unsafe' code.

Jack Mariani
  • 2,270
  • 1
  • 15
  • 30
  • Thanks. If I was writing code as a top level application then this would be an option. But since I am way deep in Unity and a code based asset then this option to me seems a bit dangerous. It could crash levels of operation either in Unity or Archimatix. Allowing unsafe code could allow memory leaks or memory consumption due to no garbage collection. And I dont believe any apk hosters would allow this, like Google store. – Paul Moore Feb 16 '21 at 18:00
  • Disadvantages of Unsafe Mode It increase the responsibility of the programmer to check for security issues and extra developer care is paramount to averting potential errors or security risks. It bypasses security. Because the CLR maintains type safety and security, C# does not support pointer arithmetic in managed code, unlike C/C++. The unsafe keyword allows pointer usage in unmanaged code. However, safety is not guaranteed because strict object access rules are not followed. It also avoids type checking, that can generate errors sometimes. – Paul Moore Feb 16 '21 at 18:07
  • 1
    Yes. Exactly. Basically unsafe code in C# makes things much similar to C or C++. You may gain performance, at the cost of getting more risk. If you require performance you might try the [Job System](https://docs.unity3d.com/Manual/JobSystem.html). – Jack Mariani Feb 17 '21 at 07:04
  • I check this as the answer and not because it shows me what I can do but because of the cautionary liturgy expressing safety over what I want to do. Thank you. – Paul Moore Feb 26 '21 at 18:19