What is the benefit of one single MonoBehavior class? - c#

Sometimes I see how Unity programmers use one script that inherits MonoBehavior for almost the entire project. The so-called "Update Managers". All scripts are subscribed to the queue for execution, and the manager runs all functions, and after execution removes them from the queue.
Does this really have any effect on optimization?

This was one of the optimization technique I analyzed in my thesis.
The Unity engine has a Messaging system which allows the developers to define methods that will be called by an internal system based on their functionalities. One of the most commonly used Messages is the Update message. Unity is inspecting every MonoBehaviour the first time the type is accessed (independently from the scripting backend (mono, il2cpp)) and checks if any of the Message methods are defined. If a Message method is defined then the engine will cache this information. Then if an instance of this type is instantiated then the engine will add it to the appropriate list and will call the method whenever it should. This is also the key reason why Unity does not care about the visibility of our Message method, and that they are not called in a deterministic order.
public class Example1 : MonoBehaviour
{
private void Update() { }
}
public class Example2: MonoBehaviour
{
public void Update() { }
}
Both of the above achieves the same results but god knows which will be called first.
One of the main problem with this approach is that every time the engine calls a Message method an interop call (a call from c/c++ side to the managed c# side) has to happen. In case of Update luckily no marshaling is needed so this overhead is a bit smaller. However, if our game handles thousand or tens of thousands of objects which all have a script requiring a Message call then this overhead can be significant. A solution to this is to avoid interop calls. A good approach to this is behavior grouping. If we have a MonoBehaviour that is attached to a huge number of GameObjects we can cut the number of interop calls to just one by introducing an update manager. Since the update manager is also a managed object running managed code the only interop call will happen between the update manager’s Update Message and the Unity engine’s internal Message handler. We have to note the fact that this optimization technique is only relevant in large scale projects, and the frame time saved via this technique is more impactful when using the Mono scripting backend. (Remember IL2CPP transpiles to C++).
The above picture illustrates the difference between the two methods.
Let's do a benchmark with Unity's performance tools. The benchmark will spawn 10 000 gameobjects each with a mover script which moves these cubes up and down.
Illustration of the example scene using the traditional method.
Now let's see the results of the bechmarks.
Not surprisingly IL2CPP leading the competition by far however it’s still interesting that the Update Manager is still twice as fast as the traditional way. If we profiled the execution of the Traditional method’s IL2CPP build we would find many Unity specific calls like check if the GameObject exists before invoking a component method etc. and these would explain the longer execution time. We can also make the conclusion that IL2CPP in this case is far faster than Mono, usually around twice as fast. The benchmark ran for one minute prior to a 5 seconds warmup and both scripting backends had the ideal compiler setting.

Based on this article which your link has a link to, having an "update manager" does indeed have a positive impact on performance when compared to using Unity's Update method. The gist is that if you implement Update in one of your classes, Unity has some additional overhead in calling Update; it doesn't run quite as fast as calling a method yourself, such as saying myObject.Update(). So if you're calling Unity's Update on 10,000 game objects per frame, that additional overhead becomes noticeable.
If you explicitly call your update-type methods from a "manager" class -- rather than letting Unity call the "magic" Update methods -- then you can avoid the additional overhead that comes with using "magic" methods.
But keep in mind that the performance penalty of using Update will only be noticeable if you have a lot of game objects in your scene that all implement Update. Game objects in your scene that don't implement Update won't have an effect. It would be good practice to remove the Update method that Unity adds to all new scripts if you're not using it though.
In short, unless you have a huge number of objects in your scene and you are running into performance problems, I wouldn't worry about it.

Related

How to call OnTriggerEnter less frequently?

I have a game that I have been developing and it requires the OnTriggerEnter() to be called many times with many different GameObjects. Although it is called a lot, I don't need it to be called extremely frequently. So, I was wondering if it is possible to lower how often the method is called such as calling it every other update or even less often than that. Is this possible?
You could check trigger collisions manually with functions like Physics.CheckBox.
Put it in a slow coroutine and cache the result of the collision, so you can always check the last state of it.
Still in early phase of learning both Unity and C#, but this came up in an excercise and might be the answer to your problem ?
from :https://docs.unity3d.com/Manual/Coroutines.html
By default, a coroutine is resumed on the frame after it yields but it is also possible to introduce a time delay using WaitForSeconds:
This can be used as a way to spread an effect over a period of time, but it is also a useful optimization. Many tasks in a game need to be carried out periodically and the most obvious way to do this is to include them in the Update function. However, this function will typically be called many times per second. When a task doesn’t need to be repeated quite so frequently, you can put it in a coroutine to get an update regularly but not every single frame. An example of this might be an alarm that warns the player if an enemy is nearby.
To set a coroutine running, you need to use the StartCoroutine function:

C# Is it appropiate to use IEnumerator Coroutines in Unity for the application's logic flow?

I am developing in Unity using C#, and would like to ask if it is appropriate to use IEnumerator Coroutines to determine an application's execution of user logic? And if there are any other optimal solutions to implement this.
To clarify as a series of strict sequential actions...
User triggers GUI action.
Open Form, and waits until it is filled out.
Begins checking if winning condition is satisfied in task (4.), if completed, jump to (5.)
Series of sequential tasks for user to complete, returns a result back to (3.) after a cycle is complete. Keep cycling between stages (3.) and (4.) until winning condition is satisfied.
Winning condition is met, inform user of final result. Exit co-routine.
I do hope that my logic is sound, and apologies for the vagueness of the specific task involved.
Using coroutines is completely fine for the right reasons. Although from what i read what you are making is a manager that checks the state of the game.
What i would do in that case is having a simple manager that doesn't utilize the update loop or coroutines at all, instead any gameobject which can change the state of the game tells the manager about the change. By basically turning it around the manager does not have to know a single game object and also doesn't use any performance to check all the relevant objects.
Using this architecture you could also add an event handler architecture which solves the problem of gameobjects knowing the manager, now you have a completely decoupled manager from the game :)
While what you have in mind is certainly possible, it will be hard to maintain once you will have multiple winning conditions, perhaps losing conditions, and more than one player.
If you think that this will be an issue for you, I suggest making a "game state" as a singleton, and allow different game objects to change the status within their respective Update() calls.
(I would also like to point out that creating singletons in unity is rather easy - during Awake() save the object itself as a static variable)

