Unity3d how to have a "text label" follow a game object - unity3d

In my world I have a GameObject, lets say a race car.
Above the race car I want a white box with a text label that says the driver's name (let's say "Fred"). This label will follow the race car as it moves.
How can I create this "white box with a text label" in Unity? Will it be a gameobject (if so, how do I construct it).
Since the only "Text" object I find in Unity editor was a UI element. And the UI canvas is unrelated to the coordinates in my game world, so I dont know if this is appropriate use case for this type of object.

I think you have 2 options. It is fundamental to read to the different canvas modes in the documentation
1.- Overlay mode. You can figure out the screen position of your canvas at runtime with
Camera.WorldToScreenPoint. This canvas mode places UI elements on the screen rendered on top of the scene, so you would kind of "fake" the canvas is following your gameObject in the world calculatig and updating its position.
2.- World Space, make cavas children of your car and make it always face the camera with a billboard component updating the canvas rotation.
public class Billboard : MonoBehaviour {
public Transform cam;
private void Start() {
cam = Camera.main.transform;
}
void LateUpdate() {
transform.LookAt(transform.position + cam.forward);
}
}
Add the component to the canvas gameObject or do myCanvas.AddComponent<Billboard>(); where myCanvas is the Canvas component in your canvas holder gameObject.
With this option the canvas is actually in the world as the mode name indicates, thats why you would need to update its rotation to make it always look to the camera.
In option 1 you need to update the position and not the rotation because the canvas is in the screen and with option 2 you need to update the rotation and not the position because the canvas is in the world.

Related

Unity GameObject rendering below GameObject lower in the hierarchy

I have a GameObject (TopSquare) that is rendered after PlayButton in the hierarchy, yet the PlayButton is showing on top. This goes against Unity's rule of objects added last are shown over objects added previously.
Why is this?
The square is a sprite that is an object in the World, while the button exists in the UI layer over it.
You have to use UI Image for black square instead of sprite renderer (Right-click on parent -> UI -> Image)

How do I make a UI button follow a 2d game object?

new to unity and have stumbled into a problem. I am unsure about how to make a UI button on a canvas follow a rigidbody game object in the 2D screen space. I want to make the button's x and y position match the x and y of the RB, so that in theory if I clicked on the RB it would activate the button. However, I am unsure how to implement such a thing into my project.
I tried using transform.position and just equating the ui button pos and RB pos together but it remained static. However, I did script the RB to move to a designated x point and only then did the button move as well despite the RB moving beforehand.
This is literally the example in the documentation for Camera.WorldToScreenPoint(). Attach this script to your button:
public class ObjectFollow : MonoBehaviour
{
public Transform Follow;
private Camera MainCamera;
// Start is called before the first frame update
void Start()
{
MainCamera = Camera.main;
}
// Update is called once per frame
void Update()
{
var screenPos = MainCamera.WorldToScreenPoint(Follow.position);
transform.position = screenPos;
}
}
I have an Idea To Implement that You can use a world space canvas and as a child of that object "that you mentioned has rigid body " now when it moves the canvas and its content will move watch this to
Understand Canvas
Now press on your object at hierarchy window Right Click then UI then Button
this will create new canvas and attach button to will look like this
hierarchy
Now Select Canvas and reset its width and height , set scale to small value 0.01 ,0.01 0.01 for example
then change its Rendering Mode to Space World and assign camera
you should insure that you have event system it should created automatically but events will never work if you don't have a one in hierarchy Window
canvas will like this
Canvas Image
Now You can Select this Button and add a function to call using onClick or you can pass it to another script to add this function dynamically like this
Add Event to UI Button From Script

Placing random game objects on canvas in random position with specific distance

