This question already has answers here:
How to detect click/touch events on UI and GameObjects
(4 answers)
Closed 4 years ago.
I'm a little new to unity and I'm unsure how to do this:
I've added a panel control to my app. I want to call a function on a script when the user touches the panel, and I want to receive the location of the touch in panel coordinates. None of the components seem to be able to do this. Maybe I have to write a bunch of raw code to watch all touches, do collision checks, etc?
The solution is to use Raycasting:
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
print("Hit something!");
}
}
The example tells you how, you only need to know if the thing you touched was your panel.
For this, you need to use RaycastHit, checking the transform's names can be a good way.
Related
I'm making a Pong game and i have no idea how can I make ball reset it's position after scoring a goal. Please help like really I need help I have seven days to complete this and convert this to Android but i havent even completed the main goal of the game. And I'm bad at English >:c
You could store the original position of the ball in a variable at the start of the program then reset its position when a goal is scored.
For example, if you have a Monobehaviour attached to your ball GameObject:
public class Ball : MonoBehaviour
{
private Vector3 originalPosition;
Void Start()
{
originalPosition = transform.position;
}
public void ResetPosition()
{
transform.position = originalPosition;
}
}
You can then reset the ball position by calling the Ball.ResetPosition() method.
Edit:
Don’t hesitate to provide more information about your current code structure/design if this answer doesn’t fit your desing.
There are many questions like this, but I didn't find a valid solution to my problem.
I would like to click an object behind a collider, this is my code:
void Update () {
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Debug.Log(hit.transform.name);
}
}
I put this code inside the script attached to the first object but the debug log will never be called.
Any ideas?
If I understand your question right, you want to click on the yellow sphere (see image) and want the name of the white cube?
There are two possible ways to do that:
1. Ignore Raycast Layer
You could give the yellow sphere the unity standard layer "Ignore Raycast":
Then your code should work (I added the on left mouse click)
void Update()
{
if (Input.GetMouseButtonDown(0)) // Click on left mouse button
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Debug.Log(hit.transform.name);
}
}
}
2. Use Layer Mask
See: Using Layers and Bitmask with Raycast in Unity
If that's not what you're looking for please give further information and a screen shot of your problem.
This question already has answers here:
How to detect click/touch events on UI and GameObjects
(4 answers)
Closed 4 years ago.
Is there way to call the onclick event from a raycast?
I have world scale canvas attached to an object that has images with buttons.
When I select the button with the mouse my event function is called.
But now I am trying to adjust the code so I can avoid using mouse all together.
[SerializeField]
private Image cursor;
[SerializeField]
private LayerMask uI;
if (Input.GetButtonDown("Fire1"))
{
Ray ray = Camera.main.ScreenPointToRay(cursor.transform.position);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100,uI))
{
Debug.Log(hit.collider);
}
}
This is the code I use to raycast into the world space canvas which works and returns the images but I am not sure how I can now call the onclick event since I am not using the mouse but a image instead
Is there way to call the onclick event attached to image that I raycast to or do I have to redo my entire script and not use on click events?
Hen you hit a GameObject, get its list of components that implement OnPointerClick event
IPointerClickHandler clickHandler=collider.gameObject.GetComponent<IPointerClickHandler>();
once you have that reference (its not null) you can call
PointerEventData pointerEventData=new PointerEventData(EventSystem.current);
clickHandler.OnPointerClick(pointerEventData)
That should do the job
I believe that the Button component does what you seek as well.
But to answer your question about raycasts.
Is there way to call the onclick event from a raycast?
//Example raycast code
//Variables
public RayCastHit _Hit;
public LayerMask _RaycastCollidableLayers; //Set this in inspector, makes you able to say which layers should be collided with and which not.
public float _CheckDistance = 100f;
//Method
void PerformRaycast(){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out _Hit, _CheckDistance + 0.1f, _RaycastCollidableLayers);
if (_Hit.collider == null)
{
Debug.Log("Raycast hit nothing");
return null;
}
GameObject go = _Hit.collider.gameObject;
}
Your raycast hits an object and stores a reference to that object. As you can see in my example you can fetch the game object through the RaycastHit.
When you have the game object you can access any scripts on it through GetComponent<>(), this means you can say.
GameObject go = _Hit.collider.gameObject;
OnClickScript ocs = go.GetComponent<OnClickScript>();
ocs.OnClick();
If I misunderstood your query, please let me know.
This question already has answers here:
How to detect click/touch events on UI and GameObjects
(4 answers)
Closed 5 years ago.
In the code below, my issue is the parent object has two child objects, so whenever I click any child object, it is recognized twice. How can I get the mouse click to recognize only the child game object that is clicked and not both? Note that the parent object was made with an empty script. Please check the code below:
void Update() {
if (Input.GetMouseButtonDown(0)) {
Debug.Log("Pressed left click, casting ray.");
CastRay();
}
}
void CastRay() {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100)) {
Debug.DrawLine(ray.origin, hit.point);
}
}
If you have your script in each child, they will each be generating a ray and both recognizing that an object is hit (thus showing it twice). What you want to do instead is have one script in the parent. You can have this script check for the name of the gameobject that the ray hits in order to determine what action should occur.
Edit: Since you have a 2D scene you will need to do the following:
void CastRay()
{
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit.collider != null && hit.collider.gameObject.name == "object1")
{
// do something for gameobject with name of object1
}
}
I use the following to detect if something is in front of my avatar:
void Start()
{
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, 10))
Debug.Log("Something in front");
}
Now, I am trying to find out if only a specific object is in front, for example another avatar with the name Police in the hierarchy:
public class CharAnim : MonoBehaviour
{
police = GameObject.Find("Police");
void Start()
{
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, 10))
Debug.Log("Something in front");
}
}
However, from the documentation, I cannot see if it is possible to use this police variable to detect it through ray-casting, measuring distance to it, etc...
How do I implement this?
The last answer doesn't take into account that things can actually block the raycast from even reaching your desired object.
You must first give the object you want to detect a custom layer.
Then you have to shoot a raycast which will penetrate and ignore all layers except for the desired one, like so:
Please note: This example assumes you used custom layer #9:
float distance = 10;
int layer = 9;
int layerMask = 1<<layer;
if (Physics.Raycast(transform.position, fwd, distance, layerMask))
Debug.Log("Something in front");
You really shouldn't mark answers as accepted unless they have actually solved the problem, because questions with answers marked as accepted receive substantially less attention from people who would otherwise potentially be able to solve it for you.
RaycastHit hit;
if (Physics.Raycast(transform.position, fwd, hit,10) && hit.collider.gameObject.tag == "police" )
{
// do stuff here
}
Note that you need to set the tag of the gameObject from the editor. you could also use gameObject.name .