17 min read

One of the key features of an RPG is to be able to customize your character player. In this article by Vahe Karamian, author of the book Building an RPG with Unity 5.x, we will take a look at how we can provide a means to achieve this.

(For more resources related to this topic, see here.)

Once again, the approach and concept are universal, but the actual implementation might be a little different based on your model structure.

Create a new scene and name it Character Customization. Create a Cube prefab and set it to the origin. Change theScaleof the cube to<5, 0.1, 5>, you can also change the name of the GameObject to Base. This will be the platform that our character model stands on while the player customizes his/her character before game play. Drag and drop thefbxfile representing your character model into theScene View. The next few steps will entirely depend on your model hierarchy and structure as designed by the modeller. To illustrate the point, I have placed the same model in the scene twice. The one on the left is the model that has been configured to display only the basics, the model on the right is the model in its original state as shown in the figure below:

Notice that this particular model I am using has everything attached. These include the different types of weapons, shoes, helmets, and armour. The instantiated prefab on the left hand side has turned off all of the extras from the GameObject’s hierarchy. Here is how the hierarchy looks in the Hierarchy View:

The model has a veryextensivehierarchy in its structure, the figure above is a small snippet to demonstrate that you will need to navigate the structure and manually identify and enable or disable the mesh representing a particular part of the model.

Customizable Parts

Based on my model, I cancustomizea few things on my 3D model. I can customize the shoulder pads, I can customize the body type, I can customize the weapons and armor it has, I can customize the helmet and shoes, and finally I can also customize the skin texture to give it different looks. Let’s get a listing of all the different customizable items we have for our character:

  • Shoulder Shields:there are four types
  • Body Type:there are three body types; skinny, buff, and chubby
  • Armor:knee pad, leg plate
  • Shields:there are two types of shields
  • Boots:there are two types of boots
  • Helmet:there are four types of helmets
  • Weapons:there are 13 different types of weapons
  • Skins:there are 13 different types of skins

User Interface

Now that we know what ouroptionsare for customizing our player character, we can start thinking about the User Interface (UI) that will be used to enable the customization of the character. To design our UI, we will need to create aCanvasGameObject, this is done by right-clicking in theHierarchy Viewand selectingCreate|UI|Canvas. This will place aCanvasGameObject and anEventSystemGameObject in theHierarchy View.

It is assumed that you already know how to create a UI in Unity. I am going to use a Panel togroupthe customizable items. For the moment I will be using checkboxes for some items and scroll bars for the weapons and skin texture. The following figure will illustrate how my UI for customization looks:

These UI elements will need to be integrated with Event Handlers that will perform the necessary actions for enabling or disabling certain parts of the character model. For instance, using the UI I can select Shoulder Pad 4, Buff Body Type, move the scroll bar until the Hammer weapon shows up, selecting the second Helmet checkbox, selecting Shield 1 and Boot 2, my character will look like the figure below.We need a way to refer to each one of the meshes representing the different types of customizable objects on the model. This will be done through a C# script. The script will need to keep track of all the parts we are going to be managing for customization.

Some models will not have the extra meshes attached. You can always create empty GameObjects at a particular location on the model, and you can dynamically instantiate the prefab representing your custom object at the given point. This can also be done for our current model, for instance, if we have a special space weapon that somehow gets dropped by the aliens in the game world, we can attach the weapon to our model through C# code. The important thing is to understand the concept, and the rest is up to you!

The Code for Character Customization

Things don’t happen automatically. So we need to create some C# code that will handle the customization of our character model. The script we create here will handle the UI events that will drive the enabling and disabling of different parts of the model mesh. Create a new C# script and call itCharacterCustomization.cs. This script will be attached to theBaseGameObject in the scene. Here is a listing of the script:

using UnityEngine; 
using UnityEngine.UI; 
using System.Collections; 
using UnityEngine.SceneManagement; 
 
public class CharacterCustomization : MonoBehaviour 
{ 
 
   public GameObject PLAYER_CHARACTER; 
 
   public Material[] PLAYER_SKIN; 
 
   public GameObject CLOTH_01LOD0; 
   public GameObject CLOTH_01LOD0_SKIN; 
   public GameObject CLOTH_02LOD0; 
   public GameObject CLOTH_02LOD0_SKIN; 
   public GameObject CLOTH_03LOD0; 
   public GameObject CLOTH_03LOD0_SKIN; 
   public GameObject CLOTH_03LOD0_FAT; 
 
   public GameObject BELT_LOD0; 
 
   public GameObject SKN_LOD0; 
   public GameObject FAT_LOD0; 
   public GameObject RGL_LOD0; 
 
   public GameObject HAIR_LOD0; 
 
   public GameObject BOW_LOD0; 
 
