Turn Sub-Object Code (raycast & mouse click & sub-objects) - unity3d

Game characters are going somewhere that is clicked with the mouse
My problem : the code only works over a GameObject. I want to use one in the ground in the box, it can not.
I use a line of code :
public GameObject obj;
void Update() {
if(Input.GetMouseButton(0)) {
RaycastHit rayHit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (obj.collider.Raycast (ray, out rayHit, Mathf.Infinity)) {
transform.position = rayHit.point;
renderer.material.color = Color.green;
}
}
}
Map as the only model so I need to do. prevents me from making changes to my map
I need to call the individual sub-objects. but I could not.
Translating google translate :)

Try using Physics.Raycast(ray, out rayHit). This will raycast from your screen into the world. Then you can check the type of the object:
if (rayHit.collider.GetType() == typeof(YourTypeHere))
{
doSomething();
}

Related

how to detect which gameobject is clicked

I want to know which gameobject is clicked with mouse on a 2D project
I used
void Update()
{
if (Input.GetMouseButtonDown(0))
{
clickTime = DateTime.Now;
mousePosition = Input.mousePosition;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
if (hit != null && hit.collider != null)
{
}
}
}
but it never goes in the second if condition
EDIT: I am working on a single script and access all gameobject from there using GameObject.FindGameObjectWithTag() and as I understand thats why the collider code in main script doesnt triggered.
I added a screenshot my code is in GameObject
This method works perfect on both desktop and mobile apps:
Add a collider component to each object you want to detect its click event.
Add a script to your project (let's name it MyObject.cs).
This script must implement the IPointerDownHandler interface and its method. And this script must add the Physics2DRaycaster to the camera. The whole body of this script could be like this:
public class MyObject : MonoBehaviour, IPointerDownHandler
{
private void Start()
{
AddPhysics2DRaycaster();
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
private void AddPhysics2DRaycaster()
{
Physics2DRaycaster physicsRaycaster = FindObjectOfType<Physics2DRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}
}
Add the MyObject.cs script to every object you want to detect click on it. After that, when you click on those objects, their name will display on Console.
Make sure that EventSystem exists in your project's Hierarchy. If not, add it by right click.
P.S. The MyObject.cs script now has IPointerDownHandler. This detects click as soon as you touch the objects. You also can use IPointerUpHandler and IDragHandler for different purposes!
and sorry for my bad English.
When you use a raycast you should set a collider on your sprite
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
if (hit.collider != null) {
Debug.Log ("CLICKED " + hit.collider.name);
}
}
}
This is working for me in unity 5.6
Note: "LeftClick" is just a "GameObject" nothing else, I called it like this for better identification :)
EDITED
I test this method for the UI button but it's not working; so I used a different approach. For the UI button you can add a listener like this:
GameObject.Find ("YourButtonName").GetComponent<Button> ().onClick.AddListener (() => {
});
Consider using OnMouseOver() method (docs):
private void OnMouseOver() {
if (!Input.GetMouseButtonDown(0)) return;
// Your logic here.
}
This method only works with collider attached to gameobject, just like Raycast.
It would be cleaner and slightly more performant because there are no multiple Update() methods to iterate each frame. Something to keep in mind if you have dozens or hundreds of clickable objects.
(Although there are reports that this method doesn't work with multiple cameras one of which is ortographic one, in which case it is not an option for you.)

Moving GameObject with RayCast hit position causing object to move towards Raycast start position

I have RayCast represented by a LineRenderer in Unity, so it looks like a laser. I want this laser to move objects it collides with so that the object follows the hit.point of the Raycast hit.
My code doesn't work, because I move these GameObjects to the hit.point, which causes the object to comes towards the start point of the Raycast, because a new hit.point gets calculated since the object is moving to hit.point. I understand why this is happening, but I'm not sure how to get the object to move with the Raycast, but not effect a new hit.point.
Here's my update function in my script attached to my Laser GameObject. Does anyone know how I can fix my code so that the object moves with the hit.point?
void Update()
{
Vector3 target = calculateDeltaVector();
lr.SetPosition(0, palm.transform.position);
RaycastHit hit;
if (Physics.Raycast(palm.transform.position, target , out hit))
{
if (hit.collider)
{
lr.SetPosition(1, hit.point);
if (hit.transform.gameObject.tag == "Chair")
{
GameObject chair = hit.transform.gameObject;
// !!! move object to hit point, problem HERE
chair.transform.position = hit.point;
hitLock = false;
}
}
}
else lr.SetPosition(1, target * 50);
}
In Unity Inspector, you can select the object and change the layer to "2: Ignore Raycast" This will make the raycast ignore the object and go through it.
Don't know, but your code should move the chair to the chair, which likely will make the chair go towards you.
You have to implement Begin and End the raycast move, e.g using mouse click.
Below is the example
public class Mover : MonoBehaviour
{
public Collider selectedChair;
void Update ()
{
Vector3 target = calculateDeltaVector();
lr.SetPosition(0, palm.transform.position);
RaycastHit hit;
if (Physics.Raycast(palm.transform.position, target , out hit))
{
if (hit.collider)
{
lr.SetPosition(1, hit.point);
if (hit.transform.gameObject.tag == "Chair" && Input.GetMouseButton(0)) //if you want to move it you have to click mouse button first
{
selectedChair = hit.collider;
hit.collider.enabled = false; //disable the collider of currently selected chair so it won't go towards you
}
if (selectedChair)
{
// !!! move object to hit point, problem HERE
selectedChair.transform.position = hit.point;
hitLock = false;
}
if (Input.GetMouseButton(0))
{
selectedChair.enabled true;
selectedChair = null; //release it
}
}
}
else lr.SetPosition(1, target * 50);
}
}

Click and object, then click the ground, make object move to that position

Hi there I'd like to be able to click on an object then click a position on a plane and would like my object to lerp to that mouse clicked position. The problem is doing this for more than one object becomes tricky. Anybody got any ideas? so far I have followed the tutorial on Coroutines on unity3D's website under the advanced scripting tutorials. here is the code:
attached to the game object:
private Vector3 target;
public float smoothing = 7f;
public Vector3 Target
{
get{return target;}
set
{
target = value;
StopCoroutine("Movement");
StartCoroutine("Movement",target);
}
}
IEnumerator Movement(Vector3 target)
{
while (Vector3.Distance(transform.position,target) > 0.05f)
{
transform.position = Vector3.Lerp(transform.position, target, smoothing* Time.deltaTime);
yield return null;
}
}
attached to the plane:
public propertiesandcoroutines coroutinescript;
private float Deltapos = 0.5f;
private GameObject collobj;
public void OnMouseDown()
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
Physics.Raycast (ray, out hit);
if (hit.collider.gameObject == gameObject)
{
coroutinescript.Target = new Vector3( hit.point.x,hit.point.y + Deltapos,hit.point.z);
}
}
this code works perfectly for one game object. how can I change this to work for a game object that I click on?
You just need to add a couple of lines to each script to get the result you want.
To the script attached to your moveable GameObjects
//This is the same type as the script attached to your plane. Rename it
//to whatever it's actually called (I've just called it PlaneScript). Also
//drag the plane into this field for each of the moveable GameObjects in the inspector
public PlaneScript planeScript;
//Paste this method anywhere inside the script attached to the GameObjects
void OnMouseUpAsButton () {
planeScript.SetObjectToMove(this);
}
Now, in the script attached to your plane, add the following
public void SetObjectToMove (propertiesandcoroutines script) {
coroutinescript = script;
}
How it works
Basically, what we're doing here is when one of your GameObjects are clicked, we reassign the "coroutinescript" variable in the script attached to the plane.
So, when the plane is clicked, the last GameObject that was clicked on before clicking the plane is moved.

