I would like to create gameObjects (text, 3d stuff, etc.) from scripts and save them in the scene.
For example: If I use a script like this,
public class ExampleClass : MonoBehaviour
{
public void Start()
{
GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
}
}
the "plane" will be add in Hierarchy temporarily (just after you press start).
I'm looking for some way to create a lot of gameObjects automatically (through a script, api, etc.) and save them in the hierarchy.
you are talking of persistent GameObject after stopping scene i suppose.
The only possibility to make gameObject instance pop inside your scene hierarchy and stay after scene played and stopped is to use CustomEditors.
You have to know, unity editor is based on Unity Gui, so you can easily add buttons make it run some specific script coded by you, inside windows menu (for example).
But you can also custom the mouse right click on scene hierarchy to allow peoples to create instances of a allowed gameObject and add this created instance directly on child of previously clicked gameobject from the scene etc...
Or make create your own tools script, and add it as component on Gameobject and with specific layout for it and rendered by Unity Editor.
For use customEditor step by step :
1 - Create a folder named Editor inside Assets/ root project hierarchy
2 - Create a script like bellow, which is using reference to UnityEditor and add you could use the commented Attribute. At the end you have to make your class extend From Editor class.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
// uncomment this line bellow if you want to create customEditor script which you will be able to use on gameObject as component.
// typeof give script type , it's a script created as component and extending from Monobehaviour, he contain value etc.. he could be manipulated from this CustomEditor script via button who call Methodes.
//[CustomEditor(typeof(YourScriptComponent))]
public class MyNewCustomEditor : Editor
{}
for more examples of customEditors script look at unity doc: http://docs.unity3d.com/ScriptReference/Editor.html
3 - Create methodes to be used and called out of scene Playing mode.
you have to create buttons inside OnInspectorGUI() function which will call your methodes for instantiate inside scenes some GameObjects.
4 - WARNING , To instantiate resources like prefabs etc, you have to put yours needed resources inside folder called Resources and use inside your script the Resources.Load() methode.
see the doc for more information , it's pretty simple to use : http://docs.unity3d.com/ScriptReference/Resources.Load.html
Hope it will help, see You.
There was a similar question asked over here.
You want be making an Editor Script then using pretty much the same logic you would use at runtime. Here is the Unity Docs on editor scripts.
You can just make a C# script and put it in the "Editor" folder. If you want it to appear in the editor as a dropdown option you can throw in "[MenuItem("MyTools/CreateGameObjects")]" before a function as shown in the other Stack Overflow answer.
Related
So I'm building a virtual gallery where the user is able to walk around and see pictures.
Now when he clicks on a picture, I want that picture to pop up take up the screen and also display some metadata about the picture, maybe read a text file related to the picture? How do I do this? I'm very new to Unity so any help will be greatly appreciated.
I'm using the below code to detect the gameobjects.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class ObjectClicker : MonoBehaviour
{
public LayerMask interactableLayermask = 6;
UnityEvent onInteract;
void Start()
{
}
void Update()
{
RaycastHit hit;
if(Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 2, interactableLayermask))
{
Debug.Log(hit.collider.name);
}
}
}
```[I want to click on them and that image pops up and takes up the screen and displays some metadata about it.][1]
[1]: https://i.stack.imgur.com/skz8H.png
You can create a Panel (Unity UI), add some elements to it (a button, image, etc) and then create a UIManager object and script.
Now, you can create the methods for that UIManager:
bool showArtInfo (int index)
bool isPanelActive ()
void closePanel ()
And references for the Panel and its picture, text in the script.
You can add an array of images and text to this object. Note indices matter! (or you can use another type of collection instead of array)
Finally, to each object to which you are assigning this ObjectClicker script, you can add a unique constant index so it can indicate who it is to the UIManager. Also add a reference field for UIManager so you can bind the UI Manager script to this guy (you'll have to bind for every gallery object you have - there are better ways if you have many objects, but this is simple).
Now, inside the Update() in ObjectClicker, you can add a call like:
if(Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 2, interactableLayermask)) {
if (! uiManager.isPanelActive ()) {
showArtInfo (myIndex);
}
}
How to implement showArtInfo?
You have to set the image from the array according to index, set text and enable the panel. You can also animate it to make it look nice.
How to implement isPanelActive?
Report whether it is enabled or not, if animating note this might not be enough - experiment to see what is nice.
How to set image?
I don't recall the details, but perhaps this might be useful: How do I change the source image of a Unity image component?
Also note, the Unity UI Panel does not need to be flat 2D, it can also be rendered in World Space, so it moves around with your 3D elements!
There might be many better ways to do this! If working with many objects, you can store details on the objects themselves using custom components, and GetComponent on the gameobject when hit, and pass it along to the UIManager - it will be easier to manage.
I'm exploring a bit in Unity and C#, I searched everywhere for a solution without luck.
Problem:
In Scene A, I have an object button called "Button_2" -> it's hidden.
In Scene B, I have another button called "Button_1", and this one, must unhide "Button_2", in the other scene "Scene A"
How can I achieve this, if possible of course?
Thank you.
EDIT 1:
I tried the following:
Used DontDestroyOnLoad. Basically can't use it on a single button. Unity doesnt allow it. So, I had to do it on the canvas, but when I switched to another scene, was a huge mess with both scenes mixed.
Tried Yuris solution and suggestions and didn't work. Scenes just don't interact with each other at all.
Tried to combine both of above with the prefab concept Yuris suggested aswell and still no luck.
I will keep doing my best, but my knowledge is very limited. I'll be back with more feedback if I make progress.
EDIT 2:
Made many experiments with a non monobehaviour script file and class with only variables to be accessed by a script file that is linked to gameobjects in the diferent scenes.
I wasnt hable to access the variables on the non monobehaviour file. Looks like unity doesn't like non monobehaviour and didn't work.
You can make the button a prefab and assign it on a script in the Scene B, and then when you load scene A again, it will be active.
Remember that if you use that prefab anywhere else, it will be active there too.
Example:
Example.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Example : MonoBehaviour
{
public GameObject button;
// Start is called before the first frame update
void Awake()
{
button.SetActive(true);
}
}
I am trying to add same components to different game objects in a scene in Unity. To make it faster I am trying to write a script that will do this for a list of game objects like (enemy1, enemy2, enemy3...).
I know that adding a script named Enemy I will do:
gameObject.AddComponent<Enemy>();
But the problem is once I stop the play mode the component is gone. Is there a way to achieve this?
You can directly select all the game objects (the list of enemies you mentioned) from the Hierarchy by holding ctrl and then add in the inspector the script Enemy to all of them.
However, if you want to use a script to do it, which can be executed outisde of the Play Mode you need to add ExecuteInEditMode before the script, like this:
[ExecuteInEditMode]
public class TriggerEdit : MonoBehaviour
{
// List of GameObjects
String[] enemyList = {"enemy1", "enemy2", "enemy3"};
void OnEnable()
{
foreach(String enemy in enemyList){
go = GameObject.Find(enemy);
go.AddComponent<Enemy>();
}
}
}
Then you need to add that script to any game object in your scene. Everytime you want to trigger the script you just need to disable and enable the script TriggerEdit in the editor:
One problem with this approach is that everytime you enable the script, it will add a new component, independently if there is already a compoment of type Enemy in the game object, so you may end up with a lot of Enemy components. Something you can try then is to clean all Enemy components in the scene before adding anything else new. For example:
object[] enemiesToDelete = GameObject.FindObjectsOfType<Enemy>();
foreach(UnityEngine.Object enemyComponent in enemiesToDelete)
{
DestroyImmediate(enemyComponent);
}
I'm new to Unity3D and looking for some basic information.
I'm used to OO programming, but I cannot quite see how to access the objects from script.
I created an object, made it a prefab (plan on using it many times) and the object has text on it.
The text uses a Text Mesh. I'm using C#.
How do I thru code, simple example on start, instantiate a new prefab object called Tile at 0,0?
How do you access the text Mesh part of the object to change the text?
I sure there is something simple I'm not picking up on.
Just having trouble understanding how to connect the code to the objects and vice versa.
Updated:
Also wanted to note, I'm trying to load multiple objects at the start, if that makes a difference in the answers.
Update2:
Just wanted to explain a little more what info I was missing when tying the mono code to the unity interface.
In Unity:
Created any object and turn it into a prefab.
Created a second empty game object, place it somewhere in the play view area.
Created a script on the Empty game object.
In Mono code editor:
Created 2 public variables (C#)
public GameObject spawnObj;
public GameObject spawnPoint;
void Update () {
Instantiate (this.spawnObj, this.spawnPoint.transform.position, this.spawnPoint.transform.rotation);
}
Back in Unity:
Select the Empty Game Object.
In the script Component, you should see the 2 vars.
Drag your Prefab Object into the var spawnObj.
Drag the Empty game object into the var spawnPoint.
I did this is the Update, not to smart, but it spawned a cube or 2 or more, spawning from code is all I wanted to understand.
AD1: It's GameObject.Instantiate:
var go=GameObject.Instantiate(prefab, Vector3.zero, Quaternion.Identity) as GameObject;
A prefab is an asset-like GameObject that is used as a template for scene GameObjects.
To use a prefab you have to drag a GameObject to the project window and reference it in code in one of two ways:
Using resources, var prefab=Resources.Load("my-prefab") will load the project file Resources/my-prefab. Note the use of the special "Resources" directory - it's a magic name that is required.
Using a reference, in a MonoBehaviour add a public GameObject prefab field. Then on a GameObject using this class you can drag and drop your prefab from the project window to create a reference to it. You can then use the prefab field in your code. No "Resources" directory needed here.
Prefer option 2, as all resources are in the final binary, while normal assets are trimmed when possible.
AD2: get the TextMesh compontent and modify text:
go.GetComponent<TextMesh>().text="new text";
is there anyway to draw stuff on scene view without calling OnSceneGUI?
or is there a way to get OnSceneGUI to get called even if the object with the script attached is not selected?
Edit: Looks like I wasn't explicit enough on what I was asking for so here's a little update:
I have a whole bunch of controls shown as GUI objects on my Game Scene that are used by the game designers to more easily test the game. Since these tools are for development use rather than deployment, I wanted to move these to the scene window instead.
Unfortunately I am only able to display these GUI tools if the object that contains the script with the "OnSceneGUI" method is selected. Instead I want them to be displayed whenever the game is running and regardless of the selected object.
I have found the solution to my issue.
If you want your GUI stuff to always be displayed on the scene window you can do the following:
public class MyClass{
static MyStaticConstructor() {
SceneView.onSceneGUIDelegate += OnScene;
}
static void OnScene(SceneView sceneView) {
// Draw GUI stuff here for Scene window display
}
}
This code will run as soon as you press play and will draw whatever you wish on your scene window.
Hope it will help others!
There are many ways to use GUI,
The easiest but least efficient way is using the GUI class on OnGUI()
GUI.Label(new Rect(10,10,10,10), "This is a label");
GUI.Label(new Rect(10,10,10,10), "Your Texture2D here");
Any active monobehaviour will run OnGUI() if its defined. So it can be attached to any gameObject. You can create an empty gameObject in the scene and call it "GuiGameObject" for example and attach the script there. That way it wont be mixed in with your gameplay script.
There are also GUI textures --> More Info on GUITexture
Also I recommend checking out nGUI
Edit:
For OnSceneGUI You can try Editor.Repaint, you can use it to make sure that the inspector updates changes made inside of OnSceneGUI