Creating a visual script - passing variables between classes

I’m trying to come up with a simple visual scripting system and I could use some technical help. My c# skills are basic but I never did anything that needed more than basic skills until now.

The main idea of the system is simple. There’s a base class called Block, containing an abstract definition of a function Act() and a nextBlock variable of type Block. It’s the basic piece of the visual script, every command expands Block, like IfStatement : Block, which also contains another block in case the testing (which happens inside its own Act()) yields true, and a couple of parameters to test (a>b etc). I still have no interface to create these connections but the way it’s intended to work is by creating the classes, defining its variables, and then the first block calls its Act() which contains a nextBlock.Act() which will eventually run the entire network. I made a few tests with this system and it seems to work fine.

The problem is how to introduce variables. I thought I would be able to pass references to variables using ref to the constructor of the class to store in a local variable for later use (Act) but it loses the reference then.

Here’s a simplified version of the code

//to keep it simple, I'm only working with int for now
class Variable{
    int myVal = 0;
    Variable (int a)
    {
        myVal = a;
    }
}


abstract class Block {
    public Block nextBlock;
    abstract public void Act ();
}

public class Incrementer : Block {
    public Variable a;
    int increment = 0;
    public Incrementer(ref Variable v, int y){
        a = v;
        increment = y;
    }
    public override void Act(){
        a.myVal ++;
        if(nextBlock!= null) nextBlock.Act ();
    }
}

public class IfIntBigger : Block{
    int a;
    int b;
    Block trueBlock;
    Block falseBlock;
    public IfIntBigger(int x, int y, Block t, Block f){
        a = x;
        b = y;
        trueBlock = t;
        falseBlock = f;
    }
    public override void Act(){       
        if (a > b)
            trueBlock.Act ();
        else
            falseBlock.Act ();   
        if (nextBlock != null)
            nextBlock.Act ();
    }
}

public class Layer : MonoBehaviour {

    Incrementer firstBlock;
    List<Variable> vars;
   
    void Start () {
        //adding a new variable to the list
        vars = new List<Variable> ();
        vars.Add (new Variable (15));
        //you can't pass it directly as ref because of 'reasons'
        Variable tempv = vars [0];
        print (vars[0].myVal.ToString ()); //output: 15
               
        firstBlock = new Incrementer (ref tempv, 3);       
       
        firstBlock.Act ();

        print (vars[0].myVal.ToString ()); //output: 15

    }

}

Any ideas? I never run into this kind of problems when working with monobehaviour classes. Every gameobject in the scene could have a reference to this Layer object and alter the vars List any time. But I would like to avoid turning every class into its own component of a gameobject and instead learn how monobehaviour achieves that functionality.

Aaand I solved it. So often I get stuck on a problem for an entire day, then I ask for help and solve it by myself within minutes after posting.

Anyway, my code isn’t exactly like the one I posted. That thing above should actually work! I was doing something stupid like using my own PrintBlock instead of regular print, but without passing a ref like I did for the iterator, so the iterator was modifying the original variable as intended, but the print block was printing the old version.

In any case, I’m not doing that either. When I mentioned in my last post how it works with monobehavior it hit me. I could just pass the Layer class and an index to the List. That way I have continuous access to everything in Layer from every class. Like this

public class Incrementer : Block {
        public Layer layer;
        public int varIndex;
        int increment = 0;
        public Incrementer(Layer l, int x, int y){
            layer = l;
            increment = y;
            varInd = x;
        }
        public override void Act(){
            layer.vars[varInd ].myVal ++;
            if(nextBlock!= null) nextBlock.Act ();
        }
    }

I’m not sure if this approach of using indices to an array will give me trouble later on though. I understand the indices of a List are not too trustworthy. But each var having an index and some clever code to keep that updated doesn’t seem hard to do.

Anyway, thanks for helping! I mean, if I solved after posting here it must mean that it helped posting here. Hopefully this could be useful for future googlers.