Hierarchy and Inspector windows positions in Unity engine

For productive work in Unity we have to use many different windows. We have Scene, Hierarchy, Inspector, Game, Project, Console, Animator and the many other windows.  Some windows are used rarely for specific tasks but some windows are opened all time as they are needed for most of tasks. This windows always present on our monitors. So, how more efficiently arrange this windows on the screen?

Default Unity layout

Continue reading “Hierarchy and Inspector windows positions in Unity engine”

Examples of CanvasGroup application in Unity.

Today I would like to tell you about one component from GUI library, ignorance of which created many problems in several projects, which resulted in big code, much work, and, as a result, many errors. CanvasGroup. If you already know that such a component exists, you can get comprehensive information about it from documentation and freely apply your knowledge.

I would like to describe all settings of “CanvasGroup” in detail and with examples, so that you have a visual copy of them and can invoke it when needed.

The main purpose of “CanvasGroup” is management of group of UI elements which are below in hierarchy (“inside” CanvasGroup). These options are also applied to the “GameObject” itself which contains “CanvasGroup”component.

For example, we want to manage all elements in a window, group of buttons or group of images at once.

“CanvasGroup” settings

As you can see in the picture above, “CanvasGroup” contains only four settings which purposes you can easily guess from their names. However let’s examine them in detail:


1. Alpha.

Control of transparency of group of UI elements. Changes transparency of  both UI element on which CanvasGroup component is located, and all affiliated UI elements.

One of application variants – make group of objects translucent, without changing colour of each object:

Changing of transparency of UI elements group

Another one widely applied variant – effect of FadeOut and effect FadeIn of a window. Without CanvasGroup component, you would need to get all UI elements located in a window and to change alpha parameter of colour for each found element (for example using CrossFadeAlpha method). Thus, you would still need to do more actions, because some UI-elements in a window can be translucent, and after applying fade out effect by setting alpha to zero, you would need to restore initial alpha parameter at the end. Thus, you would need to save all alpha parameters for each UI-element, to apply effect, and to restore all alpha parameters for each UI-element at the end. Much make-work.

CanvasGroup simplifies the process of creation of these effects.

Fade Out and Fade In effects

I wrote  two tweens which implement fade out (FadeOutTween) and fade in (FadeInTween) effects with the help of CanvasGroup, and which can be used “in one line”:

public void OnGUI()
{
    if (GUILayout.Button("Fade Out/In"))
    {
         TweenSequence.Run(
            () => FadeOutTween.Run(Panel, Duration),
            () => FadeInTween.Run(Panel, Duration).SetDelay(0.25f));
    }
}

2. Interactable.

Makes a group of UI-elements inaccessible for interaction (equivalent of enable/disable from other UI-frameworks). For example, you can make a set of buttons or all elements in a window irresponsive to click.

Making a group of button inaccessible for input

3. Blocks Raycasts.

Blocks all user’s actions over UI-elements which are realized by “Raycasts”. For example, we display a window over another one, and if the overlying window does not block the underlaying ony on size, then the possibility to interact with UI-elements of the underlaying window remains. We can use “BlocksRaycast” parameter to block this possibility  .

Blocking of possibility to interact with UI elements of underlying window

The difference from “Interactable” parameter – “Interactable” makes all UI-elements “disabled”, and if UI-element has a different form  for “disabled” condition, it changes the form for “disabled”. “BlockRaycasts” simply blocks all user’s input without changing the form of elements.

4. Ignore Parent Groups.

Ignore all CanvaGroup settings located upwards in hierarchy of UI-elements (“reset” of all CanvasGroup settings).

One button uses Ingore Parent Group settings

CanvasGroup is a useful component which description needs to be included in all uGUI basic lessons, so that the other people do not repeat my thorny path, but make a small step towards ideal code and world.

All examples can be taken at github.

Methods of organizing the interaction between scripts in Unity3D.

Introduction.

Even average Unity3D project is very quickly filled with a large number of various scripts and there is a question of interaction of these scripts with each other.

