Create a game without loading
Through my previous postmortem, I talked about applying some of the skills and optimization techniques I learned when I worked as an intern to Grim Panthera.
Today's post is related to this, and I'd like to introduce optimization techniques that can probably be used from light games to mobile games that you'll make later.
1. Techniques to turn over Scene
Maybe a few developers (or even players) who make the game have seen the loading screen that comes out when switching new screens. This is what I applied to my previous 'Press Axe' game, and the unnecessarily long loading time compared to the light game should be enough to annoy the player.
In the Unity engine, when switching between Scenes, the screen freezes and there is no response as if a bug has occurred. Developers actively recommend implementing and outputting a loading screen separately to inform players that the phenomenon is not a bug.
However, if Scene's transitions are frequent, it can also break the player's game experience, which becomes more prominent the simpler the game is.
Here I developed a desire for a game without loading, and it was nice to be able to apply the techniques I knew theoretically about this Grim Panthera.
Since we will be making simple games as independent developers, I would like to take this opportunity to introduce how we made this Grim Panthera.
2. Solve everything with one Scene - Object Pool Pattern
Basically, what Scene's transition means is that all used objects are destroyed and new objects are recreated except for objects in the DontDestroyOnLoad (ex: Game Manager objects used as singleton).
This is one of the things that causes a lot of computational overhead, and for this reason, the act of frequently creating or destroying multiple objects puts a lot of load on the CPU.
Here comes the Object Pool pattern, which reduces the burden on the CPU by activating/deactivating the object rather than creating/destroying it.
This is due to minimizing overhead by putting necessary items in several pools in advance and taking them out or putting them in whenever necessary.
And most importantly, the advantage of the pattern is that there is no difficult code to use separately to use it.
In terms of Unity, it means that the code is written by controlling the object with SetActive(true/false) instead of Instantiate/Destroy. You can flexibly add and execute code depending on the situation or condition you are developing.
3. The method used in Grim Panthera
When producing Grim Panthera, I made and introduced the game by putting objects inside one Canvas. The objects used here were not dynamically created/destroyed, but were written by taking out and using the necessary objects from pooling for each stage made in advance.
In my case, the role of the GameManager object used as Singleton was expanded and used as a place to put pooling objects. Each stage is assigned as a child of a GameManager object as a pool, and objects in Canvas enter the stage pool when switching stages according to the way the game is controlled.
public void ReparentChildren(GameObject from, GameObject to, bool toActive) { var children = new Transform[from.transform.childCount]; for(int i = 0;i< from.transform.childCount; i++) { children[i] = from.transform.GetChild(i); } foreach(Transform child in children) { child.gameObject.SetActive(toActive); child.SetParent(to.transform); } }
The above function is a function that exchanges objects in Canvas with objects in a specific pool. Finally, the code was written in the form of controlling SetActive(true/false) through the received true/false factor.
As the above code is executed, the children of the object are dynamically changed through the code, so when using the above code, be aware of the change in the ChildCount output value and write the code.
In addition, there are precautions when using the Obejct Pool pattern.
First, it is necessary to write the code assuming that all objects can be cyclized. It should be known that the operation of the Start() function to be previously executed while being instantiated is executed only once in that pattern. A method that needs to be executed each time an object is activated creates and executes an OnEnable() function or a new function.
Second, if there is a component number that has changed during the activation of an object, it is not initialized unless specified by the developer. Make sure to use the object after going through an initialization process in the process of fetching the object.
4. The end!
The advantages of using this pattern and how to use it have been described. However, the biggest drawback is that it consumes a lot of resources because there are far more objects created in advance than the existing method. But we don't make games that are GOATED enough to run out of resources, right? If you have a chance, I recommend you apply this pattern to the next game!
Get Grim Panthera(Demo v1.0)
Grim Panthera(Demo v1.0)
James Lee found his lips sewn in Wildwoods, Colorado. Attached record.
More posts
- Grim Panthera PostmortemMar 16, 2024
- Grim Panthera demo is now supported Mac!Mar 14, 2024
- Added more direct hints.Mar 14, 2024
- Grim Panthera demo has been released!Mar 13, 2024
Leave a comment
Log in with itch.io to leave a comment.