Unity3d with vuforia showing 2d image when targed is detected - unity3d

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");
}
}

Related

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

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.

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

Camera rotation within a prefab

I am trying to create a multiplayer game in unity3d using a diablo like camera system. So wherever I click on the screen. The system it was working fine in singleplayer where I did not need to include a camera in a player prefab. However Now I am facing the problem where my camera rotation is also affected by the rotation of my prefab parent. The hierarchy looks like this:
There is a script added to the camera that looks like this:
using UnityEngine;
using System.Collections;
public class MainCameraComponent : MonoBehaviour {
public GameObject Reaper;
private Vector3 offset;
void Start () {
offset = transform.position - Reaper.transform.position;
}
// Update is called once per frame
void LateUpdate () {
transform.position = Reaper.transform.position + offset;
}
}
When I run the game the camera always stays behind my character, while I want it to always stay at the same rotation. so if I order my character to walk north I would see his back, if it would walk south I wanted to see the front.
notice how the shadow changes, (thus the rotation) but i always face the back of my model. TLDR: I want my child camera to ignore the rotational change of its parent and be static. whilst letting my camera position be guided by its parent. as far as I know it seems impossible to make a networkmanager instantiate a new player prefab and attach a camera afterwards on the same hierarchy level.
Any help would be greatly appreciated.
However Now I am facing the problem where my camera rotation is also
affected by the rotation of my prefab parent
That's because your Camera is a child of the player so it will do whatever the Player/parent is doing.
Your camera should not be under the player. Remove it and make sure it is not a child of the Player or any other Object. That script should work or make the camera follow the player without making the Camera the child of the GameObject.
Remove Player = GameObject.Find ("Player"); from the LateUpdate function. You have already done this in the Start function, so it is unnecessary to do it in the LateUpdate function. GameObject.Find ("Player"); should never be called directly from the LateUpdate function. It will slow down your game.
EDIT:
After reading your comment, it looks like you want to instantiate a player with the camera. You can do this without making the camera a child of your player.
Your current Setup:
Player
Model
Projectile
Projectile Mesh
Camera
So your camera is under Player.
You new Setup:
PlayerPrefab
Player
Model
Projectile
Projectile Mesh
Camera (Attach script in question to this)
Camera is now PlayerPrefab instead of Player. Now, you can instantiate PlayerPrefab and move the Player with a script. I don't know what your move script looks like but it should be attached to the Player not PlayerPrefab. The PlayerPrefab is used to hold everything so that it can be easily instantiated as one. The code in your question should be attached to your Camera.

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.

unity | disable eventsystem module input for one gameobject

I have a eventsystem with 2 inputmodules (gaze (for cardboard) and touch). The gazeinput is above de touchinput, so that is going to be used by unity as main inputmodule. Now i have 1 object that i want to trigger on touchinput, but that is not working because of the gazeinput. So my question is if it is possible to disable the gazeinput just for this 1 gameobject?
EDIT: the object is a menu button, located in the bottom-right corner. It moves with the camera.
thanks
use raycast. when your camera is seeing the gameobject on which you want to use the touch input. detect that the user is looking at the camera via raycast.
Attach a script (to the camera or an empty gameobject) that has the reference of both the input modules
When the player looks at the object(detected through raycast) in which you want to use the touch input. Simply disable the gazeinput.
And when the player looks away from that gameObject enable the gazeinput