This article offers some various approaches to organization of such interactions from simple to advanced and describes to what problems can lead each of approaches, and will also offer ways of solution of these problems.

Approach 1. Appointment through Unity3D editor.

Let it be in our project are two scripts. First scratch is responsible for addition of points in game, and second for user interface, which displays number of scored points on game screen.

We will call both scripts – managers: ScoresManager and HUDManager.

In what way manager, who is responsible for screen menu, can receive current quantity of points from manager, who is responsible for addition of points?

It is supposed, that in hierarchy of objects (Hierarchy) of a scene there are two objects, for one of which ScoresManager script is appointed, and for other – HUDManager script.

One of approaches contains the following principle:

In UIManager script we define a variable type ScoresManager:

public class HUDManager : MonoBehaviour
{
    public ScoresManager ScoresManager;
}

But ScoresManager variable needs to be initialized by instance of a class. For this we will choose object in hierarchy of objects, to which HUDManager script is appointed and in object settings we will see ScoresManager variable with None value.

Further, from a window of hierarchy we move the object, that contain ScoresManager script, in area, where None is written and we appoint it the declared variable:

Then, we have an opportunity from HUDManager code address to ScoresManager script, thus:

public class HUDManager : MonoBehaviour
{
    public ScoresManager ScoresManager;
 
    public void Update ()
    {
        ShowScores(ScoresManager.Scores);
    }
}

Everything is simple, but game isn’t limited to only gathered points, HUD can display the current lives of player, menu available actions of player, information on level and many other things. Game can total in itself tens and hundreds of various scripts, that need to receive information from each other.

To obtain data from other script in one script we should describe every time a variable in one script and to appoint (move manually) it by means of the editor, that on its own tiresome work, which can easily forget to be made and then long to look for what of variables isn’t initialized.

If we want to edit something, rename a script, all old initialization into hierarchies of objects, connected with renamed script, will be reseted and it is necessary to appoint them again.

At the same time, such mechanism doesn’t work for prefab (prefab) – dynamic оbject сonstruction from a template. If any prefab needs to address to manager located in hierarchy of objects, you won’t be able to appoint to prefab an element from hierarchy, and it is necessary firstly to сonstruct an object from prefab and after that programmatically to appropriate an instance manager of variable to just сonstructed object. Blind work, unnecessary code, additional coherence.

Following approach solves all these problems.

Approach 2. “Singltons”.

We will apply the simplified classification of possible scripts, which are used at game construction. First type of scripts: “scripts-managers”, second: “scripts-game-objects”.

The main difference of one from others that “scripts-managers” always have the single copy in game while “scripts-game-objects” can have more instances.

Examples:

As a rule, in a single copy there are scripts which are responsible for general logic of user interface, for playing of music, tracking of level termination condition, system of tasks management, display of special effects and so on.

At the same time, scripts of game objects are in a large number of copies: each birdie from “Angry Birds” is guided by script instance of a birdie with their unique state; for any unit in strategy the unit script instance, containing its current quantity of lives, position in the field and personal purpose is constructed; behavior of five different icons is provided with various instances of the same scripts, which are responsible for this behavior.

In an example from previous step HUDManager and ScoresManager scripts always are in a single copy. For their interaction we will apply a pattern “singleton” (Singleton, same as single).

In ScoresManager class we will describe static ScoresManager property, in which a single copy of  manager of points will be stored:

public class ScoresManager : MonoBehaviour
{
   public static ScoresManager Instance { get; private set; }
   public int Scores;
}

It is also necessary to initialize Instance property with instance of a class, which is constructed by Unity3D framework. As ScoresManager the successor of MonoBehaviour is, so it participates in life cycle of all active scripts in a scene and during initialization of a script it Awake method get called. In this method we place Instance property initialization code:

public class ScoresManager : MonoBehaviour
{
	public static ScoresManager Instance { get; private set; }
	public int Scores;

	public void Awake()
	{
		Instance = this;
	}
}