I'm new on unity and am trying to create a top-down game.
My Main camera projection set to Orthographic.
I added a canvas with Render Mode of "Screen Space - Camera" and UI Scale Mode of "Scale With Screen Size" to hold my joystick and other UI element to support different resolutions. Also I added another canvas with the same settings to hold the walls and doors (Because they should be at the border or edge of screen along with different resolution!). I need to place some objects to the screen, I can do it by random with specific distance or by creating empty game objects on screen (inside canvas) and bind them to the script then place my Prefabs to their (empty GameObject) location.
The issue is I can't understand the object position in Canvas and Screen, I instantiate my prefabs to the empty gameobject position on Canvas, but it's been placed some where else.
Here's the 3d view of my scene:
You could use Camera.main.screenToWorldPoint and use a random float or integer for the x and z coordinates. If you set the random number to be between the lower right corner in world space and the upper left corner in world space, you will get a random position inside the walls.

Collisions between UI elements in Unity

I am able to detect collision between UI components and a gameobject if my canvas is rendered in the world space. Here, I am trying to find collision between two UI elements (say UI buttons) when the canvas render mode is screen space overlay.
I added box collider components to my UI buttons and tried using OnCollisionEnter2D and OnTriggerEnter2D. But, the collision is not detected. Is there a way to detect the collision?
The question does not require a code body. However, I have figured out a solution. TO both the UI elements, you need to:
Attach a rigidbody2d component
Attach a box collider component
disable gravity
enable the isTrigger checkbox.
Now in the script attached to one of the UI elements:
void OnTriggerEnter2D(Collider2D other)
{
Debug.Log ("Triggered");
}
This would detect the collision.

Unity3d with vuforia showing 2d image when targed is detected

I have a question about the way how to show simple 2d image on top of detected marker. I have followed some tutorial to show 3d model and it works fine. there is no problem with 3d.
The problem starts when I want to add normal 2d object->sprite . When I add simple sprite I can't add texture and when I insert UI image it's added together with canvas and it is not showed when target is
detected. The original image on editor is placed then so far that it's difficult to find it.
I would be grateful if somebody can highlight me the right direction.
I need to make this image touch sensitive like a button. Clicking into it must show new scene ( I have it but under GUI.Button). The best way is to replace original marker but I can also make new sprite bigger to hide marker under it.
To help understand the answer, here's a quick rundown on how Vuforia handles marker detection. If you take a look at the DefaultTrackableEventHandler script that's attached to the ImageTarget prefab, you'll see that there are events that fire when the when the tracking system finds or loses an Image.
These are OnTrackingFound (line 67) & OnTrackingLost (line 88) in DefaultTrackableEventHandler.cs
If you want to show a Sprite when tracking, all you need to do is put the Image Target prefab (or any other) and make the Sprite a child of the prefab. The enabling and disabling should happen automatically.
However, in case you want to do something more, here's some edited code.
DefaultTrackableEventHandler.cs
//Assign this in the inspector. This is the GameObject that
//has a SpriteRenderer and Collider2D component attached to it
public GameObject spriteGameObject ;
Add the below lines to OnTrackingFound
//Enable both the Sprite Renderer, and the Collider for the sprite
//upon Tracking Found. Note that you can change the type of
//collider to be more specific (such as BoxCollider2D)
spriteGameObject.GetComponent<SpriteRenderer>().enabled = true;
spriteGameObject.GetComponent<Collider2D>().enabled = true;
//EDIT 1
//Have the sprite inherit the position and rotation of the Image
spriteGameObject.transform.position = transform.position;
spriteGameObject.transform.rotation = transform.rotation;
And the below to OnTrackingLost
//Disable both the Sprite Renderer, and the Collider for the sprite
//upon Tracking Lost.
spriteGameObject.GetComponent<SpriteRenderer>().enabled = false;
spriteGameObject.GetComponent<Collider2D>().enabled = false;
Next, your question about detecting clicks on this Sprite. Unity's Monobehaviour fires events for a lot of mouse events, such as OnMouseUp, OnMouseDown etc.
Link to Monobehaviour on Unity's API docs
What you will need is an event called OnMouseUpAsButton
Create a new script called HandleClicks.cs and add the below code to it. Attach this script as a component to the spriteGameObject that you assigned for the above.
public class HandleClicks : MonoBehaviour {
//Event fired when a collider receives a mouse down
//and mouse up event, like the interaction with a button
void OnMouseUpAsButton () {
//Do whatever you want to
Application.LoadLevel("myOtherLevel");
}
}