Performance of FindGameObjectWithTag(Tag tag) Versus Using Public Variables for GameObjects in Unity

Basically, I am trying to optimize a game for Unity for mobile devices. Therefore, it is imperative to contain CPU usage. As this is a complex game, many of the scripts reference each other (and their GameObjects). Currently, I am using GameObject.FindGameObjectWithTag(Tag tag) to reference other GameObjects, Components, and Scripts. I am also aware that this can be done with public variables by using the drag-and-drop in the editor. But as I know which GameObject will be dropped into each level, I found the first option to be simpler to use as the drag-and-drop led to errors many times and was tedious to use. However, that will not be a problem, and I feel performance of one or the other outweighs these fall backs. I was wondering if there was a difference in terms of performance for these two approaches, and which one would be better suited for a high performance, mobile, aspect.
FindGameObjectWithTag() has a complexity O(n) in the worst case scenario. You will not have performance issue if you have small amount of objects in your scene and small amount of objects searching for objects with tags.
Another approach is by serializing these objects in the script and using them. With this approach you decrease CPU usage and increase memory usage since no meta objects exist in the scene or not you allocate memory for them.
I suggest a third approach if it is possible for you. Search for Singleton pattern on Google and YouTube. It allows you to have a reference to that object if it's 1 all the time, without every time trying to find it with FindGameObjectsWithTag()... resulting in very small CPU and memory usage.
In my experience your best bet is to create a public variable, if it isn't assigned when you need it, use your method of FindGameObjectWithTag or however you finding it before, store it in that public variable so you only have to do the lookup once. As long as you don't do the FindGameObjectWithTag every frame the lookup hit shouldn't be too bad.

WinJS web worker call vs call to WinRT C# component returning a promise