Then, it is possible to use ScoresManager from other scripts as follows:

public class HUDManager : MonoBehaviour
{             
   public void Update ()
   {
      ShowScores(ScoresManager.Instance.Scores);
   }
}

Now there is no need for HUDManager to describe a ScoresManager field and to appoint it in Unity3D editor, any “script-manager” can provide access to itself through static Instance property, which will initialize as Awake.

Pluses:

  • there is no need to describe a script field and to appoint it through Unity3D editor.
  • it is possible safely to edit a code, if something falls off, the compiler will let know.
  • now it is possible to address to other “scripts-managers” from prefab, through Instance property.

Minuses:

  • approach provides access only to “scripts-managers” existing in a single copy.
  • strong coherence.

We will dwell upon last “minus”.

Let us develop game, in which there are characters (unit) and these characters can die (die).

Somewhere there is a code site, which checks whether our character died:

public class Unit : MonoBehaviour
{
    public int LifePoints;

    public void TakeDamage(int damage)
    {
        LifePoints -= damage;
        if (LifePoints <= 0)
            Die();
    }
}

How game can react on the death of character? Set of various reactions! I will give some variants:

  • it is necessary to remove the character from a game scene that he wasn’t displayed on it any more.
  • in game points for each died character are added, it is necessary to add them and to update value on screen.
  • on the special panel all characters in game are displayed, where we can choose the specific character. When the character died, we need to update the panel, or move away the character from it, or display that he is dead.
  • it is necessary to replay sound effect of death of the character.
  • it is necessary to replay visual effect of death of the character (explosion, blood splashes).
  • the system of game achievements has achievement, which counts total number of the killed characters during all the time. It is necessary to add to the counter of just died character.
  • the system of game analytics sends the fact of death of the character to external server, to us this fact is important for process tracking of the player.

Considering all above-mentioned, Die function can look as follows:

private void Die()
{
   DeleteFromScene();
   ScoresManager.Instance.OnUnitDied(this);
   LevelConditionManager.Instance.OnUnitDied(this);
   UnitsPanel.Instance.RemoveUnit(this);
   SoundsManager.Instance.PlayUnitDieSound();
   EffectsManager.Instance.PlaySmallExplosion();
   AchivementsManager.Instance.OnUnitDied(this);
   AnaliticsManager.Instance.SendUnitDiedEvent(this);
}

It turns out that the character after its death has to send out to all components, which are interested in it, this sad fact, he has to know about existence of these components and has to know that they are interested in it. Isn’t that a bit too much knowledge just for a small unit?

As game, logically, is a very linked structure, so events, occurring in other components, have interest to third, unit isn’t special here.

Examples of such events (by no means all):

  • The condition passing of level depends on number of points scored, if you have 1000 points – you have passed level (LevelConditionManager is connected with ScoresManager).
  • When we score 500 points, we reach an important stage of passing of level, it is necessary to replay a festal melody and visual effect (ScoresManager is connected with EffectsManager and SoundsManager).
  • When the character restores health, it is necessary to replay effect of treatment over the picture of the character in panel of the character (UnitsPanel is connected with EffectsManager).
  • and so on.

As a result of such communications we come to a picture similar on following, where everyone knows about everything:

Example with death of the character is squib, it is necessary to report about death (or other event) to six different components not so often. But variants, when at some event in game, function, in which there was an event, reports about it to 2-3 other components, meets pretty often on all code.

The following approach tries to solve this problem.

Approach 3. World ether (Event Aggregator).

We will enter the special EventAggregator component, main function of which is to store the list of events occurring in game.

Event in game is the functionality giving to any other component opportunity both to subscribe for itself, and to publish the fact of commission of this event. Realization of functionality of event can be any on taste of developer, it is possible to use standard solutions of language or to write own realization.

Example of simple realization of event from last example (about death of a unit):

public class UnitDiedEvent
{
    private readonly List<Action<Unit>> _callbacks = new List<Action<Unit>>(); 

