Hi, my name is Mikhail Kulikov, I am a game developer and I use Unity in my difficult craft. I will not go into the description of what Unity is or how I lived it up to the point that I started using it as an engine. Let me just say that this is a great tool with a lot of advantages and disadvantages, and the main disadvantage, in my opinion, is the lack of tools for comfortable work on the UI. The toolkit that the Unity developers provided in version 4.6 as an open beta does not count. Especially I did not go into it, and there is no particular desire, since I have been using the NGUI plugin for a long time. Today I want to share with you the problems that I had to face while doing tween-animations for the interface, as well as solving these problems.
Problem # 1. Animations and anchors
Or I don’t understand something, or the
TweenPosition component doesn’t fit in with the anchors. I mean the following situation. I have a widget that is anchored to the upper left corner of the screen. Changing the screen resolution and aspect ratio, my widget maintains its position well and everything looks great.
4: 3 aspect ratio

| 16: 9 aspect ratio

|
When I tried to use
TweenPosition to animate the widget's “exit” from the edge of the screen, I realized that nothing would come of it.
TweenPosition uses the Vector3 coordinates to indicate the starting and ending positions of the animation. For example, we set the following values ​​for the animation:

When I change the aspect ratio, the widget continues to move along the coordinates stored in
TweenPosition , which do not correspond to its new coordinates.
4: 3 aspect ratio

| 16: 9 aspect ratio

|
I tried to write a script that would calculate the offset for the From and To vectors, but he didn’t want to be friends with the anchors, and the animation turned into hell. This is no good. We start thinking further.
')
NGUI has a wonderful
TweenTransform component that allows you to move an object from point A to point B, where A and B are transforms of any objects. Here is an example:

Remove anchor from widget and set anchor from our game objects A and B

Look what happened:
4: 3 aspect ratio

| 16: 9 aspect ratio

|
Now, at any resolutions and aspect ratios, the animation retains its appearance.
Well, it works fine, at least the expected result is achieved. But I want to automate the process. There are a lot of UI elements that require animation in my project and it is terribly boring to perform the operations described above on each of them. We write a simple script that will help us. Let's call it
TweenTransformHelper .
I know, the above script probably struck you with its complexity, so the next one will not scare you:
TweenTransformHelperEditor.cs I do not see the point of describing the work of the script in detail, there is nothing complicated in it. Now, if we add the script to the widget, we will see the following panel:

Create
$ anchorTo and
$ anchorFrom and click “Apply to tween” (this will automatically fill in the appropriate fields in the
TweenTransform ). Now it's small, adjust the snapping to the edges of the screen for $ anchorTo and $ anchorFrom, pre-putting them in the right position.

This is problem # 1 solved. Go ahead.
Problem # 2 Sequential Animations
But what if we want to make a chain of moving objects? With the help of NGUI to do it is elementary. Each
TweenTransformer component has an
On Finished field that can contain any methods of any component, provided that this method is public. Added methods are called immediately after the animation has finished playing. For example, we can make a sequence of exit entries like this:

Now when you start the animation, we will see the following wonders:

When you activate the screen elements go and it looks good. But what if we want to play the animation in reverse order when the screen is deactivated?
Based on what I found in the plug-in forum discussions, it’s not me alone who faced this problem. The participants in the discussions suggested solving this problem in the following way: somehow getting a list of event calls, reversing it and building calls in the reverse order. This decision seemed to me too complicated, because, as they say, normal heroes always go around. The
existing OnFinished event functional of the
UITweener class (of which the
TweenTransform is
derived ) is not enough, because it is called when the animation plays from beginning to end and vice versa. It is impossible to determine in which direction the animation played before being completed. If it were possible, my problem would be solved. In the end, I decided to expand the capabilities of NGUI. Forgive me
ArenMook , but I had to manage in his code. In fact, the changes that need to be made to the
UITweener class
are minimal.
In
UITweener.cs we add the following fields:
List<EventDelegate> mTempForward = null; List<EventDelegate> mTempReverse = null; [HideInInspector] public List<EventDelegate> onFinishedForward = new List<EventDelegate>(); [HideInInspector] public List<EventDelegate> onFinishedReverse = new List<EventDelegate>();
And in the Update method after
if (onFinished != null) { mTemp = onFinished; … }
add
if (onFinishedForward != null && direction == Direction.Forward) { mTempForward = onFinishedForward; onFinishedForward = new List<EventDelegate>(); EventDelegate.Execute(mTempForward); for (int i = 0; i < mTempForward.Count; ++i) { EventDelegate ed = mTempForward[i]; if(ed != null && !ed.oneShot) EventDelegate.Add(onFinishedForward, ed, ed.oneShot); } mTempForward = null; } if (onFinishedReverse != null && direction == Direction.Reverse) { mTempReverse = onFinishedReverse; onFinishedReverse = new List<EventDelegate>(); EventDelegate.Execute(mTempReverse); for (int i = 0; i < mTempReverse.Count; ++i) { EventDelegate ed = mTempReverse[i]; if (ed != null && !ed.oneShot) EventDelegate.Add(onFinishedReverse, ed, ed.oneShot); } mTempReverse = null; }
Go to
UITweenerEditor.cs and add a few more lines of code so that the advanced features of the
UITweener class
are displayed in the editor.
After
NGUIEditorTools.DrawEvents("On Finished", tw, tw.onFinished);
add
NGUIEditorTools.DrawEvents("On Finished forward", tw, tw.onFinishedForward); NGUIEditorTools.DrawEvents("On Finished reverse", tw, tw.onFinishedReverse);
As a result of these manipulations, the TweenTransform window now looks like this

Having the opportunity to find out in which direction the animation has finished, I can build a sequence that can correctly play back and forward. This is done elementary:

To play the animation forward, you need to call the PlayForward method on the first element of the chain, and in order to play it in reverse order, you need to call PlayReverse on the last element. Now we get the expected result:

Conclusion
NGUI is a great plugin for Unity, with great features, but it, like any complex tool, has its flaws or flaws. But, having in store a little bit of time and desire, they are easy to fix and achieve the desired result.