   // Head Equipment 
   public GameObject GLADIATOR_01LOD0; 
   public GameObject HELMET_01LOD0; 
   public GameObject HELMET_02LOD0; 
   public GameObject HELMET_03LOD0; 
   public GameObject HELMET_04LOD0; 
 
   // Shoulder Pad - Right Arm / Left Arm 
   public GameObject SHOULDER_PAD_R_01LOD0; 
   public GameObject SHOULDER_PAD_R_02LOD0; 
   public GameObject SHOULDER_PAD_R_03LOD0; 
   public GameObject SHOULDER_PAD_R_04LOD0; 
 
   public GameObject SHOULDER_PAD_L_01LOD0; 
   public GameObject SHOULDER_PAD_L_02LOD0; 
   public GameObject SHOULDER_PAD_L_03LOD0; 
   public GameObject SHOULDER_PAD_L_04LOD0; 
 
   // Fore Arm - Right / Left Plates 
   public GameObject ARM_PLATE_R_1LOD0; 
   public GameObject ARM_PLATE_R_2LOD0; 
 
   public GameObject ARM_PLATE_L_1LOD0; 
   public GameObject ARM_PLATE_L_2LOD0; 
 
   // Player Character Weapons 
   public GameObject AXE_01LOD0; 
   public GameObject AXE_02LOD0; 
   public GameObject CLUB_01LOD0; 
   public GameObject CLUB_02LOD0; 
   public GameObject FALCHION_LOD0; 
   public GameObject GLADIUS_LOD0; 
   public GameObject MACE_LOD0; 
   public GameObject MAUL_LOD0; 
   public GameObject SCIMITAR_LOD0; 
   public GameObject SPEAR_LOD0; 
   public GameObject SWORD_BASTARD_LOD0; 
   public GameObject SWORD_BOARD_01LOD0; 
   public GameObject SWORD_SHORT_LOD0; 
 
   // Player Character Defense Weapons 
   public GameObject SHIELD_01LOD0; 
   public GameObject SHIELD_02LOD0; 
 
   public GameObject QUIVER_LOD0; 
   public GameObject BOW_01_LOD0; 
 
   // Player Character Calf - Right / Left 
   public GameObject KNEE_PAD_R_LOD0; 
   public GameObject LEG_PLATE_R_LOD0; 
 
   public GameObject KNEE_PAD_L_LOD0; 
   public GameObject LEG_PLATE_L_LOD0; 
 
   public GameObject BOOT_01LOD0; 
   public GameObject BOOT_02LOD0; 
 
   // Use this for initialization 
   void Start() 
   { 
 
   } 
 
   public bool ROTATE_MODEL = false; 
   // Update is called once per frame 
   void Update() 
   { 
      if (Input.GetKeyUp(KeyCode.R)) 
      { 
         this.ROTATE_MODEL = !this.ROTATE_MODEL; 
      } 
 
      if (this.ROTATE_MODEL) 
      { 
         this.PLAYER_CHARACTER.transform.Rotate(new Vector3(0, 1, 0), 33.0f * Time.deltaTime); 
      } 
 
      if (Input.GetKeyUp(KeyCode.L)) 
      { 
 
         Debug.Log(PlayerPrefs.GetString("NAME")); 
      } 
 
   } 
 
 
   public void SetShoulderPad(Toggle id) 
   { 
      switch (id.name) 
      { 
         case "SP-01": 
            { 
               this.SHOULDER_PAD_R_01LOD0.SetActive(id.isOn); 
               this.SHOULDER_PAD_R_02LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_03LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_04LOD0.SetActive(false); 
 
               this.SHOULDER_PAD_L_01LOD0.SetActive(id.isOn); 
               this.SHOULDER_PAD_L_02LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_03LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_04LOD0.SetActive(false); 
 
               PlayerPrefs.SetInt("SP-01", 1); 
               PlayerPrefs.SetInt("SP-02", 0); 
               PlayerPrefs.SetInt("SP-03", 0); 
               PlayerPrefs.SetInt("SP-04", 0); 
               break; 
            } 
         case "SP-02": 
            { 
               this.SHOULDER_PAD_R_01LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_02LOD0.SetActive(id.isOn); 
               this.SHOULDER_PAD_R_03LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_04LOD0.SetActive(false); 
 
               this.SHOULDER_PAD_L_01LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_02LOD0.SetActive(id.isOn); 
               this.SHOULDER_PAD_L_03LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_04LOD0.SetActive(false); 
 
               PlayerPrefs.SetInt("SP-01", 0); 
               PlayerPrefs.SetInt("SP-02", 1); 
               PlayerPrefs.SetInt("SP-03", 0); 
               PlayerPrefs.SetInt("SP-04", 0); 
               break; 
            } 
         case "SP-03": 
            { 
               this.SHOULDER_PAD_R_01LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_02LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_03LOD0.SetActive(id.isOn); 
               this.SHOULDER_PAD_R_04LOD0.SetActive(false); 
 
               this.SHOULDER_PAD_L_01LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_02LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_03LOD0.SetActive(id.isOn); 
               this.SHOULDER_PAD_L_04LOD0.SetActive(false); 
 
               PlayerPrefs.SetInt("SP-01", 0); 
               PlayerPrefs.SetInt("SP-02", 0); 
               PlayerPrefs.SetInt("SP-03", 1); 
               PlayerPrefs.SetInt("SP-04", 0); 
               break; 
            } 
         case "SP-04": 
            { 
               this.SHOULDER_PAD_R_01LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_02LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_03LOD0.SetActive(false); 
               this.SHOULDER_PAD_R_04LOD0.SetActive(id.isOn); 
 
               this.SHOULDER_PAD_L_01LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_02LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_03LOD0.SetActive(false); 
               this.SHOULDER_PAD_L_04LOD0.SetActive(id.isOn); 
 
               PlayerPrefs.SetInt("SP-01", 0); 
               PlayerPrefs.SetInt("SP-02", 0); 
               PlayerPrefs.SetInt("SP-03", 0); 
               PlayerPrefs.SetInt("SP-04", 1); 
 
               break; 
            } 
      } 
   } 
 