    public void Subscribe(Action<Unit> callback)
    {
        _callbacks.Add(callback);
    }

    public void Publish(Unit unit)
    {
        foreach (Action<Unit> callback in _callbacks)
        callback(unit);
    }
}

We add this event to “EventAggregator”:

public class EventAggregator
{
   public static UnitDiedEvent UnitDied;
}

Now, Die function from previous example with eight lines will be transformed to function with one line of code. We don’t have need to report that the unit died to all interested components and to know about these interested. We simply publish the event fulfillment fact:

private void Die()
{
  EventAggregator.UnitDied.Publish(this);
}

And any component, to which this event is interesting, can react to it as follows (on example of manager, who is responsible for number of points scored):

public class ScoresManager : MonoBehaviour
{
    public int Scores;

    public void Awake()
    {
        EventAggregator.UnitDied.Subscribe(OnUnitDied);
    }

    private void OnUnitDied(Unit unit)
    {
        Scores += CalculateScores(unit);
    }	
}

In Awake function manager subscribes for event and delegate who is responsible for processing of this event. The handler of event accepts an instance of the dead unit as parameter and adds quantity of points depending on type of this unit.

In the same way, all other components, to whom the event of unit death is interesting, can be signed for it and process when the event occurs.

As a result, the chart of communications between components when everyone component knew about each other, turns into the chart when components know only about events which occur in game (only about interesting them events), but thei don’t care, from where these events came. The new chart will look as follows:

I like other interpretation: suppose the “EventAggregator” rectangle stretched extensively and took in itself all other rectangles, turned into world borders. In my head on this chart “EventAggregator” in general is absent. “EventAggregator” it simply the world of game, certain “game air” where various parts of game shout “Hey, people! Unit so-and-so died!”, and all listen to air and if some of the heard events interests them, they will react to it. Thus, there are no communications, each component is independent.

If I am a component and I am responsible for publication of some event, I shout in air that this died, this received level, shell crashed into the tank. And I don’t care if somebody cares. Perhaps, nobody listens to this event now, and it can be one hundred other objects is signed on it. I, as author of event, don’t care, I know nothing about them and I don’t want to know.

Such approach allows to enter easily new functionality without change old. Let’s say we decided to add system of achievements to ready game. We create new to a component system of achievements and subscribe for all interesting us events. No other code changes. It isn’t necessary to go on other components and cause from them system of achievements and tell it to count my event. Besides, everyone, who publish events in the world, knows nothing about system of achievements, even about the fact of its existence.

Remark:

Saying that no other code changes, of course I dissemble a little bit. It can appear so that system of achievements interest events, which earlier simply weren’t published in game because any other system didn’t interest before. And in this case, to us it will be necessary to decide what new events to add to game and who will publish them. But in ideal game are already all possible events, also air is filled with them in spades.

Pluses:

– not coherence of components, it’s suffice just to publish the event and it doesn’t matter who interested in it.

– not coherence of components, I simply subscribe for necessary to me events.

– it is possible to add separate modules without change in the existing functionality.

Minuses:

– it is necessary constantly to describe new events and add them to the world.

– violation of functional atomicity.

We will explore the last minus in full detail:

Put the case we have “ObjectA” object, in which «MethodA» method get called. «MethodA» method consists of three steps and get called in itself three other methods, which carry out these steps consistently (“MethodA1”, “MethodA2” and “MethodA3”). In second «MethodA2» method there is a publication of some event. And there is a following: everyone, who is signed on this event, will start  processing it, carrying out some logic. In this logic there can be also a publication of other events, which processing can also lead to publication of new events and so on. Publications tree and reaction in some cases can expand very strongly. It is so difficult to tweak such long chains.

But the most terrible problem, which can occur here, it when one of chain branches brings back into “ObjectA” and starts processing event by activation of some other «MethodB» method. It turns out that «MethodA» method haven’t executed all steps yet, as it was interrupted on the second step, and comprises now not valid state (in 1 and 2 step we changed a condition of object, but the last change of step 3 wasn’t made yet) and thus “MethodB” in the same object begins to carry out, having such not valid state. Such situations generate mistakes, and very difficult to recognise, lead to that it is necessary to control an activation methods order and publication of events, when, according to the logic, there is no need to do it and enter additional complexity, which it would be desirable to avoid.

