Guestimating cost of changing code from A to B.

I have a dilemma. I think I might be able to improve coding efficiency, but, it might increase overhead by a substantial amount. “Check it yourself” is not an option, because overwriting this would take also quite a big amount, if impact is minimal or even positive, then it’s definitely worth it. But going to rewrite it is going to pain my back.

Check these two situations (all pseudo code):

This is first version:

using MyScriptSet;

class Player : MonoBehavior {

    void Awake() {
        MySecondScript mySecondScript = GetComponent<MySecondScript>();
    }

    void SendToOtherClass(object[] data = null) {
        mySecondScript.ExecuteThis(data[0]);
    }
   
}


///


class MySecondScript : Monobehavior {

    public void ExecuteThis(string something) {
        // Do do do do do do
    }

}

This is the second version:

using static MyScriptSet.MySecondScript;

class Player : MonoBehavior {

    // Reference in namespace
    void SendToOtherClass(object[] data = null) {
        MySecondScriptSink("executeThis", data[0]);
    }
   
}


///


class MySecondScript : Monobehavior {

    public MySecondScriptSink(string func, object data) {
        switch (func) {

            // tens of cases here
            case "executeThis": {
                // Easy preparataions
                ExecuteThis();
                break;
            }
           
            // tens of cases here
        }
    }

    public void ExecuteThis(string something) {
        // Do do do do do do
    }

}

The who’s and why’s are not necessarily important, what I’m wondering is how much will it cost computationally. If it happens a lot, as a main feature to control information flow in the game, how heavy will the overhead be? I know this is one of the things that you don’t know for sure unless you do it, so I rely more on your experience on it.

Second version looks ugly to me. Why don’t you use unity or .net native events to send random events to another class instances? And if events are not enough, then why don’t you implement command pattern to allow your MySecondScript to execute complex commands?

2 Likes

I definitely feel like there is a better way then either of these things to accomplish your goals, possibly UnityEvent as hinted at above, but it’s hard to make a good recommendation without actually knowing what your actual goals are.

2 Likes

This may sound stupid, I can read the UnityEvent here.

Could you please modify either examples to work with UnityEvent because I’m missing something. Is UnityEvent something like SendMessage with listener?

class MyUnityEvent : UnityEvent<object[]> {
}

public MyUnityEvent myUnityEvent;

void SendToOtherClass(object[] data = null) {
    myUnityEvent.Invoke(data)
}

After that you may add subscribers to myUnityEvent via Inspector window or script code.

The simple answer is that the second version is worse than the first, both in terms of performance (although it would likely be unnoticeable if you have small data arrays) and code maintenance. Are you sure you need to refactor this code in the first place? Are you actually seeing performance problems caused by this?

It looks like regular code to me, but without GetComponent or using.

Do you understand what the event is?

It looks like System.Action to me. I’m not advanced in C#, sorry. Sorry, I don’t.

1 Like

Well I knew about the thing at the bottom with onClick, but I found it too staticy for my liking. I see that with script you can pass data forward, which is definitely a step forward. The question is, can I request any data?
var myPlayer = event_getPlayer.Invoke(myId); ? And get the function executed and it to return data that I ask?

No you can’t. Understand the concept of event. The event is a thing to invoke multiple not known foreahead callbacks when something happens in your script. Event can’t return a signle value because multiple function may be called. At least, not directly. You may provide an object as a event parameter to allow callback to write some data to that object.

For instance, you can have OnSendDamage event on your character. Whenever the character attacks someone, it fires that event. Everything on character, what may affect amount of damage dealt with attack writes its modifiers into list provided with event. After that, final amount of damage is calculated using base amount of damage and modifiers and is sent to victim.

In this model i don’t know what script may exist on my character and what of them may modify outgoing damage amount. Later on, when I want something, for instance a gauntlet, to add amount of damage, i go to gauntlet script, add handler to that event, and provide correct values inside that handler. Everything else happens automagically.

It might be important because there can be other alternatives that are 1) typesafe 2) more elegant 3) easier to maintain 4) achieve better structure of the code.

Why do you have those object arrays? Where do they come from?

The examples you’ve provided are a little too abstract. Performance would most-likely not differ a lot, because all that you’ve done is replacing direct method calls with string-mapped method calls.
The switch-case only accepts constants and literals, i.e. even when the list of cases grows, the compiler can generate code that results in performance which will be acceptable in many cases.

The real question is, why do you want to replace method calls with some mapping approach? It’ll render lots of language features useless and makes your application extremely difficult to maintain.

1 Like