Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - BeShifty

Pages: [1]
1
NGUI 3 Support / Solving anchored + animated widgets
« on: May 04, 2015, 02:17:24 PM »
After running into another case where I need anchored and animated widgets, I've come to the conclusion that NGUI needs to address this fairly common requirement and how it can be reconciled with the current anchoring system. The main issue arises due to the fact that it is no longer possible to match a widget's dimensions without also taking its position. The legacy components UIAnchor and UIStretch provided that ability. Here's an example that illustrates the problem:

Widget A (anchored to fill the left 1/4 of the screen)
- Various UI elements (anchored to Widget A in order to have correct dimensions/relative spacing)

Now what can I do to slide these elements on-screen from the left?
- I can't apply a TweenPosition to Widget A because its anchoring will override the tween.
- I can't apply TweenPositions to the sub-elements, because they still need to accept the dimensions from Widget A

My proposed solution is to add a control to UIRect that allows the user to toggle position and/or dimension matching. This new enum (or checkboxes) has three possible states: Position, Dimensions, or PositionAndDimensions. The only change in behaviour is that right before overwriting localPosition or mWidth/mHeight in UIWidget.OnAnchor:1231/1238, we check that we have an acceptable AnchorMode.

I believe this change to be low-risk, backward-compatible (default to PositionAndDimensions), and easy to communicate. Please let me know what you think.

2
NGUI 3 Support / UIKeyNavigation directional filter logic
« on: December 09, 2014, 04:14:30 PM »
I'll keep this short:

UIKeyNavigation should be comparing direction vectors relative to the camera, instead of world space. Currently the system breaks down if your UI/Camera heirarchy has a non-zero rotation, if your UI is 3D, or if your buttons have different Z-depths (for whatever reason). Here are the necessary changes:

  1. static protected Vector3 GetCenter (GameObject go)
  2. {
  3.         UIWidget w = go.GetComponent<UIWidget>();
  4.         UICamera cam = UICamera.FindCameraForLayer(go.layer);
  5.         Vector3 center = go.transform.position;
  6.  
  7.         if (w != null)
  8.         {
  9.                 Vector3[] corners = w.worldCorners;
  10.                 center = (corners[0] + corners[2]) * 0.5f;
  11.         }
  12.  
  13.         center = cam.cachedCamera.WorldToScreenPoint( center );
  14.         center.z = 0;
  15.         return center;
  16. }
  17.  

While I'm at it, a layer mask would be cool to restrict navigation between buttons on different layers. Sometimes we have a map screen and a UI overlay and we don't want to be able to navigate between them freely. This would just involve adding a public LayerMask field, and throwing out targets that aren't in the mask in the Get() loop. Let me know what you think.

3
NGUI 3 Support / Feature Request - AnchorUpdate.OnAwake execute mode
« on: August 06, 2014, 01:32:11 PM »
Would it be possible to add an OnAwake value for the AnchorUpdate enum that only executes the first time the UIRect is enabled? Our screen objects are being transitioned in and out, and the 2nd time we transition them in, we don't want the anchor to execute again since the transition out puts everything into an ugly state (scaled down, slid off screen, etc).

4
NGUI 3 Support / Bug - UICamera dimensions incorrectly calculated
« on: July 11, 2014, 03:13:14 PM »
Bug: When the UI's camera is not a child of a UIRoot, its dimensions are reported as far too large.

Steps to Reproduce:
1) In an empty scene, run NGUI/Create/UI 2D
2) Unparent the Camera GameObject from the UI Root GameObject
3) Reset the Camera's transform.
Note that the Panel attached to the UIRoot now has a gigantic rect visualization, even though the Camera's frustum hasn't changed size at all. For further visualization of the issue, add a sprite as a child of the panel, and anchor it fully to the panel or the camera.

The issue I believe stems from the fact that in NGUITools.GetSides(Camera) and NGUITools.GetWorldCorners(Camera), the points are being transformed by cam.transform.TransformPoint, despite the fact that Unity doesn't scale cameras' frustums by their transform scale. I can hack it to work by modifying the aforementioned functions to something like I've attached below, but you probably need to fix the rectangle gizmos/handles as well.

  1. static public Vector3[] GetSides (this Camera cam, float depth, Transform relativeTo)
  2. {
  3.         Rect rect = cam.rect;
  4.         Vector2 size = screenSize;
  5.  
  6.         float x0 = -1f;
  7.         float x1 = 1f;
  8.         float y0 = -1f;
  9.         float y1 = 1f;
  10.  
  11.         float aspect = (size.x / size.y) * (rect.width / rect.height);
  12.         x0 *= aspect;
  13.         x1 *= aspect;
  14.        
  15.         mSides[0] = new Vector3(x0, 0f, depth);
  16.         mSides[1] = new Vector3(0f, y1, depth);
  17.         mSides[2] = new Vector3(x1, 0f, depth);
  18.         mSides[3] = new Vector3(0f, y0, depth);
  19.         if (relativeTo != null)
  20.         {
  21.                 for (int i = 0; i < 4; ++i)
  22.                         mSides[i] = relativeTo.InverseTransformPoint(mSides[i]);
  23.         }
  24.         return mSides;
  25. }
  26.  

5
NGUI 3 Support / Feature Request - onFilled Event
« on: July 04, 2014, 04:15:21 PM »
Hi,