How to Drag Objects in unity3D?

I am new to unity. I am working on cake maker like game for android device. I am facing a difficulty in dragging objects from cabinet to table. On table i want to mix them in a jar. These are Many items. So, I cannot do it by separating them using unity Tags. How to make a generic way to drag them on table?
I am using this code but its not working for me.
using UnityEngine;
using System.Collections;
public class DragObjects : MonoBehaviour {
Ray ray;
RaycastHit hit;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit))
{
if (hit.collider.tag == "oil")
{
OnMouseDrag();
}
}
}
}
void OnMouseDrag()
{
Vector3 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
point.x = gameObject.transform.position.x;
gameObject.transform.position = point;
}
}
The Unity way of doing this would be to have a Draggable behaviour which you attach to each object you wish to drag.
If you are using 2D colliders you can use something like this:
Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
bool isOver = collider2D.OverlapPoint(pos);
With 3D colliders you can get a ray from the camera and see if that intersects with a draggable.
Then you can use other colliders to detect when they are placed on the jar.

Create a copy of an gameobject

How do you create a copy of an object upon mouse click in Unity3D?
Also, how could I select the object to be cloned during run-time? (mouse selection preferable).
function Update () {
var hit : RaycastHit = new RaycastHit();
var cameraRay : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (cameraRay.origin,cameraRay.direction,hit, 1000)) {
var cursorOn = true;
}
var mouseReleased : boolean = false;
//BOMB DROPPING
if (Input.GetMouseButtonDown(0)) {
drop = Instantiate(bomb, transform.position, Quaternion.identity);
drop.transform.position = hit.point;
Resize();
}
}
function Resize() {
if (!Input.GetMouseButtonUp(0)) {
drop.transform.localScale += Vector3(Time.deltaTime, Time.deltaTime,
Time.deltaTime);
timeD +=Time.deltaTime;
}
}
And you'll want this to happen over course of many calls to Update:
function Update () {
if(Input.GetMouseButton(0)) {
// This means the left mouse button is currently down,
// so we'll augment the scale
drop.transform.localScale += Vector3(Time.deltaTime, Time.deltaTime,
Time.deltaTime);
}
}
The simplest way (in c#) would be something like this:
[RequireComponent(typeof(Collider))]
public class Cloneable : MonoBehaviour {
public Vector3 spawnPoint = Vector3.zero;
/* create a copy of this object at the specified spawn point with no rotation */
public void OnMouseDown () {
Object.Instantiate(gameObject, spawnPoint, Quaternion.identity);
}
}
(The first line just makes sure there is a collider attached to the object, it's required to detect the mouse click)
That script should work as is, but I haven't tested it yet, I'll fix it if it doesn't.
If your script is attached to a GameObject (say, a sphere), then you can do this:
public class ObjectMaker : MonoBehaviour
{
public GameObject thing2bInstantiated; // This you assign in the inspector
void OnMouseDown( )
{
Instantiate(thing2bInstantiated, transform.position, transform.rotation);
}
}
You give Instantiate( ) three parameters: what object, what position, how is it rotated.
What this script does is it instantiates something at the exact position & rotation of the GameObject this script is attached to. Oftentimes you will need to remove the collider from the GameObject, and the rigidbody if there is one. There a variations in ways you can go about instantiating things, so if this one doesn't work for you I can provide a different example. : )