Unity allows developers to use property attributes to modify how a class instance looks within the inspector. Here are some of them and how they work.
[Header("Some Header")]
Header allows you to title a set of variables so if you had a string for the characters name and a string for their description you can place a header attribute above them to signal to anyone that those variables are specifically for a character's description, then use another header attribute for the character's movement stats.
[Tooltip("Some Tip")]
Tooltip allows you to display a tip within the inspector to help explain any variable viewed in the inspector. This is especially useful if the naming of the variable is confusing or could possibly be confused with another variable.
[ContextMenu("Some Menu Name")]
Context Menu allows you to call a function defined within the class from the inspector and can be used to check the functionality of a function without going into play mode in the editor. This attribute is placed above the function that would be called. An example of this would be a TakeDamage() function that in game would be called if the player/character gets hit. Adding a context menu attribute allows that TakeDamage function to be visible in the inspector and allows you to check that the function works as expected due to being able to see the characters health decreasing when called.
[Multiline]
The multiline attribute modifies the text field of a string to be a text area instead, providing more room to write and as the name suggests use multiple lines. This attribute is useful for things such as character/level descriptions.
[Range(min, max)]
The range attribute creates a slider for the variable attached to and requires a min value and a max value. An example use of this would be for a damage per second variable, where you can adjust that value using the slider instead of typing a value in.
[ContextMenuItem("Some Menu Item Name", "Some Function Name")]
Context Menu Item works similar to the context menu attribute but is specific to a variable aka the one below said attribute. This will then call a specified function when clicked on within the inspector. An example of this would be a characters health, which has a context menu item that calls the TakeDamage function from earlier. Another could be added that can then be used to call a GainHealth function, which gives the character more health.
[CreateAssetMenu(fileName = "Some File Name", menuName = "Some Menu Name", order = Some Number]
Create Asset Menu is particularly useful when creating scriptable object classes. This attribute allows you to create a scriptable object file within the project view. This attribute goes above the class definition.
For Example:
[CreateAssetMenu(fileName = "Gun Stats", menuName = "ScriptableObject/Guns/Stats", order = 1]
public class GunStats : ScriptableObject
{
public float reloadRate;
}
[Space]
The space attribute added a gap between two variables being displayed within the unity inspector.
Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts
Thursday, May 9, 2019
Wednesday, April 17, 2019
Unity C#: Dictionaries
A dictionary is similar to a list but with a few advantages and a disadvantages, where the dictionary is not displayed in the editors inspector windows (although this can be overcome through Unity packages like the Odin Inspector or by writing your own custom inspector). A dictionary is a list of pairs, where each pair is made up of a key and a value. This is where the dictionary becomes faster than a list. In order to find a value within a list, you have to loop through all of the elements. However with a dictionary, you just give it the key that is associated with the value you want.
[System.Serializable]
public class Item()
{
string name;
ItemType itemType;
int itemId;
string itemDescription
}
public class TestClass : MonoBehaviour
{
// Defining a dictionary
private Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>();
private void Start()
{
// Create new item
Item shield = new Item();
shield.name = "Shield";
shield.itemType = ItemType.Shield;
shield.itemId = 0;
shield.itemDescription = "Something to block attacks with";
// Add the first item to our dictionary
itemDictionary.Add(0, shield);
// Access the first item and display the name of the item in the console log
Debug.Log("First Item: " + itemDictionary[0].name);
}
}
Adding values to a dictionary is similar to a list but with one minor change, you have to provide a key with the value that you want to add. Accessing an value is also similar to a list but instead of using an index, you use the key associated with the value you want.
[System.Serializable]
public class Item()
{
string name;
ItemType itemType;
int itemId;
string itemDescription
}
public class TestClass : MonoBehaviour
{
// Defining a dictionary
private Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>();
private void Start()
{
// Create new item
Item shield = new Item();
shield.name = "Shield";
shield.itemType = ItemType.Shield;
shield.itemId = 0;
shield.itemDescription = "Something to block attacks with";
// Add the first item to our dictionary
itemDictionary.Add(0, shield);
// Access the first item and display the name of the item in the console log
Debug.Log("First Item: " + itemDictionary[0].name);
}
}
Adding values to a dictionary is similar to a list but with one minor change, you have to provide a key with the value that you want to add. Accessing an value is also similar to a list but instead of using an index, you use the key associated with the value you want.
Looping Through A Dictionary
You can loop through a dictionary using a foreach loop, but there are three ways you can write that loop. The first being as a KeyValuePair, the second being just the keys and the third being just the values. Below are examples of all three loops.
[System.Serializable]
public class Item()
{
string name;
ItemType itemType;
int itemId;
string itemDescription
}
public class TestClass : MonoBehaviour
{
// Defining a dictionary
private Dictionary<int, Item> itemDictionary = new Dictionary<int, Item>();
private void Start()
{
// Create new item
Item shield = new Item();
shield.name = "Shield";
shield.itemType = ItemType.Shield;
shield.itemId = 0;
shield.itemDescription = "Something to block attacks with";
// Add the first item to our dictionary
itemDictionary.Add(0, shield);
// Create new item
Item sword = new Item();
sword.name = "Sword";
sword.itemType = ItemType.Sword;
sword.itemId = 1;
sword.itemDescription = "Something to attacks with";
// Add the second item to our dictionary
itemDictionary.Add(3, sword);
// Create new item
Item helmet = new Item();
helmet.name = "Helmet";
helmet.itemType = ItemType.Armour;
helmet.itemId = 2;
helmet.itemDescription = "Something to put on your head";
// Add the third item to our dictionary
itemDictionary.Add(6, helmet);
// Loop through dictionary using KeyValuePair
foreach(KeyValuePair<int, Item> entry in itemDictionary)
{
Debug.Log("Key: " + entry.key);
Debug.Log("Value: " + entry.value);
}
// Loop through dictionary using Key
foreach(int key in itemDictionary.keys)
{
Debug.Log("Key: " + key);
}
// Loop through dictionary using values
foreach(Item item in itemDictionary.values)
{
Debug.Log("Value: " + item.name);
}
}
}
Note that it is possible that all keys are not going to be sequential as demonstrated above. Also all keys should be unique, but there can be duplicate items. You can also check if a dictionary has a key by using the ContainsKey() function, this stops any exception errors due to missing keys.
Tuesday, April 16, 2019
Unity C#: Static Types
Like with most programming languages, C# has a static keyword that can be used on classes, variables and functions. By using the static keyword, that class, variable or function is available for the lifetime of the game. It's worth noting that if you create a static class, it cannot inherit from the MonoBehaviour class but also that all variables and functions must be static.
Static Members Verses Instance Members
Besides being a member that is available throughout the lifetime of a game, a static member is available to all instances of a class. Instance members on the other hand are different because they are specific to that instance of a class. For example, you have an enemy ship class, that class might have a health member. Generally this type of member would be an instance, as you would want each ship to have a unique amount of health. An example of a static member for an enemy ship class would be a shipCount, which keeps track of how many ships there currently are. With this you don't want each instance of the class to have a unique value for this member, so it would be static.
public class EnemyShip()
{
public EnemyShip()
{
shipCount++;
}
public int health;
public static int shipCount;
}
public class TestClass : MonoBehaviour
{
private void Start()
{
EnemyShip shipOne = new EnemyShip();
shipOne.health = 10;
EnemyShip shipTwo = new EnemyShip();
shipTwo.health = 5;
Debug.Log("Ship Count: " + EnemyShip.shipCount);
}
}
Static Constructor
A static constructor can be used to initialise any static members within a class. This constructor will only be called once unlike the constructors we usually use. It will also be called first before any of the instance constructors.
public class EnemyShip()
{
public EnemyShip()
{
shipCount++;
}
static EnemyShip()
{
shipGroup = "Atlas";
}
public int health;
public static int shipCount;
public static string shipGroup;
}
public class TestClass : MonoBehaviour
{
private void Start()
{
EnemyShip shipOne = new EnemyShip();
shipOne.health = 10;
EnemyShip shipTwo = new EnemyShip();
shipTwo.health = 5;
Debug.Log("Ship Count: " + EnemyShip.shipCount);
}
}
In this example the static constructor is used to set the ship's group to "Atlas", as this is static, all enemy ships will have the same ship group value and is done once before the instance constructors.
Subscribe to:
Posts (Atom)