Decision point:

It’s not difficult to solve the described problem, it is enough to add functionality of postponed reaction to event. As simple realization of such functionality we can get storage, in which we will put the occurred events. When the event occurred, we don’t carry out it immediately, and simply keep somewhere at ourselves. And at the time of occurrence run queue of functionality some components in game (in Update method, for example) we check for existence of occurred events and processing if there are such events.

Thus, by «MethodA» method execution there is no its interruption, and the published event everyone, who are interested in it, write down to their special storage. And only after they  have their turn, they will get an event from storage and process it. At this moment all “MethodA” will be complete and “ObjectA” will have a valid state.

Conclusion.

Computer game is difficult structure with a large number of components, which closely interact with each other. It is possible to construct a set of mechanisms of organization of this interaction, I prefer the mechanism, described by myself, based on events and to which I came in the evolutionary way overcoming difficulties. I hope somebody will also like it and my article will make things clear and will be useful.

Shadow and Outline effects in Unity GUI.

One of the ways to create a text with shadow is displaying the text two times, the second time – with a small shift and shadow colour behind the first one. This solution is widely used, if the graphic library does not provide own means for display of shadows.

Such a solution is inconvenient though, because you need to create two objects for each text with shadow effect, and if the text is dynamic, then you have to ensure updating of text in both objects.

Simple text and text with shadow created manually

Unity GUI available from 4.6 version, allows to match two effects on the text: «Shadow» and «Outline». As you can guess from the names – the first effect adds a shadow and the second one – outline.

But these effects can be applied not only to the text (Text), but also to the image (Image). And since the text and the image are key blocks of all other UI elements, these effects can be applied to any other UI element as well. For example to the button:

Buttons with Shadow and Outline effects

If we look in the initial code of Shadow and Outline components, we will see that these components, in a fact, do the same thing: Shadow creates a copy of UI component’s geometry and shifts it some pixels aside; Outline creates four copies and shifts them in four opposite directions on x and y axes which provide the outline effect.

Let’s ponder what else we can achieve using these components: Simple outline for the selected objects. You do not need to draw two conditions for each image or handle the colour, you can simply add Outline effect and enable it for the selected object.


Extracting of image by enabling Outline component

Shadows of objects which “go beyond” further than usual shadows of UI elements.

For example, you can display some planes and their shadows on the ground, and imitate sun motion by changing one parameter. (Of course you won’t create game mechanism on GUI elements, but if you need only one simple scene, then why not).

Planes shadows and their shift over time  

Effect of double objects.

For example, you want to apply doubling effect on HUD when your hero is heavily hit or drinks much alcohol. This simply script, applied to all UI objects of the window will help you to achieve the necessary result.

Doubling effect in UI element

You are welcome to write your own ideas on using Shadow, Outline and other effects to the maximum extent in comments.

Wrapper for Invoke

API Unity often pushes programmers to poor practice of hardcore function names. One of such slippery ways is the usage of Invoke function for MonoBehaviour class: Invoke, CancelInvokeIsInvokingInvokeRepeating.

Invoke function and co. are useful when we need to call another function from the initial one with a delay of a few seconds. For instance, after start of the level, to show the panel with bonuses, not immediately, but in two seconds:

public void Start()
{
    Invoke("ShowPanel", 2f);
}

private void ShowPanel()
{
    //show panel there
}

Or if it’s necessary to create a game object (bullet from a gun, a monster, running from behind the corner, etc.) regularly with a certain periodicity. For example, one second after the start of the level for the first time and every three seconds each following time:

public void Start()
{
    InvokeRepeating("SpawnMonster", 1f, 3f);
}

private void SpawnMonster()
{
    //Spawn monster there
}

