Hello Guest

Author Topic: help setting up UI on top of 3D world  (Read 3875 times)

David Kalina

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 26
    • View Profile
help setting up UI on top of 3D world
« on: June 11, 2013, 03:50:25 pm »
Hey there -- I'm trying to figure out the best way to approach UI implementation using 2DToolkitUI and could use some guidance.

Let's start by saying that I'm building a 3D game (the standard camera is perspective) that targets mobile + PC -- variable screen size, aspect ratio, and pixel density all need to be accounted for, though for now I'll be happy to just use hi-res/hi-DPI assets for all targets. 

I am looking to implement my always-on-screen UI using 2DToolkitUI.  I figure the best way to do this is have a separate, ortho camera that only shows UI elements in screen space, and that it draws after the game camera draws the 3D world.

I dropped a tk2dcamera into my scene, set its Clear Flags to "don't clear", and am using the Culling Mask to draw only things in a new layer called "2DToolkitUI".  Set the camera depth to 1 so that it draws after my standard perspective camera.

I then drop a BasicButton prefab into the scene, put it in my "2DToolkitUI" layer.  Takes me some time to figure out where to position the button but I finally figure out how to get it on screen.  This is where I start to get confused.

1.  The button doesn't respond to clicks in game.  It renders on top of the 3D world as intended but clicks are not received.  Note that if I do this same work in a new, empty project, clicks are received just fine, so it must have something to do with my project's settings.  Any idea where to look?

2.  What's the best way to resize UI elements when placing them in the editor?  I can resize the button graphic's "dimensions" in "pixel units" but these numbers don't seem to have any correlation with what I see on screen.  I currently set this field 128x128 with a transform.scale on the BasicButton of 1x1 ... and the button is completely invisible.  If I set the transform.scale up to 128x128, the button now appears to occupy 48x48 pixels in my 1024x768 window.  Huh?  I feel like I'm just randomly trying things here, what's the correct method?

3.  I'm going to start with our HUD -- on-screen indicators for score, resource count, and a menu button.  All of these elements want to be laid out relative to the corners of the screen.  Is there a way to properly author this in-editor?  Or do I need to perform the layout tasks in code? 

Thanks in advance for your time and guidance!

Cheers,
David

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: help setting up UI on top of 3D world
« Reply #1 on: June 11, 2013, 04:07:19 pm »
1. There are 2 things to check if clicks don't work.
i. Is the collider intersecting with the camera?
ii. Do you have Raycast Hit Triggers turned off in Edit > Project Settings > Physics?

2. The tk2d UI prefabs are configured to work with a normal Unity camera with orthographic size 1.0. If you want to use the prefabs as is, then use those camera settings. If you would just like to use tk2dCamera - your sprite collections should have "Use tk2dCamera" ticked to work automatically without messing with scales. You shouldn't mess with scales at all, really. Setting it up right will mean you don't have to.
Docs here: http://unikronsoftware.com/2dtoolkit/doc/2.00/

3. In the next tk2d, the anchor classes will work with any camera. Here is a quick sample for now.
Code: [Select]
using UnityEngine;
using System.Collections;

public class SampleAnchorToCamera : MonoBehaviour {

public tk2dBaseSprite.Anchor anchor = tk2dBaseSprite.Anchor.UpperLeft;
public int pixelOffsetX = 0;
public int pixelOffsetY = 0;

public Camera targetCamera;

void Start() {
if (targetCamera != null) {

Vector2 origin = Vector2.zero;
float y1 = targetCamera.pixelHeight;
float x1 = targetCamera.pixelWidth;
switch (anchor) {
case tk2dBaseSprite.Anchor.LowerLeft: origin.Set(0, 0); break;
case tk2dBaseSprite.Anchor.LowerCenter: origin.Set(x1 / 2, 0); break;
case tk2dBaseSprite.Anchor.LowerRight: origin.Set(x1, 0); break;
case tk2dBaseSprite.Anchor.MiddleLeft: origin.Set(0, y1 / 2); break;
case tk2dBaseSprite.Anchor.MiddleCenter: origin.Set(x1 / 2, y1 / 2); break;
case tk2dBaseSprite.Anchor.MiddleRight: origin.Set(x1, y1 / 2); break;
case tk2dBaseSprite.Anchor.UpperLeft: origin.Set(0, y1); break;
case tk2dBaseSprite.Anchor.UpperCenter: origin.Set(x1 / 2, y1); break;
case tk2dBaseSprite.Anchor.UpperRight: origin.Set(x1, y1); break;
}

origin += new Vector2(pixelOffsetX, pixelOffsetY);

float d = transform.localPosition.z;
Vector3 w = targetCamera.ScreenToWorldPoint(new Vector3(origin.x, origin.y, d));
transform.position = w;
}
}
}

David Kalina

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 26
    • View Profile
Re: help setting up UI on top of 3D world
« Reply #2 on: June 11, 2013, 05:02:50 pm »
1.  Got it working by re-enabling Raycast Hit Triggers and then had to fix up properties on tk2dUIManager.  Thanks!

2.  I'll go over the documentation carefully, but I'm not sure how I wouldn't mess with scales at all, if, for example, I was creating menu buttons using sliced sprites and text.  My intent (hope?) is to layout my main menu entirely in the editor, similarly to how you lay out your menu in the UI Demo. 

3.  I'm not sure what you're suggesting.  I should use the script you include?  How do I layout UI elements relative to screen size today?  Just looking for best practices.

Thanks,
David


unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: help setting up UI on top of 3D world
« Reply #3 on: June 11, 2013, 05:59:32 pm »
2. The sliced sprites can be resized (when dragging handles it adjusts dimensions, not scale). Thats not "scale"ing the sprite. What you dont want to do is change transform.localScale or sprite.scale.

3. The built in camera anchor class only works with tk2dCamera. You can use this script to anchor things to camera, even when not using a tk2dCamera.