Accessing Scriptable Objects
Learn how to access Game Creator Scriptable Objects like weapons, ammo and melee weapons.
The documentation has moved to: https://mitschmr-studios.io/documentation/api-guides/accessscriptableobjects.html
This version will no longer be updated and maintained.
In this tutorial, I want to show you how you can access scriptable objects like weapons and ammo by using HookPlayer and Inventory i.e. to compare the stats of a weapon.
- Install Unity
- Install IDE (I use Visual Studio 2019)
- Import Game Creator
- Import and enable the Inventory module
- Import and enable the Shooter module
- Import and enable the Melee module
Note: You don't need to buy a module if you don't use it. If you only use melee weapons, then you don't need the shooter module and vice versa. I have both on the list for the tutorial only.
Note 2: I assume that when you equip a weapon (melee or shooter, doesn't matter) in the inventory, you also draw the weapon. If you are not using the inventory module, I have prepared a case without it. Case #2
The shooter module consists of mainly three parts:
To learn more about each part, I recommend to read the official documentation. I only briefly cover the basics of each part.
From the official documentation:
Weapons are scriptable objects that allow to configure how a weapon looks like, how to hold it, as well as link it to a particular Ammo object.
From the official documentation:
Ammunition (from now on Ammo) are the other objects used by the Shooter module that allow you to create any kind of weapon. Weapon objects allow you to define how the Character behaves using a certain gun, but Ammo allows to define what happens when shooting it, charging shots, how the aiming is done, etc...
So that a character or the player knows which weapon he is holding right now, he needs to have a component attached. PlayerShooter for the player and CharacterShooter for a character.

The melee module consists of mainly three parts:
- The Interaction component (undocumented, similar to the Shooter Interaction component)
From the official documentation:
The Weapon asset represents the definition of a specific weapon of your game. From a simple Steel Sword to a Fire spellbound Battle Axe.
From the official documentation:
Shield assets complement Weapon assets and provide a way to block incoming attacks, as well as determine how much pressure the wielder can withstand.
From the official documentation:
Melee Clips are the essential part of the Melee module. You can think them as animation clips in steroids, where you can not only define what animation will be played, but also what effects this animation has, when these happen and how this affects the character and enemies behavior.
So that a character or the player knows which weapon he is holding right now, he needs to have a component attached. This is the CharacterMelee component for both a character and the player.

Comparing the statistics of different weapons is a normal use case in any shooter game. For this example I use the weapon comparing feature in the game I develop, Defnite. My system looks like this:

You have the currently selected weapon on the left side and the currently equipped weapon on the right.
In order to compare the stats of the weapons, I needed to extend my inventory with a field for my weapon (type
Weapon
) and add a weapon asset to it. To learn how to extend the inventory, follow this guide: Inventory Custom Entries 
In my inventory UI prefab, I made two sections (one for the selected and one for the equipped weapon) and added several text gameobjects to hold the values of each weapon stat I want to compare. The next thing I did was to add a script to the top gameobject that contains all the UI elements for my equipped weapon. The script has public references to each comparable element.

In order to get access to these statistics, I need to first get a reference of my equipped weapon item:
public void GetRifleDetails()
{
Item equippedRifle = InventoryManager.Instance.GetEquip(HookPlayer.Instance.gameObject, 0);
SetRifleDetails(equippedRifle);
}
The method
GetEquip()
accesses the PlayerEquipment
component of the specified gameobject and searches for equipped items of a specified type. In my case, it reads the inventory of my player and searches for equipped items of type Rifles. The method
GetRifleDetails()
gets called when I open the inventory or equip another weapon. Now that we have a reference to our currently equipped weapon item, how do we get access to the weapon item stats? Well, we access the newly added
weapon
field and now we can get every stat we want. private void SetRifleDetails(Item target)
{
rifleName.text = target.itemName.GetText();
rifleImage.sprite = target.sprite;
rifleRecoil.text = "Recoil: " + target.weapon.defaultAmmo.recoil.ToString();
rifleFireRate.text = "Fire Rate: " + target.weapon.defaultAmmo.fireRate.ToString();
rifleClipSize.text = "Clip Size: " + target.weapon.defaultAmmo.clipSize.ToString();
rifleFocusTime.text = "Focus Time: " + target.weapon.defaultAmmo.crosshairFocusTime.ToString();
rifleAccuracy.text = "Accuracy: " + target.weapon.defaultAmmo.maxSpread.ToString();
rifleVelocity.text = "Velocity: " + target.weapon.defaultAmmo.projectileVelocity.ToString();
}
Note:
rifleName
, rifleImage
etc. are the variables for the UI elements. To get the stats of a selected weapon, we need to add a script to the inventory item prefab (i.e. ItemRPG). Because the script is not aware of the inventory UI (seperate prefabs, not in the scene) we can't reference the UI elements easily. What we need to do is find them by using
GameObject.Find()
. This approach is slower than the above one, but it doesn't have a big impact on performance because we aren't using it all the time. Let's have a look at some examples: void OnEnable()
{
itemName = GameObject.Find("WeaponSelectedName").GetComponent<TextMeshProUGUI>();
itemImage = GameObject.Find("WeaponSelectedImage").GetComponent<Image>();
<...>
}
GameObject.Find()
searches the hierarchy for a gameobject with a certain name. In the end this is the same as using public TextMeshProUGUI itemName;
and dragging the gameobject with the TextMesh component on it. In order to get the stats of the selected weapon, we need to do the following:
public void GetItemDetails()
{
weaponItem = gameObject.GetComponent<ItemUI>().itemObject;
SetRifleDetails(weaponItem);
}
private void SetRifleDetails(Item target)
{
itemName.text = target.itemName.GetText();
itemImage.sprite = target.sprite;
weaponRecoil.text = "Recoil: " + target.weapon.defaultAmmo.recoil.ToString();
weaponFireRate.text = "Fire Rate: " + target.weapon.defaultAmmo.fireRate.ToString();
weaponClipSize.text = "Clip Size: " + target.weapon.defaultAmmo.clipSize.ToString();
weaponFocusTime.text = "Focus Time: " + target.weapon.defaultAmmo.crosshairFocusTime.ToString();
weaponAccuracy.text = "Accuracy: " + target.weapon.defaultAmmo.maxSpread.ToString();
weaponVelocity.text = "Velocity: " + target.weapon.defaultAmmo.projectileVelocity.ToString();
}
The method
GetItemDetails()
needs to be called whenever I click on an item. 
The item prefab has a component on it called
ItemUI
which holds a reference to the item in the database. By using .itemObject
, we get a reference to this item and can now access the weapon values. Finally the stats are written to the UI elements. In order to get the weapon stats without using the inventory module, we need to access the
PlayerShooter
component (for the player) or the CharacterShooter
(for characters). void GetWeaponDetails()
{
Weapon playerWeapon = HookPlayer.Instance.GetComponent<PlayerShooter>();
Debug.Log(playerWeapon.weaponName);
Debug.Log(playerWeapon.defaultAmmo.recoil.ToString());
}
To get the stats of a melee weapon, you can do the same approaches I showed above for the shooter module. The only things you need to change are the types of the objects and the stats you are looking for.
Add a field of type
MeleeWeapon
to your item in the item catalogue the same way you add custom entries to it. Drag and drop a melee weapon asset on it to get a reference to this weapon. You can then simply access the melee weapon: meleeWeaponName.text = target.meleeWeapon.weaponName.GetText();
meleeWeaponImage.sprite = target.sprite;
meleeWeaponName.text = "Name: " + target.meleeWeapon.weaponName.GetText();
Get a reference to the
CharacterMelee
component and you are good to go: void GetWeaponDetails()
{
CharacterMelee playerMelee = HookPlayer.Instance.GetComponent<CharacterMelee>();
Debug.Log(playerMelee.currentWeapon.weaponName.GetText());
}