Wednesday 17 August 2016

Zelda Style Life System Unity Tutorial – Part 3 of 10

Zelda Style Life System Unity Tutorial – Part 3 of 10



The end result of the full tutorial.

At the end of Part 3 we will have produced this (See image 1.0).
Image 1.0


Before you start you should know these things:

You should have gone through and completed ‘Part 2’ of this tutorial before going any further. If you find yourself not understanding some of the terminology or code of the tutorial I would also recommend going through the previous tutorial to get up to speed. I will leave a link to it below to go through at your leisure.




If you follow this tutorial and find I am moving too fast or if you don’t know the things in the list above, I would recommend getting up to speed and then come back to this tutorial when you are ready.


Links to Parts 1 - 10 of this tutorial series:

Part 1

Part 2

Part 4

Part 5

Part 6

Part 7

Part 8

Part 9


Part 10



With this tutorial if you want to convert this into JavaScript by all means do so but it may be easier for you to follow this in C# and stick with the language of the tutorial to make it easier.

PROJECT RESOURCES: At the bottom of the post there is a download link to a zip file. This files includes all files needed to follow Part 3 and the completed project file of Part 3.

This tutorial is split up into several parts. In this part we will continue working on completing the foundations:

  • Resize the width and height of the ‘lifeImg’ game object using the variables from Part 1 
  • Lean how to manipulate the RectTransform component variables of the ‘lifeImg’ object 
  • Lean how to use the Group Layout component for multiple UI objects 
  • Effect one variable of multiple UI elements easily using the Group Layout component 
Step 1: - Resizing the image width and height using ‘sizeDelta’

In this step we will learn to work with the RectTransform of the ‘
lifeImg’ prefab. At the moment when the ‘lifeImg’ is instantiated during runtime, it is spawned at a scale factor of one on all three axis. It also has the same width and height as the one in their prefab folder. This is typical and how we normally want prefabs to behave.

However in our case depending the resolution of the player’s screen and how large we want the instantiated object to be we want it to cover a different amount of the screen. The UI image you may want to use may be bigger or smaller or the resolution could be lower and you may want it to maintain visual integrity or prevent the image from looking squashed or over lap another image. Maybe you need it to cover more or less of the screen to make it more visible.

Now in order for us to do this we need to do a few things. We need to access the width and height of the ‘
lifeImg’ RectTransform as Vector2 variables. Then we need to set them to ‘lifeImgWidth’ for the width and ‘lifeImgHeight’ for the height of the image. In order to do this we need to access the ‘rectTransform’ of the ‘Image’ game object, but here is the thing, we cannot directly access the height and width variables of the component through code. This is mostly because it’s stored as a Vector2 variable. We need to set both the width and height at once. In order to set the width and height we set them through accessing the ‘rectTransform’ class of the image object the accessing the ‘sizeDelta’ Vector2 variable of it. When we set the ‘sizeDelta’ to a new Vector2 we set the ‘X’ or axis or width to ‘lifeImgWidth’ and the ‘Y’ axis or height to ‘lifeImgHeight’.


Code:

void Start ()
{
    GetScreenDimentions();
    SetImageSize();
    Image tempImg = Instantiate(lifeImg, 

                                transform.position, 
                                transform.rotation) as Image;
    tempImg.transform.parent = transform;
    tempImg.rectTransform.sizeDelta = new 
Vector2(lifeImgWidth, 
                                                  lifeImgHeight);
}


You might be thinking what is a '
sizeDelta'? Well it is the size the the UI element relative to the distances between it’s anchors. (See figure 1.0)



Figure 1.0

Now we press Play. (See figure 1.1)




Figure 1.1

This is the result. It’s not a bad start. However when we add more ‘
lifeImg’ UI elements to the canvas we need to make sure each one is the correct width and height. Each time we create a new ‘lifeImg’ we could just set the sizeDelta ourselves along with Instantiating it but this would involve more code than required, there is an easier way to it. Now your thinking ‘why haven’t put this in it’s own function yet and put the ‘sizeDelta’ in there?’. We will do this in a later, but at the moment it’s not necessary. Also the method for it will get quite complex later on as we add more functionality and we want our code to be easy to read and do one specific task.

In the next set we will automate this task using the Group Layout component.



Step 2: - Resizing the width and height using the Group Layout component manually

In this step we will cover how to use the Group Layout component to automatically resize would UI image elements.