I'm working on some "decorator" components that modify a widget's geometry to create procedural gradients, skewing, morphing, etc. The main problem I'm running into is that it's hard to detect when I need to reapply my effects to the geometry buffers, AKA when the geometry has been rebuilt. Currently I'm calling UpdateGeometry() manually in the decorator's Update() function and checking if it's changed, but this approach breaks down when stacking multiple effects since only one decorator would see UpdateGeometry return true. Decorators that modify vertex positions also must call ApplyTransform on the geo, which is an extra cost since ApplyTransform is already getting called internally in UpdateGeometry.

Subscribing to UIWidget.onChange doesn't cover most cases since we need to reapply our effects whenever text changes, a filled sprite changes fill value, pivot changes, etc.

Proposed Solution
Add UIWidget.onFilled notification that is called/sent immediately after OnFill() in UIWidget.UpdateGeometry. This would allow developers to hook into the geometry fill process from other scripts without having to inherit from UISprite/UILabel/UITexture, since that goes against Entity/Component principles.

Any feedback or suggestions?

6
NGUI 3 Support / Alpha-tested Hit Check
« on: January 27, 2014, 07:26:29 PM »
I whipped up an alpha-tested hit check script to use with the recent API addition. Attach it to the widget with the collider. Please note that Read/Write must be enabled on your atlas texture. I've tested it with UISprites and UITextures, but not extensively. Please let me know what you think. Here it is:

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. [RequireComponent(typeof(UIWidget))]
  5. public class UIHitAlphaTest : MonoBehaviour {
  6.         [Range(0.01f,1f)]
  7.         public float threshold = 0.5f;
  8.  
  9.         void Start () {
  10.                 GetComponent<UIWidget>().hitCheck = HitCheck;
  11.         }
  12.  
  13.         bool HitCheck(Vector3 worldPos) {
  14.                 UIWidget w = GetComponent<UIWidget>();
  15.                 Vector3 localPos = w.cachedTransform.InverseTransformPoint(worldPos);
  16.                 Texture2D tex = w.mainTexture as Texture2D;
  17.  
  18.                 for( int i = 0; i < w.geometry.verts.size; i+=4 ) {
  19.                         if( CheckTriangle( localPos,
  20.                                         w.geometry.verts.buffer[i], w.geometry.verts.buffer[i+2], w.geometry.verts.buffer[i+1],
  21.                                     w.geometry.uvs.buffer[i], w.geometry.uvs.buffer[i+2], w.geometry.uvs.buffer[i+1], tex )     ||
  22.                                 CheckTriangle( localPos,
  23.                                     w.geometry.verts.buffer[i], w.geometry.verts.buffer[i+3], w.geometry.verts.buffer[i+2],
  24.                                     w.geometry.uvs.buffer[i], w.geometry.uvs.buffer[i+3], w.geometry.uvs.buffer[i+2], tex ) )
  25.                                 return true;
  26.                 }
  27.                 return false;
  28.         }
  29.  
  30.         bool CheckTriangle(Vector3 pos, Vector3 v1, Vector3 v2, Vector3 v3, Vector2 uv1, Vector2 uv2, Vector2 uv3, Texture2D tex) {
  31.                 Vector3 normal = Vector3.Cross( v3-v1, v2-v1 );
  32.                 if( normal.sqrMagnitude < 0.01f )
  33.                         return false;
  34.  
  35.                 pos = pos - Vector3.Dot( pos-v1, normal ) * normal;             //Project point onto plane
  36.  
  37.                 float area = normal.magnitude;  //Technically area*2
  38.  
  39.                 float a1 = Vector3.Cross( v2-pos, v3-pos ).magnitude / area;
  40.                 if( a1 < 0 || a1 > 1 )
  41.                         return false;
  42.  
  43.                 float a2 = Vector3.Cross( v3-pos, v1-pos ).magnitude / area;
  44.                 if( a2 < 0 || a2 > 1 )
  45.                         return false;
  46.  
  47.                 float a3 = 1f-a1-a2;    //Vector3.Cross( v1-pos, v2-pos ).magnitude / (2*area);
  48.                 if( a3 < 0 || a3 > 1 )
  49.                         return false;
  50.  
  51.                 Vector2 finalUV = uv1 * a1 + uv2 * a2 + uv3 * a3;
  52.                 Color pixel = tex.GetPixel( (int)(finalUV.x * tex.width), (int)(finalUV.y * tex.height) );
  53.  
  54.                 return pixel.a >= threshold;
  55.         }
  56. }
  57.  

7
NGUI 3 Support / Dynamic Font Shader not ZTesting
« on: August 26, 2013, 03:47:16 PM »
Since switching my fonts to be dynamic, my UILabels in my 3D environment no longer check the depth buffer when drawing, resulting in them being overlaid on top of my 3D environment. I see that the Panel is using Unity's built in "Font Material", but is it possible to swap out the shader to one that has ZTest enabled?

8
NGUI 3 Support / Panel Soft Clipping
« on: February 26, 2013, 02:21:17 PM »
One issue I'm having with UIPanel's clipping is that for scrolling panels, I'd like to only apply the soft clip to the top/bottom edges if there is more content to be shown in that direction. I can do handle writing the code to set the values, but I'm not sure whether there's a straightforward way of setting the top and bottom soft clip values independently. Any tips?

9
NGUI 3 Support / Filled Sprite Texture Offset
« on: January 03, 2013, 05:51:36 PM »
I'd like to create an effect similar to this loading bar: , where a repeating texture has its UV coordinates animated to create a scrolling effect. I understand that for the repeating part I should use a UITiledSprite, but that doesn't help me with the UV offsetting. Is there any way of assigning an offset manually, or will I have to modify the UITiledSprite class?

Pages: [1]