I'm working on a WinJS game in which part of the logic is implemented in a C# WinRT component because it proved to be both more efficient and easier to conceptualize and debug. That component is called on a relatively infrequent basis and returns a promise whose return value I plug back into the WinJS game object.
Now I have a second scenario where I want to speed up an SVG animation by delegating the necessary maths work which occurs during the animation phase to a separate thread and return an object which represents the pure UI action to take, e.g., a list of game objects which should move / grow etc, and have the main thread action that quickly against the DOM (I'm using Knockout). Unlike the first scenario, this background thread interaction would happen for each animation increment, so, quite a lot.
I was going to implement this with a web worker, which I have partly got working, but I want to make sure I understand the pros and cons and recommended use cases of these 2 approaches. It seems that calling a WinRT component and calling a web worker both involve some kind of serialization or translation of the object being passed. For my existing WinRT call I have a WinRT factory class as a property on my js object and I use that to build a mirror simplified WinRT representation of the game to pass to the WinRT component. With a web worker I would have to pass a JSON copy of the relevant aspects of the game and then translate the result back again. Would I be better off using a call to C# again, or is that really only recommended for infrequent calls? What's the relative overhead of each? Is there anything else I'm missing?
Besides what Tavares mentions there is no real hard fast rule. Communication between WebWorkers is faster than a call to WinRT BUT WebWorkers are not something you want to create and destroy repeatedly.
In this case I personally would use a Webworker that I create once during startup and then called the method in it every time I need something calculated.

Game Programming and Event Handlers

I haven't programmed games for about 10 years (My last experience was DJGPP + Allegro), but I thought I'd check out XNA over the weekend to see how it was shaping up.
I am fairly impressed, however as I continue to piece together a game engine, I have a (probably) basic question.
How much should you rely on C#'s Delegates and Events to drive the game? As an application programmer, I use delegates and events heavily, but I don't know if there is a significant overhead to doing so.
In my game engine, I have designed a "chase cam" of sorts, that can be attached to an object and then recalculates its position relative to the object. When the object moves, there are two ways to update the chase cam.
Have an "UpdateCameras()" method in the main game loop.
Use an event handler, and have the chase cam subscribe to object.OnMoved.
I'm using the latter, because it allows me to chain events together and nicely automate large parts of the engine. Suddenly, what would be huge and complex get dropped down to a handful of 3-5 line event handlers...Its a beauty.
However, if event handlers firing every nanosecond turn out to be a major slowdown, I'll remove it and go with the loop approach.
Ideas?
If you were to think of an event as a subscriber list, in your code all you are doing is registering a subscriber. The number of instructions needed to achieve that is likely to be minimal at the CLR level.
If you want your code to be generic or dynamic, then you're need to check if something is subscribed prior to calling an event. The event/delegate mechanism of C# and .NET provides this to you at very little cost (in terms of CPU).
If you're really concerned about every clock cycle, you'd never write generic/dynamic game logic. It's a trade off between maintainable/configurable code and outright speed.
Written well, I'd favour events/delegates until I could prove it is an issue.
The only way you'll truly know if it is an issue for you is by profiling your code -- which you should do anyway for any game development!
It's important to realize that events in C# are not queued asynchronous events (like, for example the Windows message queue). They are essentially a list of function pointers. So raising an event doesn't have worse performance implications than iterating through a list of function pointers and calling each one.
At the same time, realize that because of this, events are synchronous. If your event listener is slow, you'll slow down the class raising the events.
The main question here seems to be:
"What is the overhead associated with using C# Delegates and Events?"
Events have little significant overhead in comparison to a regular function call.
The use of Delegates can create implicit and thus hidden garbage. Garbage can be a major cause performance problems especially on the XBox360.
The following code generates around 2000 bytes of garbage per second (at 60 fps) in the form of EntityVisitor objects:
private delegate void SpacialItemVisitor(ISpacialItem item);
protected override void Update(GameTime gameTime)
{
m_quadTree.Visit(ref explosionCircle, ApplyExplosionEffects);
}
private void ApplyExplosionEffects(ISpacialItem item)
{
}
As long as you avoid generating garbage, delegates are fast enough for most purposes. Because of the hidden dangers, I prefer to avoid them and use interfaces instead.
In my extra time away from real work, I've been learning XNA too.
IMHO (or not so humble if you ask my coworkers) is that the overhead of the event handles will be overwhelmed by other elements in the game such as rendering. Given the heavy use of events in normal .Net programming I would be the underlying code is well optimized.
To be honest, I think going to an UpdateCameras method might be a premature optimization. The event system probably has more uses other than the camera.
XNA encourages the use of interfaces, events and delegates to drive something written with it. Take a look at the GameComponent related classes which set this up for you.
The answer is, "As much as you feel comfortable with".
To elaborate a little bit, If for example you take and inherit from the gamecomponent class into a cameracontroller class and add it to the Game.Component collection. Then you can create your camera classes and add them to your cameracontroller.
Doing this will cause the cameracontroller to be called regularly and be able to select and activate the proper camera or multiple cameras if that is what you are going for.
Here is an example of this (All of his tutorials are excellent):
ReoCode
As an aside, you might be interested to know that Shawn Hargreaves, original developer of Allegro, is one of the main developers on the XNA team :-)
Before going into what is the impact of an event in terms of performance you must first evaluate whether or not it is needed.
Assuming you are really trying to keep a chase cam updated and its not just an example, what you are looking for is not an event (though events might do the trick just as well), if you are following an avatar likelihood is it will be moving most of the time.
One approach I found extremely effective is to use hierarchic transformations, if you implement this efficiently the camera won't be the only object to benefit from such a system, the goal would be to keep the camera within the coordinate space of the object it is tracking.
That approach is not the best one if you want to apply some elasticity to the speed and ways in which the camera tracks the object, for that, it is best to use an update call, a reference, and some basic acceleration and resistance physics.
Events are more useful for things that only happen from time to time or that affect many different aspects of the application, like a character dying, probably many different systems would like to be aware of such an event, kill statistics, the controlling AI, and so on, in such a case, keeping track of all the objects that would be have to constantly check if this has happened is far less effective than throwing an event and having all the interested objects be notified only when it happens.

Categories

Resources