Unity Community |

Can you explain the difference between the 2D UI and 3D UI objects? Can they be used together, etc.
The only difference is in the camera used to draw them. Ortho camera is used for the 2D UI and a perspective camera is used for the 3D UI. They can be used together safely. In example 3 (the orc) the UI itself is 3D, but tooltips are 2D.
@ArenMook, thanks, I have been using Example 1 - Interaction, and haven't gotten to the Orc yet. I did not know if more was involved.
Do you recommend any animation package that can work with NGUI? That can move objects around after state has been sent?
I have written a bunch of animation classes that work with NGUI and is working, just wondering if I should use another package.
Last edited by parkerdc; 01-08-2012 at 10:29 AM.
I'm currently working on a simple built-in tweening system that will go live in the next update. If you need more advanced animations, you can just create them using Unity itself (Right click in project view -> Create -> Animation).
ArenMook, you are awesome, a simple tween system is exactly what I need!
Ah of course, nice and clean! Im good at making things overly complicated
Today I was wondering over how to deactivate gui elements the most efficient way. Lets say I have a lot of UI elements with fairly complex compositions (Lots of game objects and UIWidgets), and I want these to stop being rendered. Is the best way to iterate through the hierarchy and go gameObject.active = false, or is there some shortcut through the UIPanel so that the gameobjects themselves can stay active while the UIWidget is not rendered by the panel? Similar to just turning off a gameobjects renderer (I usually do that instead of turning off gameobjects completely).
I suggest organizing your UI to have several sub-roots that you can activate/deactivate using SetActiveRecursively:
If you want to disable all widgets but keep game objects active:Code:
... but the colliders will still be active, so I suggest you go with my original suggestion.Code:
UIWidget[] widgets = gameObject.GetComponentsInChildren<UIWidget>();
Hi Aren, is the trimmed texturepacker atlas feature compatible with using UIFonts as sprite within UIAtlas? Entering the PixelRect for the font could get kinda crazy with trimming enabled... It's already hard to get the correct PixelRect just without trimmed sprites. Can you give any guidelines for reading the texturepacker .txt file and interpreting what needs to be entered in PixelRect? Thanks
Yup, fully supported.
No need to manually enter anything anymore. Select the atlas on UIFont and choose the font's sprite.
@Aren, wow- I just did that and the UIFont inspector updated automagically. That's some pretty impressive codingThanks much
A PM I just received gave me a perfect idea for the next example: iTunes style playlist.
It's a part of 1.28, now available for download via the PayPal link.
It's fairly rudimentary. For example in order to make a widget expand and shrink in a loop, you can attach a TweenScale to it and check the "loop" parameter. There's also TweenPosition, TweenRotation, and TweenColor. TweenColor is capable of tweening widget colors, renderer material color, or light colors -- whatever it finds on the game object it's attached to.
Usage via code is equally simple:
You can change the method of interpolation like so:
UIState series of scripts have been updated to use the tweening scripts.
I'll add an example for it in a bit.
I bought all your packages from the app store except BT (PayPal). I will have to wait for the app store to get the update.
I took the uistateposition, created a new class and added this code to the bottom of the update.
Code:
if (Mathf.RoundToInt(mTrans.localPosition.x) == positions[index].x && Mathf.RoundToInt(mTrans.localPosition.y) == positions[index].y && Mathf.RoundToInt(mTrans.localPosition.x) == positions[index].z)
I created various positions that the logo falls into place and red player walks. Once they reach the position, continue onto the next one. They stop at the end.
The other class I created was to cycle through positions, going back to the begining once reaching the end.
![]()
Last edited by parkerdc; 01-08-2012 at 02:27 PM.
I still say using Unity's built-in animation is your best bet for anything past simple tweening
1.28 should be on the asset store tomorrow.
Hi Aren, the Trim support for TexturePacker seems to work great! Only this problem: every time when I reimport the TP Import TextAsset, all my sprite's sizes got reset back to pixel perfect. Is that a regression of previous bug? It's time consuming to go back and resize every sprite just because the atlas had some new stuff added to it.
Thanks for the update. I was under the impression that there is a big overhead when using Unity's built in animation.
Do you know of a good tutorial on how to use the built in animation?
Last edited by parkerdc; 01-08-2012 at 02:42 PM.
@mindlube: That must be a regression bug. I'll track it down.
@parkerdc: Nope, can't say I do... I learned it just by playing around with it. It's fairly simple though -- you get a graph, and if you are in Record mode, you can just move the timeline, move the objects into place, then hit Play and see it come alive.
Aren, I'm using 1.26 from the App Store. I just did a test, and the same happens for non-trimmed atlases as well. So I could just be confused what the normal behavior was though: I was sizing directly my UISprites, instead of parenting them to gameobject and scaling/transforming the parent instead.That would be more advisable, right?
@arenmook: Thanks for your suggestions regarding how to best turn of widgets!
A question, when adding a collider to a widget that was just created (in code), is there something special to keep in mind? Look at this short code for example:
The first to lines set the widget up through my simple UIManager (It creates a gameobject and adds it to the UI hierarchy (The root that has the UIPanel) and set the correct layer and so on), the second line just gets the right font.Code:
The problem is that the collider added by AddCollider gets a size of zero (the code is a copy of the stuff in NGUIMenu minus the editor code stuff). If I add it through the menu later in runtime everything is correct. Is it that the UIPanel has not yet updated the sprite and its size?
Edit: It seems to work for UISprites.
Edit2: labelWidget.visibleSize returns (0,0) but if I instead run labelWidget.font.CalculatePrintedSize I get the correct values.. I dont understand this, but it works the way I want it now, I think![]()
Last edited by mydingefnysen; 01-08-2012 at 03:50 PM.
Hello,
i just bought NGUI and am quite pleased with it so far. While i was trying to set up my GUI with it, i thought, oh well, why not try to make everything with it, and in my case that is.... tadaaaaaa, mobile joystick.
You know, there is a joystick prefab in the mobile package (i guess), and since this is a GUI, it should be handled by any guysolution - or it ads up drawcalls.
Furthermore, one could pimp it a bit.
I guess some other users would appreciate this as well, as the one draw call gui is typically a mobile thingy.
as Ngui uses C# only this evening i ported the unitys joystick.js to c#. Seems to work, i got no errors.
But now i am stuck, as we need to replace everything concerning GUITexture (which this script relies on) to UISprite, or whatever you use. Its not much, one merely needs to retrieve the actual screenrepresentations RECT of the joystick texture.
As for Pimping it up:
The existing joystick ONLY works on mobile devices. Because of the input things. It would be much nicer to have additional MouseInput available at least in the editor, to test a game a bit there (For other machines, i actually cannot see any use in this) A relative restposition graphic would also by nice (i mean basically a circle underneath, that is static, but the user can see how much he moved the joystick (well actually the developer only needs to put an appropriate graphic underneath the joystick sprite)).
Second thing to pimp would be the position of the joystick. Unitys solution is fixed. I like the idea of centering the joystick on Touchdown. So people with large hands have the center of it more to the middle of the screen.
I will try to port it myself more, when i find the time (hard with two children). But i am not a too good coder especially not in C. If you think its a good idea to incorporate this, here is my joystick port so far:
Code:
using UnityEngine; /// <summary> /// Attach this script to a child of a draggable window to make it tilt as it's dragged. /// Look at how it's used in Example 6. /// </summary> public class JStickBoundary { } { // A static collection of all joysticks static private NGUIjoystick[] joysticks; // A static collection of all joysticks static private bool enumeratedJoysticks=false; static private float tapTimeDelta = 0.3f; // Time allowed between taps public bool touchPad; // Is this a TouchPad? public Rect touchZone; public float deadZone = 0; // Control when position is output public bool normalize = false; // Normalize output after the dead-zone? private int lastFingerId = -1; // Finger last used for this joystick private float tapTimeWindow; // How much time there is left for a tap to occur private Vector2 fingerDownPos; private float fingerDownTime; private float firstDeltaTime = 0.5f; private JStickBoundary guiBoundary = new JStickBoundary(); // Boundary for joystick graphic /* #if !UNITY_IPHONE && !UNITY_ANDROID void Awake () { gameObject.active = false; } #else */ // Cache this component at startup instead of looking up every frame // Store the default rect for the gui, so we can snap back to it // how do we find the drawing rect for this NGUI GameObject defaultRect = guiSprite.pixelInset; transform.position = initPos; if (touchPad) { // If a texture has been assigned, then use the rect ferom the gui as our touchZone if (guiSprite.texture) touchZone = defaultRect; } else { // This is an offset for touch input to match with the top left // corner of the GUI guiTouchOffset.x = defaultRect.width * 0.5f; guiTouchOffset.y = defaultRect.height * 0.5f; // Cache the center of the GUI, since it doesn't change guiCenter.x = defaultRect.x + guiTouchOffset.x; guiCenter.y = defaultRect.y + guiTouchOffset.y; // Let's build the GUI boundary, so we can clamp joystick movement guiBoundary.min.x = defaultRect.x - guiTouchOffset.x; guiBoundary.max.x = defaultRect.x + guiTouchOffset.x; guiBoundary.min.y = defaultRect.y - guiTouchOffset.y; guiBoundary.max.y = defaultRect.y + guiTouchOffset.y; } } void Disable () { gameObject.active = false; enumeratedJoysticks = false; } void ResetJoystick () { // Release the finger control and set the joystick back to the default position guiSprite.pixelInset = defaultRect; lastFingerId = -1; /* if (touchPad) guiSprite.color.a = 0.025f; */ } bool IsFingerDown () { return (lastFingerId != -1); } // If another joystick has latched this finger, then we must release it ResetJoystick (); } if (!enumeratedJoysticks) { // Collect all joysticks in the game, so we can relay finger latching messages enumeratedJoysticks = true; } // Adjust the tap time window while it still available if (tapTimeWindow > 0) else tapCount = 0; ResetJoystick (); } else { var shouldLatchFinger = false; if (touchPad) { shouldLatchFinger = true; shouldLatchFinger = true; } // Latch the finger if this is a new touch if (touchPad) { joystickcolor.a = 0.15f; guiSprite.color = joystickcolor; lastFingerId = touch.fingerId; fingerDownPos = touch.position; fingerDownTime = Time.time; } lastFingerId = touch.fingerId; // Accumulate taps if it is within the time window if (tapTimeWindow > 0) { tapCount++; } else { tapCount = 1; tapTimeWindow = tapTimeDelta; } // Tell other joysticks we've latched this finger foreach ( NGUIjoystick j in joysticks ) { if ( j != this ) } } // Override the tap count with what the iPhone SDK reports if it is greater // This is a workaround, since the iPhone SDK does not currently track taps // for multiple touches if (touchPad) { // For a touchpad, let's just set the position directly based on distance from initial touchdown } else { // Change the location of the joystick graphic to match where the touch is } ResetJoystick (); } } } // Calculate the length. This involves a squareroot operation, // so it's slightly expensive. We re-use this length for multiple // things below to avoid doing the square-root more than one. // If the length of the vector is smaller than the deadZone radius, // set the position to the origin. } else { // Normalize the vector if its length was greater than 1. // Use the already calculated length instead of using Normalize(). } else if (normalize) { // Normalize the vector and multiply it with the length adjusted // to compensate for the deadZone radius. // This prevents the position from snapping from zero to the deadZone radius. } } if (!touchPad) { // Change the location of the joystick graphic to match the position //guiSprite.pixelInset.x = (position.x - 1) * guiTouchOffset.x + guiCenter.x; //guiSprite.pixelInset.y = (position.y - 1) * guiTouchOffset.y + guiCenter.y; } } } //#endif