show text when clicking on a 3D object - c#

I am fairly new to Unity and am currently working on a small project.
My problem is this.
I want to display text when I click on the cube.
I have a total of four different cubes, all of which should display different text when clicked.
The solution I have so far works, but of course now when I click on the cubes the same text comes up and if I assign each cube its own text they all appear at once.
The cubes should also rotate and when clicked on just stop and display the text.
I tried it with the Event Trigger System and assign different texts, but without success.
Any suggestion for a solution?
I tried it with the Event Trigger System and assign different texts, but without success.
Any suggestion for a solution?
enter image description here

You are using input.GetMouseButtonDown, when you click anywhere all
the boxes run the same code, you don't specify which box is clicked
you only looking for a click, I suggest you use raycast to send a
ray to detect which box you are clicking and run ,
Add this script to the camera or player and give all the boxes gameobject a "Box" Tag :
void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Transform objectHit = hit.transform;
if (objectHit.CompareTag("Box"))
{
objectHit.GetComponent<Rotator>().RotateObject();
}
}
}
}
add this function to the Rotator Script and remove the code from update :
public void RotateObject()
{
if (rotateObject)
{
rotateObject = false;
Text.SetActive(true);
}
else
{
rotateObject = true;
Text.SetActive(false);
}
}
}

Related

How can I change/set the 3d cube clicking area?

Since the keypad don't have buttons I added cubes to each number and attached a script to each cube so when clicking on a cube it will show it's number in the top area.
For example Key 1 (Cube) when I click on it when the game is running it's not firing the click on all the cube area same for all the other cubes :
When I click on the cube of key 1 it's working only on the left bottom area mostly on that sides. Even if the cube is covering the whole key area.
This is how it looks like when I uncheck the cubes mesh renderer :
Then when running the game and clicking on a cube : it's showing the number in the Security Keypad Text(Text Mesh)
This is the script attached to each cube :
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
public class SecurityKeypadKeys : MonoBehaviour
{
public TextMesh text;
private void Start()
{
text = GameObject.Find("Security Keypad Text").GetComponent<TextMesh>();
}
private void OnMouseDown()
{
string[] digits = Regex.Split(transform.name, #"\D+");
foreach (string value in digits)
{
int number;
if (int.TryParse(value, out number))
{
text.text = value;
}
}
}
}
The main problem is that on most of the cubes you need to click on specific point/small area to make it work and I want it to be working trigger when you click on each cube at any place on the cube.
Try the RaycastExample by robertbu code here and put it on a script. OnMouseDown() requires nothing else be in the way. That code will tell you if something is in the way. Also, try moving everything closer as OnMouseDown() has a depth limit to its raycast.
I recreated your above example, and it works perfectly, so something else must be wrong.

Open kitchen cupboard on keypressed with Unity

I have recently downloaded a cabinet kitchen → https://www.cgtrader.com/3d-models/interior/kitchen/ca-5cd9388f-0be1-4cea-ab44-bc1b493f590f
So everything basically works fine, however, I've added a player controller and I want for each cupboard, that the player press E to open it. I'm having some serious difficulties with that though since every cupboard opens instead of only one and I don't know how to focus on only one at the time, maybe adding a box collider for when the player is close to a cupboard?
Plus, I've found two different types of keypressing :
→ Input.GetKeyDown(KeyCode.E) = which slightly opens every cupboard but not entirely
→ Input.GetKey("e") = which fully opens every cupboard but you have to keep pressing E and this is not what I want.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Door : MonoBehaviour {
public bool isopen;
public float speed;
[SerializeField]
float Open,Close;
private void Awake()
{
}
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetKey("e"))
{
isopen = true;
Quaternion open = Quaternion.Euler(Open, 90, 90);
transform.localRotation = Quaternion.Slerp(transform.localRotation, open, Time.deltaTime * speed);
}
else
{
isopen = false;
Quaternion close = Quaternion.Euler(Close, 90, 90);
transform.localRotation = Quaternion.Slerp(transform.localRotation, close, Time.deltaTime * speed);
}
}
void PlayAnim()
{
print("hit");
if (isopen)
{
isopen = false;
}
else
{
isopen = true;
}
}
}
Here is my 'HIT' script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class hit : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100.0f))
{
hit.transform.SendMessage("PlayAnim");
}
}
}
}
However, the script works only for my drawers but not for my cupboard which are all slightly opened when E is pressed.
But when the player looks at a drawer, they press E and only the drawer they focused opens, same steps for closing it.
I've added the HIT script to my cupboards though...
So, I would like to be able to open a single cupboard when needed, and press E again to close it.
How am I supposed to do? Any directions?
Thank you very much guys.
This problem would best be solved by breaking it into parts: Selecting a cupboard with a key, making it open/close and running the animation.
If you are using a first person view, you could check which cupboard the player is looking at by casting a ray using Physics.Raycast() from the position of the camera at the direction it is looking at. If the resulting RaycastHit collided with a cupboard, this one will need to open. By the way, GetKeyDown() fires once on a single Update() when the key is pressed, GetKey() fires as long as the key is held. You want to only fire once and keep the animation running by itself from then, so use GetKeyDown(). You would probably not want to use a box collider for that, as the player could open a cabinet behind him, just by rubbing his back against it and pressing "e".
Then, in a different script attached to the cupboards, you have to have a function to open/close them. As soon as it is called, you check whether it is currently moving, and if not, start the animation.
The animation will need to rotate the door on every frame in Update() until it reached the target position. By saving how far it moved already and whether it is closing or opening in variables, this should be rather easy to achieve because you already managed to make them rotate in the right way.
It finally works! I have added the hit script and Physics.RayCast and edited the Door script. Now I have to figure out how to add the text canvas and makes it disappear when needed.
Thank you anyways!

