Reputation: 20901
I spawn objects that have laser beam property. When I click on one of them(specific object), I want it to only show its laser beam not the others.
How can I prevent it? I have a static GameObject
variable (touch_detect.clickedObject
) by which I can determine which object is clicked.
using UnityEngine;
using System.Collections;
public class Laser : MonoBehaviour
{
private LineRenderer lr;
private bool clicked = false;
RaycastHit rh;
// Use this for initialization
void Start()
{
lr = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(ray, out rh, Mathf.Infinity))
{
if (rh.collider.gameObject.name == touch_detect.clickedObject.name)
{
Debug.Log(rh.collider.gameObject.name + " clicked.");
Debug.Log("static object name" + touch_detect.clickedObject.name + " clicked.");
clicked = true;
lr.enabled = true;
}
}
}
if (Input.GetMouseButtonUp(0))
{
if (Physics.Raycast(ray, out rh, Mathf.Infinity))
{
if (rh.collider.gameObject.name == touch_detect.clickedObject.name)
{
Debug.Log(rh.collider.gameObject.name + " clicked.");
Debug.Log("static object name" + touch_detect.clickedObject.name + " clicked.");
clicked = false;
lr.enabled = false;
}
}
}
if (clicked)
{
lr.SetPosition(0, transform.position + new Vector3(0, 0, 0));
RaycastHit hit;
if (Physics.Raycast(transform.position + new Vector3(0, 0, 0), -transform.up, out hit))
{
if (hit.collider)
{
lr.SetPosition(1, hit.point);
}
}
else lr.SetPosition(1, -transform.up * 5000);
}
}
}
Upvotes: 2
Views: 323
Reputation: 4343
The issue is that since this script is attached to both of your gameobjects, there are two rays being cast at the mouse position (one from each script). Because you are just looking to see that the raycollider matches the static object, this statement is true for both scripts no matter which you click on:
if (rh.collider.gameObject.name == touch_detect.clickedObject.name) // always true
To get an immediate fix, you should change the above statement to something like this to check that the ray is intersecting the same gameobject that the script is attached to:
if (rh.collider.gameObject.name == gameObject.name)
This really is not the best method though since you are still casting two rays and therefore doing all the logic twice (or more times if you spawn more cubes). A better method would be to have one master gameobject that casts the ray. When this ray intersects a cube, you would then activate a method inside that cubes script to show the laser. So for example:
on the master object you would have:
if (Physics.Raycast(ray, out rh, Mathf.Infinity))
{
// add a tag to all objects with the laser script
if (rh.collider.gameObject.tag == "hasLaser") //verify object has laser script via tag
rh.collider.GetComponent<laser>().activateLaser(); // call public method in collider script
}
and then the cube would have the laser script with a public method:
public void activateLaser()
{
lr.enabled = true;
}
Upvotes: 2