The Group Layout component is a simple yet powerful component. It can be used to automatically space out UI elements in the editor or Play mode. It can also be used to automatically set size of a new UI element without having to write any extra code each time you create a new UI element. You can set the width and height of an item once in the inspector panel or code when you need to and all children of said object are uniformly resized automatically.

We will cover the rest of it’s functionality later, for now this is all you need to know.

Making sure the LifeSystemManager is highlighted, in the inspector add a GridLayoutGroup component to it. Now if we enter Play mode, not much will happen apart from the ‘lifeImg’ will slightly change position so all of it in view and not out of the screen. There are also about five pixels between the top of it and the top edge of the screen, same thing for the left edge. This can also be done if you change the padding properties manually. (See figure 1.2)



Figure 1.2

With the GridLayoutGroup it normally makes UI elements are with in a UI panel (if there is one). If not it makes sure things are spaced nearly on screen, it’s quite smart.

Note: You can’t change any part of the RectTransform of the child elements the GridLayoutGroup is attached to (It actively greys it out so you physically can’t do it). This is because the GridLayoutGroup takes care of these properties for us automatically, also they adopt the same anchoring as their parent UI element.

We can keep it’s setting more of less as they are for now. What we need to do it look at the ‘Cell Size’ variable. Every item that that is a child of ‘LifeSystemManager’ is treated as a cell. So if we dynamically create a new image as a child, the GridLayoutGroup will automatically take care of all the settings, such as the X and Y pixels (width and height of the cells). If we want to we can take care of this by hand. Go to the inspector and change the ‘Cell Size’ properties to any number to want and press Play. (See figure 1.3)


Figure 1.3. I have set the properties to X: 50, Y:50.



This is OK if everything will stay at a consistent size but we want this to adjust to our screen resolution automatically. For this we need to go back to our code and change some things.



Step 3: - Resizing the Cell Size Dynamically using the Grid Layout Group component

We need to go back to our code and rewrite a few lines. First we need to create a private variable of type ‘
GridLayoutGroup’ and called it ‘gridLayoutGroup’ just under our ‘lifeImg’ variable.


Code:

public Image lifeImg;

private GridLayoutGroup gridLayoutGroup;



We do this to store it locally in case we need to access it’s properties later on.

Then we create a method called ‘ResetGridLayoutProperties’. When we are done we reference it in the Start method just before the Image is instantiate since it will rely on those properties.

In the ‘ResetGridLayoutProperties’ method we first need to assign it the GridLayoutGroup component attached to the ‘gameObject’ using ‘GetComponent’. We do this so it has local access to it’s properties.

Then we access the ‘
cellSize’ property of the gridLayoutGroup variable and assign it a new Vector2 value using the ‘lifeImgWidth’ and ‘lifeImgHeight’ for the ‘X’ and ‘Y’ properties respectively.


Code:

void Start ()
{
  GetScreenDimentions();
  SetImageSize();
  ResetGridLayoutProperties();
  Image tempImg = Instantiate(lifeImg,
                              transform.position, 

                              transform.rotation) as Image;
  tempImg.transform.parent = transform;
}

void ResetGridLayoutProperties()
{
  gridLayoutGroup = GetComponent<GridLayoutGroup>();
  gridLayoutGroup.cellSize = new Vector2(lifeImgWidth, 

                                         lifeImgHeight);
}



Let the code compile and enter play mode and see what happens. (See figure 1.4)




Figure 1.4

If you change the screen resolution the image will change size. If you do not have ‘Maximise On Play’ enabled you can see the values change once on the first frame you enter play mode.

Great, part three is finished. We have laid down even more foundations, made our code a bit easier to read, more modular and made our job for Part 4 easier.

We have learnt how to:

  • Resize an image using the sizeDelta function of the RecTransform component class
  • Use GetComponent to store a Script or MonoBehavior locally
  • Access and set variables of said script via the local variable
  • How the GridLayoutGroup effects the RectTransform of child UI elements
  • Set size of an image automatically sing the GridLayoutGroup component

In Part 4 we will make our code more modular. Not just that. We will learn more about the Grid Layout Group component and how we can use it to:

  • Create a row of UI elements on the screen (our ‘lifeImg’ game object)
  • Create new UI images on demand
  • Destroy the last created UI element on demand

Click here for Part 4.


If you liked this tutorial leave a comment below telling me why you like it and share it with a friend who will find it useful. If you didn’t like it, please leave a comment below saying why.

If you would would like to see more of these tutorials, please leave a comment below. And if you want more of this particular tutorial say what you want to see more of in the comments.



Download resources and project files.

No comments:

Post a Comment