And it’s convenient, but the hardcore functions names lead to problems, forcing to keep in mind unnecessary information and complicating support and refactoring of the code.

Let’s try to solve the issue taking advantages of the C# language and write the wrappers for Invoke functions and co.:

For a start we have to write a method which gets the name of the function out of the lambda expression, calling this function:

private string GetMethodName(Expression<Action> expr)
{
    return ((MethodCallExpression)expr.Body).Method.Name;
}

After that, write a wrapper for Invoke function, which takes on entry not the function name, but lambda, which calls the function, gets the name out of lambda and calls built-in Unity Invoke function:

protected void Invoke(Expression<Action> expr, float time)
{
    Invoke(GetMethodName(expr), time);
}

By analogy we wrap all other functions, we place the wrappers into the basic class and use. The foregoing examples will now look as follows:

public void Start()
{
    Invoke(() => ShowPanel(), 2f);
}

private void ShowPanel()
{
    //show panel there
}

and

public void Start()
{
    InvokeRepeating(() => SpawnMonster(), 1f, 3f);
}

private void SpawnMonster()
{
    //Spawn monster there
}

Now, any renaming of the function during refactoring will result in a compilation error, or all function calls will be automatically renamed by refactoring tools, if any are used.

You can find wrappings for Invoke here: UtilsExtensions.cs

Thank you for attention!

SortingLayer settings for any object in Unity 2D.

This article is obsolete now. Unity got many new features and it is possible to set SortingLayer now from many places.


In Unity3D 4.3 version there was a long-awaited 2D framework, which brought with itself the work mechanism with sprites, for display of which “Sprite Renderer” is responsible. There is a set of tutorial and video in a network how to work with sprites, I just want to stop on two important settings which are in “Sprite Renderer”, and on a use problem of 3D objects of Unity in 2D games.

Important settings are: “Sorting Layer” and “Order in Layer”:

Why these two parameters are necessary? In a nutshell in 2D framework z-coordinate isn’t used, it doesn’t effect on displaying order objects in a scene. For displaying order other mechanism is responsible – it’s mechanism of layers. It’s possible to operate displaying order of sprites in a scene by appointment of a certain layer (“Sorting Layer”) to sprite, and also, if necessary, displaying order internally of a concrete layer can be adjusted by means of “Order in Layer” parameter.

Displaying order of layers in a scene is adjusted in a window of editing layers:

But Unity3D comprises the mass of interesting functionality, which was made for 3D and which wants to be used in 2D. For example, particles system. Let’s say, in 2D scene you want to use effects from particles system and place one of effects on 2D scene. Here you receive a problem of incorrect displaying of effect (it can be expressed in different ways – partial displaying of effect, blinking, full invisibility and another). Manipulations with z-coordinate won’t lead to necessary result as at 2D displaying of scenes z-coordinate doesn’t effect on displaying order.

This problem is easily solved. “Sorting Layer” and “Order in Layer” properties were added not to class “SpriteRenderer”, but tо basic class “Renderer”, which other classes are inherited, and which are responsible for displaying, but as settings were taken out only for class “SpriteRenderer”, and in others aren’t available. Therefore, we need to write own component which will establish a layer and an order in layer for any renderer.

For myself I wrote such component which can be taken according to links: SortingLayerSettings (a component) and SortingLayerSettingsEditor (editor extension for parameters settings).

Added both scripts to the project, it is possible to add SortingLayerSettings component on any object and to adjust a displaying order of object in 2D scene. For example for “3D Text”:

And it is easy to operate displaying order:

Thus, we can easily use Unity3D objects in 2D scenes. Mechanism perfectly works! On personal experience I used system of particles and 3D text in several projects. I suppose with other types of objects there will be no problems.

Practically, SortingLayerSettings component doesn’t make sense after we specified the necessary layer for object. But at the time of application development there is a need in it, as it can be necessary in operating time of game to experiment with layers or to see, for which layer this or that object belong. But during game release there is a sense to remove all “SortingLayerSettings” from all objects.