Create a prefab object into the scene exactly where the mouse is pointing
Hello Guys,I am new to Unity and I would like your help if it is possible. I made a new window like a level editor and I made a button there called "cube". I have a prefab cube and I would like when I click the button "Cube" to go into the scene and start drop prefab cubes exactly where my mouse is pointing. I tried a lot before such as rays and Event.mousePosition but I couldn't make it to work. I guess that is has to be done with a Ray but as I told you I am new and I make something wrong. I will appreciate any help.
Answer by MakeCodeNow · Sep 17, 2015 at 03:04 AM
You've got the right idea. You need to use the Event.mousePosition, use Camera.ScreenPointToRay to convert that into a Ray, and then intersect that Ray with the world. The question is, how do you intersect the ray with the world. If you want to check against collision, use Physics.Raycast. However, it's possible that this returns no results (like in an empty scene). In that case, you probably want to place the object where the ray intersects the XY plane. To do that, you need to create a Plane object and use it's Ray intersection method to compute where the ray and plane intersect.
Answer by Squallara · Sep 17, 2015 at 07:14 AM
Thank you for your Answer. This is my code of my window:
using UnityEditor;
using UnityEngine;
using System.Collections;
public class LevelEditor : EditorWindow
{
// Add menu item named "My Window" to the Window menu
[MenuItem("Window/Level Editor")]
public static void ShowWindow()
{
//Show existing window instance. If one doesn't exist, make one.
EditorWindow.GetWindow(typeof(LevelEditor));
}
//It is a method like for display things in our Editor
void OnGUI()
{
//GUILayout.Button("...") creates a button named ... to our Window Editor
if(GUILayout.Button("Cube"))
{
CreateCubes.OnSceneGUI();
}
}
}
and this is the code I try to cast the ray:
using UnityEngine;
using System.Collections;
using System;
using UnityEditor;
public class CreateCubes : Editor
{
public static void OnSceneGUI()
{
Debug.Log("You clicked Button");
if (Event.current.type == EventType.MouseDown)
{
Ray ray = Camera.main.ScreenPointToRay(Event.current.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit, 1000.0f))
{
Debug.Log(Event.current.mousePosition);
Vector3 newTilePosition = hit.point;
Instantiate((GameObject)Resources.Load("prefabs/WholeCube", typeof(GameObject)), newTilePosition, Quaternion.identity);
}
else
{
Debug.Log ("Problem with the Physics");
}
}
else {Debug.Log ("Ray didn't get value");}
}
}
I get the log "You clicked Button" and "Ray didn't get value" Why?
Is your code here correct? the way it's written, "You clicked button" will always happen and "Ray didn't get value" happens anytime Event.current.type is not equal to EventType.$$anonymous$$ouseDown.
Basically, your logging doesn't match the logic.
Also, if your scene is empty, Raycast will always fail. See my original answer regarding doing by physics raycasts and Plane intersections.
Yes I found out the most of them. These are my codes now:
using UnityEditor;
using UnityEngine;
using System.Collections;
public class LevelEditor : EditorWindow
{
bool GUI$$anonymous$$eyDown($$anonymous$$eyCode key)
{
if (Event.current.type == EventType.$$anonymous$$eyDown)
return (Event.current.keyCode == key);
return false;
}
// Add menu item named "$$anonymous$$y Window" to the Window menu
[$$anonymous$$enuItem("Window/Level Editor")]
public static void ShowWindow()
{
//Show existing window instance. If one doesn't exist, make one.
EditorWindow.GetWindow(typeof(LevelEditor));
}
void OnGUI()
{
GUILayout.Button("Cube");
if (GUI$$anonymous$$eyDown($$anonymous$$eyCode.C))
{
CreateCubes.OnSceneGUI();
}
}
}
I made a shortcut for placing the cubes with "C" button.
The code for creating them is:
using UnityEngine;
using System.Collections;
using System;
using UnityEditor;
public class CreateCubes : Editor
{
public static void OnSceneGUI()
{
Debug.Log("You clicked Button");
if (Event.current.type == EventType.$$anonymous$$eyDown)
{
Ray ray = Camera.main.ScreenPointToRay(Event.current.mousePosition);
Debug.Log(ray);
RaycastHit hit = new RaycastHit();
Debug.Log(Physics.Raycast(ray, out hit, 1000.0f));
Debug.DrawRay(ray.origin, ray.direction, Color.red, 3);
if (Physics.Raycast(ray, out hit, 1000.0f))
{
Debug.Log(Event.current.mousePosition);
Vector3 newTilePosition = hit.point;
Instantiate((GameObject)Resources.Load("prefabs/WholeCube", typeof(GameObject)), newTilePosition, Quaternion.identity);
}
else
{
Debug.Log ("Problem with the Physics");
}
}
else {Debug.Log ("Ray didn't get value");}
}
}
I changed the condition "(Event.current.type == EventType.$$anonymous$$eyDown)".
I forgot to mention that I have a plane already in my scene. Now it seems to working but my problem is that the cubes aren't placing exactly at my mouse position. Do you know why? $$anonymous$$aybe if I change the camera.main to camera.current? Thank you once again for you time.
I think your original question has been answered. Now you just need to do more debugging. Please mark the question as answered and go to the forums if you want more help with debugging your code.