   public void SetBodyType(Toggle id) 
   { 
      switch (id.name) 
      { 
         case "BT-01": 
            { 
               this.RGL_LOD0.SetActive(id.isOn); 
               this.FAT_LOD0.SetActive(false); 
               break; 
            } 
         case "BT-02": 
            { 
               this.RGL_LOD0.SetActive(false); 
               this.FAT_LOD0.SetActive(id.isOn); 
               break; 
            } 
      } 
   } 
 
   public void SetKneePad(Toggle id) 
   { 
      this.KNEE_PAD_R_LOD0.SetActive(id.isOn); 
      this.KNEE_PAD_L_LOD0.SetActive(id.isOn); 
   } 
 
   public void SetLegPlate(Toggle id) 
   { 
      this.LEG_PLATE_R_LOD0.SetActive(id.isOn); 
      this.LEG_PLATE_L_LOD0.SetActive(id.isOn); 
   } 
 
   public void SetWeaponType(Slider id) 
   { 
      switch (System.Convert.ToInt32(id.value)) 
      { 
         case 0: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 1: 
            { 
               this.AXE_01LOD0.SetActive(true); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 2: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(true); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 3: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(true); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 4: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(true); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 5: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(true); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 6: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(true); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 7: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(true); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 8: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(true); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 9: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(true); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 10: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(true); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 11: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(true); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 12: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(true); 
               this.SWORD_SHORT_LOD0.SetActive(false); 
               break; 
            } 
         case 13: 
            { 
               this.AXE_01LOD0.SetActive(false); 
               this.AXE_02LOD0.SetActive(false); 
               this.CLUB_01LOD0.SetActive(false); 
               this.CLUB_02LOD0.SetActive(false); 
               this.FALCHION_LOD0.SetActive(false); 
               this.GLADIUS_LOD0.SetActive(false); 
               this.MACE_LOD0.SetActive(false); 
               this.MAUL_LOD0.SetActive(false); 
               this.SCIMITAR_LOD0.SetActive(false); 
               this.SPEAR_LOD0.SetActive(false); 
               this.SWORD_BASTARD_LOD0.SetActive(false); 
               this.SWORD_BOARD_01LOD0.SetActive(false); 
               this.SWORD_SHORT_LOD0.SetActive(true); 
               break; 
            } 
 
      } 
   } 
 
   public void SetHelmetType(Toggle id) 
   { 
      switch (id.name) 
      { 
         case "HL-01": 
            { 
               this.HELMET_01LOD0.SetActive(id.isOn); 
               this.HELMET_02LOD0.SetActive(false); 
               this.HELMET_03LOD0.SetActive(false); 
               this.HELMET_04LOD0.SetActive(false); 
               break; 
            } 
         case "HL-02": 
            { 
               this.HELMET_01LOD0.SetActive(false); 
               this.HELMET_02LOD0.SetActive(id.isOn); 
               this.HELMET_03LOD0.SetActive(false); 
               this.HELMET_04LOD0.SetActive(false); 
               break; 
            } 
         case "HL-03": 
            { 
               this.HELMET_01LOD0.SetActive(false); 
               this.HELMET_02LOD0.SetActive(false); 
               this.HELMET_03LOD0.SetActive(id.isOn); 
               this.HELMET_04LOD0.SetActive(false); 
               break; 
            } 
         case "HL-04": 
            { 
               this.HELMET_01LOD0.SetActive(false); 
               this.HELMET_02LOD0.SetActive(false); 
               this.HELMET_03LOD0.SetActive(false); 
               this.HELMET_04LOD0.SetActive(id.isOn); 
               break; 
            } 
      } 
   } 
 