unity2d prevent ui button from being clicked when raycast2d hit

I have a gameobject with collider2d which was designed to be clickable, and I also Have an UI button which will follow the camera while player moving, the thing is they may overlap sometimes, and when they overlap, when user click the overlap area, I am sure that user want to click the object (which was do by raycast2d hit) so I should prevent the button to be clicked.
The script for the raycast implantation of clickable gameobject is as following:
private void checkTouch()
{
if (Input.touchCount > 0 || Input.GetMouseButtonDown(0))
{
Vector2 rayPos = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
RaycastHit2D hit = Physics2D.Raycast(rayPos, Vector2.zero, 0f);
if (hit)
{
Debug.Log(hit.collider.gameObject + "is hit");
IInputBehavior inputBehavior = hit.collider.gameObject.GetComponent<IInputBehavior>();
//IInputVehavior was a self-desgined C# interface which has a `OnClick()` method.
if (inputBehavior != null)
{
//here we should prevent the UIButton to be clicked, but how?
inputBehavior.OnClick();
}
}
}
}
Okay so I'm at work so I can't give you the exact code but I can point you in the right direction. When you made the canvas originally it should have generated an event system ( as a game object in the scene somewhere ), you need to reference this in your game object that you want to not click when the ui is over it.
In your game object it's something like this:
if(GetComponent<EventSystem>().IsPointerOverGameObject) {
// The mouse is obscured by a UI element
} else {
// The mouse is not over a UI element
}
https://docs.unity3d.com/ScriptReference/EventSystems.EventSystem.IsPointerOverGameObject.html

Detect which GameObject Touched?

