Sonstiges: Developer Diary - The Creation of a Switch Game
Michael Grönert, am 26.12.2016, Seite 25 von 25
BadToxic Discord Server | GameMaster Discord Server | BadToxic on Twitter
BadToxic on Instagram | BadToxic's Dev Instagram | BadToxic on YouTube
Part 25: Character Individualization
We are used to being able to put together our own characters in RPGs and other games. We choose the gender, regulate height and stature and can adjust many different details. In diary entry 23 we created a 3D manga-style character, but so far it has remained as we created it with the VRoid Studio program. Today we want to explore how we can change the look of this character within Unity and our game.
What can we manipulate?
To find that out, let's examine the player object we got from VRoid Studio after the conversion process. In the following screenshot you can see an already slightly refined version of the object hierarchy, which we then merged with our player.
Structure of our player object
Under "Armature" we find a lot of nodes that stand for different body parts and joints. For example, the legs and the torso or spine extend from the hip. From there it goes to the chest and from there to the shoulders and to the neck. The basic idea is that we scale these individual parts differently, i.e. stretch or compress them, in order to obtain new proportions. But is it really that simple? No, of course it is not. First of all, you have to notice that all parts below are being distorted as well. For example, if we want wider shoulders, the arms will also have a larger diameter. But of course only on the axis that we are changing - so wider shoulders create an oval arm cross-section, which we do not want. There are also rotations between the nodes, which makes the whole thing a bit more complicated. So changing the X-axis of an object can also influence the Y-axis of the child objects instead of their X-axes. Probably even pro rata - around 20% the X-axis and 80% the Y-axis.
So if we want to change individual body parts, we have to compensate for the changes in their child objects. For example, if we make the arms 10% longer, we have to make the hands underneath shorter by 10%. To do this, we need to know which axes of the child we have to adjust by how much in order to achieve the 10% overall. To stick to this example - maybe shorten your hands by 6% on the X-axis and 2% on the Y and Z-axes, respectively. Calculating what needs to be changed and by how much seems to be more time-consuming than trying it out, even if it turns out a bit rough.
How can we do that?
Planning the implementation is even more difficult. We want a UI where we can use sliders to change different parts of the body. The code behind needs references to the individual body parts that are supposed to be changed. So we create a "CharacterCustomizationController", as I called the C# class, which gets a "player", runs through it independently and collects the references based on the node names so that they can be accessed directly later on. Each slider of a changeable body part gets a range of values according to a sense of proportion - a minimum and maximum stretch or compression. And now the tricky part: In addition, each slider receives a list of references to other parts of the body that are to be scaled to the exact opposite for compensation. For each of these references we need a 3D vector which indicates the proportions to which these referenced body parts should be scaled and on which axes.
Code example: Necessary references and scaling vectors to change the arm lengths.
In order to find out everything necessary for this, a lot has to be tried out - one says "Trial & Error". And this accumulates a number of values that also want to be managed. We need average default values that match the initial situation best. Then there are the minima and maxima and a factor by how much a scaling changes when you move the slider by a certain distance. The minimum and maximum can of course result from the factor (or vice versa), since the sliders have a fixed value range from zero to one.
Code example: Necessary factors and standard values for ten changeable body parts
These values have to be saved and loaded and also have to be transmitted in multiplayer via network so that you can see the settings of other players. However, I will not go into more detail here, since it is mainly a lot of writing effort and the storage system and communication via the network have already been mentioned in previous diary entries.
The graphical realization
At the push of a button, we let the camera move and zoom to our character in the middle of the game at any time. We have a two-part user interface: the categories of body parts can be selected on the left and corresponding sliders are displayed on the right. In the video above you can see a very simple and early implementation. Only standard Unity UI graphics are used here and keywords describe the functions. In my opinion, such texts aren’t very pleasant to look at and you have to put more effort into translating the game into several languages. So I consider how images can achieve the same meaningfulness. In the following video you can see how I implemented it in the end - simple figures, each of which shows what is changing. For the body categories on the left, entire body areas are marked in blue. The concrete axes are shown on the right-hand side at the affected points. In addition, the user interface is now more compact, only stays at the edge of the screen and is minimally more attractive in design.
It is finished
So we have achieved our goal. In fact, I only implemented settings for the body parts for which it was possible with reasonable effort. I also experimented with parts of the body where the distortion of the child nodes was so severe that I couldn’t easily compensate for them. But you can also think of a few other options. For example, we can change the colors of the skin, eyes and hair. Other clothing is also desirable, but probably not easily interchangeable, as it is currently an integral part of our player body. But for now, that should suffice for character individualization.
And with that I want to say goodbye for today. Until next time - then we want to create a smooth transition between the Overworld and the mini games by taking our “GameGuy” handheld out of our pocket and starting a game on it.
Do you prefer to read this diary in the developer's mother tongue? Then click here to read this diary entry in the original German language!