How to get reference to GameObject without using Find() in C#/Unity? - c#

I am currently taking an intro to games programming class and in the lecture notes it mentions that instead of using something like:
GameObject obj = GameObject.Find("name");
inside functions, you can "add object as Public member of type GameObject and connect it in the inspector" without actually explaining how to do it.
I tried to lookup how to do this but was unable to find how to properly do so, would appreciate any help.

Here is how you could do it. Lets say you want obj2 in obj1
First go in the script of obj1 and declare a public variable public GameObject obj2;
Then go in to the inspector of the obj1, on script component you will find a field Obj2. Now just drag and drop the obj2 from hierarchy in that field or click a circular button next to field and select the object from the list.

If you use the public access-modifier, or for fields with the private(default), internal or protected access-modifier, if you annotate with [SerializeField], they will show up in the inspector, if they are serializable and of a supported type.
//This is shown in the inspector
public string _publicField = "public field";
//This is not shown in the inspector, unless you are in debug mode.
private string _privateField = "private field";
//This is shown in the inspector
[SerializeField]
private string _annotatedPrivateField = "annotated private field";
As for what the inspector is:
The Inspector window (sometimes referred to as “the Inspector”)
displays detailed information about the currently selected GameObject,
including all attached components and their properties, and allows you
to modify the functionality of GameObjects in your Scene.
From the official documentation.

Related

How to call a class in Unity, without assigning the script to a gameObject