   public void SetShieldType(Toggle id) 
   { 
      switch (id.name) 
      { 
         case "SL-01": 
            { 
               this.SHIELD_01LOD0.SetActive(id.isOn); 
               this.SHIELD_02LOD0.SetActive(false); 
               break; 
            } 
         case "SL-02": 
            { 
               this.SHIELD_01LOD0.SetActive(false); 
               this.SHIELD_02LOD0.SetActive(id.isOn); 
               break; 
            } 
      } 
   } 
 
   public void SetSkinType(Slider id) 
   { 
      this.SKN_LOD0.GetComponent<Renderer>().material = this.PLAYER_SKIN[System.Convert.ToInt32(id.value)]; 
      this.FAT_LOD0.GetComponent<Renderer>().material = this.PLAYER_SKIN[System.Convert.ToInt32(id.value)]; 
      this.RGL_LOD0.GetComponent<Renderer>().material = this.PLAYER_SKIN[System.Convert.ToInt32(id.value)]; 
   } 
 
   public void SetBootType(Toggle id) 
   { 
      switch (id.name) 
      { 
         case "BT-01": 
            { 
               this.BOOT_01LOD0.SetActive(id.isOn); 
               this.BOOT_02LOD0.SetActive(false); 
               break; 
            } 
         case "BT-02": 
            { 
               this.BOOT_01LOD0.SetActive(false); 
               this.BOOT_02LOD0.SetActive(id.isOn); 
               break; 
            } 
      } 
   } 
} 

This is a long script but it is straightforward. At the top of the script we have defined all of the variables that will be referencing the different meshes in our model character. All variables are of type GameObject with the exception of thePLAYER_SKINvariable which is an array ofMaterialdata type. The array is used to store the different types of texture created for the character model. There are a few functions defined that are called by the UI event handler. These functions are:SetShoulderPad(Toggle id); SetBodyType(Toggle id); SetKneePad(Toggle id); SetLegPlate(Toggle id); SetWeaponType(Slider id); SetHelmetType(Toggle id); SetShieldType(Toggle id); SetSkinType(Slider id);All of the functions take a parameter that identifies which specific type is should enable or disable. A BIG NOTE HERE! You can also use the system we just built to create all of the different variations of your Non-Character Player models and store them as prefabs! Wow! This will save you so much time and effort in creating your characters representing different barbarians!!!

Preserving Our Character State

Now that we have spent the time to customize our character, we need to preserve our character and use it in our game. In Unity, there is a function calledDontDestroyOnLoad(). This is a great function that can be utilized at this time. What does it do? It keeps the specified GameObject in memory going from one scene to the next. We can use these mechanisms for now, eventually though, you will want to create a system that can save and load your user data. Go ahead and create a new C# script and call itDoNotDestroy.cs. This script is going to be very simple. Here is the listing:

using UnityEngine; 
using System.Collections; 
 
public class DoNotDestroy : MonoBehaviour 
{ 
 
   // Use this for initialization 
   void Start() 
   { 
      DontDestroyOnLoad(this); 
   } 
 
   // Update is called once per frame 
   void Update() 
   { 
 
   } 
} 

After you create the script go ahead and attach it to your character model prefab in the scene. Not bad, let’s do a quick recap of what we have done so far.

Recap

By now you should have three scenes that are functional. We have our scene that represents the main menu, we have our scene that represents our initial level, and we just created a scene that is used for character customization. Here is the flow of our game thus far:

We start the game, see the main menu, select theStart Gamebutton to enter the character customization scene, do our customization, and when we click theSavebutton we loadlevel 1. For this to work, we have created the following C# scripts:

  • GameMaster.cs:used as the main script to keep track of our game state
  • CharacterCustomization.cs:used exclusively for customizing our character
  • DoNotDestroy.cs:used to save the state of a given object
  • CharacterController.cs:used to control the motion of our character
  • IKHandle.cs:used to implement inverse kinematics for the foot

When you combine all of this together you now have a good framework and flow that can be extended and improved as we go along.

Summary

We covered some very important topics and concepts in the article that can be used and enhanced for your games. We started the article by looking into how to customize your player character. The concepts you take away from the article can be applied to a wide variety of scenarios. We look at how to understand the structure of your character model so that you can better determine the customization methods. These are the different types of weapons, clothing, armour, shields and so on… We then looked at how to create a user interface to help enable us with the customization of our player character during gameplay. We also learned that the tool we developed can be used to quickly create several different character models (customized) and store them as Prefabs for later use! Great time saver!!! We also learned how to preserve the state of our player character after customization for gameplay. You should now have an idea of how to approach your project.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here