I have 3 Game Objects. These 3 Game Objects are my right , up and left buttons.
But I have no idea to control and check which of them clicked to action on player !
Note : I can do this by creating special C# for each of game objects
by using OnMouseDown Method but I want do this in one Script file
attached to player .
and this is one of my Game Objects for Control Player
Note : I can do this by creating special C# for each of game objects
by using OnmouseDown Method but i want do this in one Script file
attached to player .
This shouldn't be a problem at-all. You can have two scripts communicate with each other.
Method 1:
Notify the PlayerController script when there is a click action from other script.
Attach to each GameObject to detect click on. It sends the GameObject that was clicked to your PlayerController script.
public class ClickDetector: MonoBehaviour
{
PlayerController playerController;
void Start()
{
playerController = GameObject.Find("GameObjectPlayerControlIsAttachedTo").GetComponent<PlayerController>();
}
void OnMouseDown()
{
//Notify our PlayerController script that there was a click
playerController.OnGameObjectClicked(this.gameObject);
}
}
Add this to your PlayerController script. It receives the GameObject that was clicked. You can compare with the GameObject name or tag. I suggest you go with a tag.
public class PlayerController: MonoBehaviour
{
public void OnGameObjectClicked(GameObject objClicked)
{
Debug.Log("There was a click from: "+objClicked.name);
if (objClicked.CompareTag("right"))
{
//Your code
}
else if (objClicked.CompareTag("left"))
{
//Your code
}
else if (objClicked.CompareTag("up"))
{
//Your code
}
}
}
Method 2:
Do everything in one script (PlayerController).
You can use a raycast. I suggest you use tag to compare which gameobject is clicked. Create 3 tags(right,left and up) from the Editor and put each GameObject to the right tag. If you don't want to use tag, you can replace the if (rayCastHit.collider.CompareTag("up")) with if (rayCastHit.collider.name=="up").
void Update()
{
//Check if Mouse Button is pressed
if (Input.GetMouseButtonDown(0))
{
//Raycast from mouse cursor pos
RaycastHit rayCastHit;
Ray rayCast = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(rayCast, out rayCastHit))
{
if (rayCastHit.collider.CompareTag("right"))
{
//Your code
}
else if (rayCastHit.collider.CompareTag("left"))
{
//Your code
}
else if (rayCastHit.collider.CompareTag("up"))
{
//Your code
}
}
}
}
EDIT:
After updating your question, you need to attach a collider to your GameObjects for raycast to work. Attach Box Collider 2D to each of the 3 GameObjects.
Also, since this is a 2D sprite, The code for Method 2 changes a little bit:
if (Input.GetMouseButtonDown(0))
{
Vector2 ray = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D rayHit = Physics2D.Raycast(ray, Vector2.zero);
if (rayHit)
{
if (rayHit.collider.CompareTag("up"))
{
}
}
}
Finally, from what you are doing, it looks like you need a Virtual JoyStick and you are current doing it wrong. The current solution should work for you but the right way to do this is with the UI system (Image component).

Create a simple button in Unity3D 2D mode

I'm working on a 2D game in Unity 3D, v4.5. I have added some sprites to the Hierarchy. How do I add a button to the hierarchy? I already have a designated button.png that should display as the button. Should I turn a sprite into a button?
What I tried so far:
Someone noted GUI.Button, but
1: It has to be done in code - I assume we can add buttons to the game UI inside Unity GUI (??)
2: Even using GUI.Button from script, that class adds a border around the specified texture. I also haven't figured out how to use the existing image and size (width/height) of the sprite as the texture that is sent to GUI.Button.
you can useOnGUI for button and to disappear the rectangle you have to make a new GUIStyle
private GUIStyle testStyle = new GUIStyle();
public Texture2D Texture1;
void OnGUI(){
if( GUI.Button( new Rect (0, 0, 100, 100) , texture1 ,testStyle) )
{
//doSomething if clicked on
}
}
if you dont want that you can do a raycasting your selfand give your buttons tags like below
void Update () {
if (Input.GetMouseButtonDown (0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
if(hit.collider.tag=="play")
//DoSomething
}
}
}
in unity 4.6 UI you can add listeners to buttons in script like below
private Button MyButton = null; // assign in the editor
void Start()
{
MyButton.onClick.AddListener(() => { somefunction(); });
}

Categories

Resources