I have a gameController GameObject, which pulls in and creates 3 List objects built from text files (NameBoys, NameGirls, NameLast). I have defined a Name Class, which is defined as as 3 strings (first, middle, last). In the gameController GameObject, I want to create a function that returns an object of my custom Name type, which will then be used my a NPC type on screen unit. How can I reference the custom Name class in both the gameController GameObject as well as the NPC GameObject, without assigning the script to a gameObject and referencing the GameObject from both places?
You should have a script on gameController, which controlls your name class.
NPC should also have a script, with a field open to script of type gameController.
On NPC, you can reference this class (and any of it's contents) by dragging the class on gameController onto the script on NPC.
Notes:
NPC will have all data gameController has, updated every frame
Attempting to explain my issue to Walter showed me the answer. Just add a namespace to your custom class, and you can reference it normally like you would in any other C#.net application, with a 'using' clause.

Is there any way to get an array containing un-instantiated prefabs

I have a folder, Items, that contains prefabs with the class attached, what I want to do is make an array full of these prefabs in order to compare their ID numbers, a string inside the item class, with the ID numbers from a database to put these prefabs into an inventory array, I hope this is enough detail.
This is what you probably need.
public List<GameObject> prefabsWithClassOnThem;
public GameObject CheckTheID(string ID)
{
foreach (GameObject go in prefabsWithClassOnThem)
{
if(go.GetComponent<ItemClass>().getID() == ID){
return go;
}
}
return null;
}
prefabsWithClassOnThem - the name speaks for itself. It is the list of prefabs you will have to put manually into the list. Then you add your script to a script manager (or any object you feel like) this is how it will look like:
Click on the arrow, write in wanted size and put all the prefabs manually.
CheckTheID - method, which will check for a prefab with the ID you give for this method.
ItemClass - the class, you were mentioning in your question. The class which holds the ID of prefab, and has method GetID().
You will want to call this method in your addToInventory method or something like this.
If you want to check if object was instantiated before, just create additional boolean parameter in ItemClass which will hold true if it was instantiated (you will have to change it for the first time you instantiate one of the prefabs).
Every time you want to create unique item, just check the boolean and thats pretty much it.
Sorry for messy language.

Unity C# getting a variable from another script on the same GameObject

So I got the default FPSController as my GameObject.
I added a script called Controller with a bool called holding which allows me to pick up an object.
Now I want to add an if statement to the FirstPersonController script in which I can't run if hold is true. Therefore I need the bool hold in my FPScontroller script.
I tried diffrent ways to do it but every time I use
.GetComponent<Controller>
I get an error saying that Controller can not be found.
The clas from Controller is public as well as the bool hold.
They are both on the same Object.
Seems like everything seems to be fine.
What happens when in your FPSController you write
Controller controller = transform.GetComponent<Controller>();
Is controller null? Or do you get a null reference exception?
your trying to get the "controller" as a child of the script your in. try :
this.GameObject.GetComponent<Controller>
it might be:
this.gameObject.GetComponent<Controller>
but one of those will fix your problem

Save preferences and use them in other platform

I wanted to ask if it's possible to save preferences in unity editor and use them when project is built and access them from other platform.
For example, I have set n=5 then saved it using playerprefs in unity editor and then I want to get the same integer on other platform when the project is build.
Is there any possible way to achieve this type of problem?
Sounds like you'd be better off using JSON and serializing your data. In the desktop, Unity saves PlayerPrefs to the registry. In Android, it is saved to a manifest file. So, in other words.. No, PlayerPrefs is not a cross-platform kinda thing. Furthermore, if this is "save-game" data, you should know that PlayerPrefs is used to store simple data like an Options menu. For saving an entire save game file you are going to want to use something a little more robust.
Sounds like what you want is turning your data (the value of n in your example) into assets in your builds.
PlayerPrefs does not fit your need because it does not create assets at the build time that could be loaded back during run time. Instead, it is used to serialize data generated during run time to users' devices and use across application sessions (by session I mean the time from launch to quit an application).
My suggestions would be finding someway to serialize your data into assets that Unity can read. There are at least two ways of doing such thing:
Using ScriptableObject. ScriptableObject is a class that inherits from UnityEngine.Object that is designed for serializing data as assets. Here is a simple example:
[CreateAssetMenu("my_data.asset", "My Data")]
public class Data : ScriptableObject
{
[SerializeField]
private int _n;
[SerializeField]
private string _someString;
public int N { get { return _n; }}
public string SomeString { get { return _someString; }}
}
The normal usage would be defining your data class , say Data, that inherits from ScriptableObject. Then, you put desired data into it as serialized fields (_n and _someString here). The attribute CreateAssetMenu is used to create a menu item in the Unity editor for you to create the asset.
After doing this, you can use the data in your MonoBehaviour by referencing it through a field marked with [SerializeField] just like any other Unity assets (like materials or sprites):
public class SomeMono : MonoBehaviour
{
[SerializeField]
private Data _data;
void Awake()
{
Debug.Log("Data.SomeString is " + _data.SomeString);
}
}
Serialize the data into your own format (JSON, BSON, XML, whatever you like) and save them and read back as TextAsset. Here is an example:
public class SomeMono2 : MonoBehaviour
{
[SerializeField]
private TextAsset _text;
void Awake()
{
// Assumes that the data is just a plain string sequence.
// However, it could be any text data you like.
Debug.Log(_text.text);
// Or you can serialize your data as bytes
// byte[] byteData = _text.bytes
}
}
Please note that Unity only automatically identifies files with extension txt (and maybe json? not quite sure about this one) as text assets.

GetComponent in Unity (C#)

So i try to access the script component in another GameObject, but to do it faster i have a Component variable.
Component map = GameObject.FindWithTag("Map").GetComponent<Map>();
Now when i want to reference a variable inside a map component
map.selected = true;
it gives me an error that
UnityEngine.Component does not contain a definition for selected".
Selected is a public bool in Map script, attached to the Map GameObject.
When i go with the long way
GameObject.FindWithTag("Map").GetComponent<Map>().selected = true;
everything works, but i'm looking for a way to shorten my code (this script uses variables from Map in many instances, so i want to write it the shorter way).
This happens because you are instanciating your variable map as a Component, so the compiler will be looking for the selected attribute in the Component class.
Try something like this:
MapScript map = GameObject.FindWithTag("Map").GetComponent<MapScript>();
(Replace MapScript with the actual name of that script.)
I'm not entirely sure if this exact syntax will work, and I have no way of testing this at the moment, so please try and see if it works. If it doesn't, I will look into that as soon as I'm home.

Categories

Resources