Attach Custom Class To A Newly Instantiated Object - c#

I'm trying to instantiate multiple objects called Stars. In my Simulation class, I have a method where I am creating an object called newStar and attaching the class Star.
Here is my GameObject hierarchy:
The Simulation script, which has the Simulation class is attached to the Simulation gameobject. The Star script which has the Star class is attached to the StarObject gameobject. Within the Star script, I've attached both the prefab of the star to prefabStar and the StarObject gameobject has been attached to the StarObject variable through the Unity editor.
Here is my Simulation class: (ObjectStar is a GameObject which is the parent of the prefabStar.
void listStars()
{
int i = 0;
while (i < (StarDataBank.Instance.NumOfStars))
{
int primaryID = int.Parse(StarDataBank.Instance.StarIDID[i]);
string properName = StarDataBank.Instance.StarName[i];
string HIPID = StarDataBank.Instance.StarIDHIP[i];
string HDID = StarDataBank.Instance.StarIDHD[i];
string HRID = StarDataBank.Instance.StarIDHR[i];
string GLID = StarDataBank.Instance.StarIDGL[i];
string BFID = StarDataBank.Instance.StarIDBF[i];
decimal rightAscension = Convert.ToDecimal(StarDataBank.Instance.StarRA[i]);
decimal declination = Convert.ToDecimal(StarDataBank.Instance.StarDec[i]);
decimal Mag = Convert.ToDecimal(StarDataBank.Instance.StarMag[i]);
decimal CI = Convert.ToDecimal(StarDataBank.Instance.StarCI[i]);
int scale = 0;
int r = 0;
int g = 0;
int b = 0;
Star newStar = ObjectStar.AddComponent<Star>();
newStar.Instantiate(primaryID, properName, HIPID, HDID, HRID, GLID, BFID, rightAscension, declination, Mag, CI);
i++;
}
}
Here is the Star class:
public void Instantiate(int primaryID, string properName, string HIPID, string HDID, string HRID, string GLID, string BFID, decimal rightAscension, decimal declination, decimal magnitude, decimal colourIndex)
{
this.primaryID = primaryID;
this.properName = properName;
this.HIPID = HIPID;
this.HDID = HDID;
this.HRID = HRID;
this.GLID = GLID;
this.BFID = BFID;
this.rightAscension = rightAscension;
this.declination = declination;
this.magnitude = magnitude;
this.colourIndex = colourIndex;
var newStar = Instantiate(prefabStar, transform.position + getVector(Convert.ToDecimal(rightAscension), Convert.ToDecimal(declination)), Quaternion.identity);
newStar.name = (primaryID).ToString();
newStar.transform.parent = StarObject.transform;
newStar.transform.localScale = new Vector3(20, 20, 20);
}
My desired intention is to create a clone of the prefabStar, with each clone attached to the Star class, so I can retrieve the variables of each clone of the prefabStar.
Instead, what's happening is I'm getting an error that reads "The Object you want to instantiate is null." and there are no new gameobjects (prefabStar isn't being cloned.)
EDIT: I have added a screengrab of the Star prefab in the editor,
Notice how the Star class is attached to this prefab. (Please ignore the name Star Manager, I was doing a few tests, the problem still persists with it called Star)

Check the editor again and try to look if the prefab you've attached is still visible in the game editor upon starting the game. Maybe mistakenly you've attach it in the editor while being in game-mode.
Also if you've made your change in the edit mode to your object that is also a prefab you need to apply the changes to your prefab by clicking on Apply button, that will be located most probably in the upper right corner of your editor.
From the screenshot that you've posted I would choose the prefab that is in question from the bottom part of your screen. Upon selection the right side panel should change to show your prefab data. Then I would lock the right side panel by clicking on little lock icon that is visible at the top. While locked just press and drag your prefabs from the bottom panel to appropriate places in your right side panel.

Related

Instantiate a Object below another object instead of above

First of all, i created a GIF to show what is currently happen.
GIF with my current problem
and
Awhat I want
I have a List of GameObject which add the bodyParts temp and Instantiate it in the correct time and position.
Now this is working like expected, but i want this new bodyParts below another object instead of above.
As you can see the Head is "under" the new body parts, but it should always on Top and every new part should spawn under the next. (only should looks like! I dont want to change the Z position.)
i tried :
bodyParts.transform.SetAsFirstSibling();
to change the Hierarchy, but this do nothing. I also can drag and drop the Clones to a other position in Hierarchy but they just stay at the same position (above another).
Is this possible and what should i have to do?
Here some of my Code which makes the process:
private void CreateBodyParts()
{
if (snakeBody.Count == 0)
{
GameObject temp1 = Instantiate(bodyParts[0], transform.position, transform.rotation, transform);
if (!temp1.GetComponent<MarkerManager>())
temp1.AddComponent<MarkerManager>();
if (!temp1.GetComponent<Rigidbody2D>())
{
temp1.AddComponent<Rigidbody2D>();
temp1.GetComponent<Rigidbody2D>().gravityScale = 0;
}
snakeBody.Add(temp1);
bodyParts.RemoveAt(0);
}
MarkerManager markM = snakeBody[snakeBody.Count - 1].GetComponent<MarkerManager>();
if (countUp == 0)
{
markM.ClearMarkerList();
}
countUp += Time.deltaTime;
if (countUp >= distanceBetween)
{
GameObject temp = Instantiate(bodyParts[0], markM.markerList[0].position, markM.markerList[0].rotation, transform);
if (!temp.GetComponent<MarkerManager>())
temp.AddComponent<MarkerManager>();
if (!temp.GetComponent<Rigidbody2D>())
{
temp.AddComponent<Rigidbody2D>();
temp.GetComponent<Rigidbody2D>().gravityScale = 0;
}
snakeBody.Add(temp);
bodyParts.RemoveAt(0);
temp.GetComponent<MarkerManager>().ClearMarkerList();
countUp = 0;
}
}
Finally i found the working Solution.
It has nothing to do with which hierarchy order GameObjects spawn in.
Just the Layer and the LayerOrder are responsible for it.
So I give my parent object a specific layer name (manually in the inspector under "Additional Settings" or programmatically)
I chose the programmatic way...
Any newly spawned GameObject that is Child would get a lower number
yourGameObject.GetComponent<Renderer>().sortingLayerID = SortingLayer.NameToID("Player");
yourGameObject.GetComponent<Renderer>().sortingOrder = -snakeBody.Count;

"Selection.objects" doesn't seem to work in open prefab hierarchy window

I want to select several game objects in open prefab but Selection.objects, which normally works for scene game objects, like on this picture:
doesn't seem to work properly for prefab objects.
Actually, the Inspector window displays common properties of the selected objects as expected but in the Hierarchy window they are not selected (highlighted) like on the picture above.
Here is how my script looks like in my MyEditor : EditorWindow:
int childObjectsCount;
string prefabName;
...
if (AssetDatabase.LoadMainAssetAtPath(prefabName) is GameObject prefab)
{
if (AssetDatabase.OpenAsset(prefab))
{
if (childObjectsCount > 0)
{
List<GameObject> innerObjects = FindInnerObjects(prefab);
Selection.objects = innerObjects.ToArray();
}
}
}
The reason it doesn't work is that the Gameobject specified by Selection.objects is not the Gameobject in the current PrefabStage, so we need to get the current PrefabStage
// LoadPrefab
GameObject assetGameObject = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
// OpenPrefab
AssetDatabase.OpenAsset(assetGameObject);
// GetPrefabStage
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
// Get Root Gameobejct Of Prefab Which We Are Editing
GameObject instanceGameobject = prefabStage.prefabContentsRoot;
// Then Select It , it works well(highlight)
Selection.objects = new Object[] {instanceGameobject };

Acquiring Text of a label from scene1 to scene2 Unity

I have created a simple 2d card game in Unity , While the user is playing the game , certain information is getting captured like (score,tries,time), When the user wins or loses the game then the appropriate scene (game over or Win scene) is getting triggered, in these 2 scenes id like to copy the info from the score, tries, time fields of the game to the appropriate labels of gameOver or Win, But it seems I'm doing something wrong..
I tried to find similar questions on StackOverflow, Youtube, the web; I checked the documentation and I tried different approaches.
Here is the code I'm working with at the moment, which seems totally correct to me, I don't get any errors, just nothings appears in the labels.
'''
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class win_results : MonoBehaviour
{
// public options script;
public Text score_final_text;
public Text tries_final_text;
public Text time_final_text;
public void player_win_results()
{
// script = a.getComponent<options>();
if (options.user_lvl_choice=="easy")
{
GameObject tries_final = GameObject.Find("tries_text_lvl1"); //finds the object named score_results
tries_final_text.text = tries_final.GetComponent<Text>().text + "a"; //gets the Text property of it.
GameObject time_final = GameObject.Find("TimeCounter_lvl1"); //finds the object named score_results
time_final_text.text = time_final.GetComponent<Text>().text + "a"; //gets the Text property of it.
GameObject score_final = GameObject.Find("score_lvl1"); //finds the object named score_results
score_final_text.text = score_final.GetComponent<Text>().text + "a"; //gets the Text property of it.
}
else if (options.user_lvl_choice == "hard")
{
GameObject tries_final = GameObject.Find("tries_text_lvl2"); //finds the object named score_results
tries_final_text.text = tries_final.GetComponent<Text>().text + "a"; //gets the Text property of it.
GameObject time_final = GameObject.Find("TimeCounter_lvl2"); //finds the object named score_results
time_final_text.text = time_final.GetComponent<Text>().text + "a"; //gets the Text property of it.
GameObject score_final = GameObject.Find("score_lvl2"); //finds the object named score_results
score_final_text.text = score_final.GetComponent<Text>().text + "a"; //gets the Text property of it.
}
}
As the code above shows I'm using GameObject.Find as the documentation states, I have double checked the names and typos, the scripts are correctly attached, I get no errors in the output, just nothing happens.
As you can see above I have added an extra "a" character at the end for debugging purposes, the "a" character also doesn't appear in the output, meaning that the gameObject find doesn't work correctly in my example.
What am I doing wrong?
Thanks in advance.
When you load a scene without the second parameter
SceneManager.LoadScene("scene2");
The old scene will be destroyed, all the GameObjects in that scene will also be destroyed except you've called DontDestroyOnLoad on it.
So if you haven't done this job yet, what you get in the new scene are empty data. You can print the values to check.
The easiest way to pass data through scenes is use static field. Create a class and add some static fields:
class Global
{
public static string user_lvl_choice;
public static string tries_final;
....
}
Then you can set or get these values from any scene.
Global.user_lvl_choice = "easy"
print(Global.user_lvl_choice);
Read more:
static
SceneManager.LoadScene
Object.DontDestroyOnLoad

How to create custom 3D name using c# script in Unity 3D

I'm stuck on a c# scripting problem in Unity that I would like to solve.
This is what I want to achieve:
Enter a name on an InputField
Get Characters from the Input field
For each Character: set the 3D GameObject of the Character already created in the Hierarchy
SetCharacterPosition next to each other so they can create a name
SetMaterial in this order (Blue, Green,Red,Yellow) and start over
View the given input name in a 3D Colored way on the screen
This is what I have done so far:
Created 3D Prefabs of each Character and loaded into Hierarchy
Created the GUI with an InputField and a Button (+Script)
Create a Button Script (button_scr) in order to get the name and split into Characters
GUI
SCRIPT button_scr
public class button_scr : MonoBehaviour
{
public Button myButton;
public InputField un;
public GameObject go;
void Start ()
{
myButton = GetComponent<Button>();
myButton.onClick.AddListener(ProcessText);
}
void ProcessText()
{
Debug.Log("Your name is : "+un.text);
getCharacters(un.text);
}
void getCharacters(string text)
{
foreach (char c in text)
{
go = GameObject.Find(""+char.ToUpper(c));
go.SetActive (true);
// setPosicionNext2EachOther
// setColoredMaterial(Blue,Green,Red,Yellow) in this order
Debug.Log("GameObject name Log: "+go.name);
}
}
}
Some considerations:
Names can have some repeated Characters
Names can have accent marks on vowels (Á, É,Í,Ó,Ú)
Names can have "ñ" character
This is where I would like to get some orientation in order to solve the problem:
I have considered creating and filling a GameObject Array with all
the references of each character like so:
GameObject[0] = A 3D Character prefab
GameObject[1] = B 3D Character prefab
Then create a for loop to find the name character in the GameObject Array and make a copy in order to setup in the game
Set 3D character position
Set Material to 3D character in a sequential order (Blue,Green,Red,Yellow)
Is there any easier way to do this that I'm missing?
I would like to get some orientation/advice or some sample code where I can check similar issue solving.
this is a quick solution. not tested. i dont have unity installed. just for you to have an idea.
Yes. is better to assign all the letters in a array for optimization. Also deactivate all the letters in Awake()
public Material materials[]; // assign the materials in the order you want
public void getCharacters (string name)
{
int materialIndex = 0;
for (int i = 0; i < text.lenght; i++)
{
char c = char.ToUpper(text[i]);
GameObject go = GameObject.Find("" + c);
go.SetActive (true);
go.transform.position = new Vector3(i, 0, 0); // place the letters in the x axis separated by one meter
// change the material
go.GetCOmponent<Renderer>().sharedMaterial = materials[materialIndex];
materialIndex = (materialIndex + 1) % materials.length; // cycle the materials
// setPosicionNext2EachOther
// setColoredMaterial(Blue,Green,Red,Yellow) in this order
//Debug.Log("GameObject name Log: "+go.name);
}
}

unity control one object from many same object in scene that have same script c# with UI button

i have three same object with same script in scene, i also has one button for upgrade the object script's variable i selected
below is what i tried but still upgraded all of object variable instead just what i selected
what i want is when i selected one of the object on scene and clicked the button, then just selected object script variable upgraded instead all of the object script variable
public int lv;
public float hp;
public float damage;
public float atkSpeed;
public GameObject objBtnUpgrade;
public Button btnUpgrade;
void Start () {
objBtnUpgrade = GameObject.Find ("BtnUpgrade");
objBtnUpgrade.GetComponent<Button> ().onClick.AddListener(() => { UpgradeSummonLevel(); });
}
public void UpgradeSummonLevel(){
lv = lv + 1;
hp = hp + ((hp / 100) * 10);
atkSpeed = atkSpeed + ((atkSpeed / 100) * 10);
damage = damage + ((damage / 100) * 10);
}
Are you asking why every one of your objects is being upgraded?
But to answer you question as far as I understand, the most likely problem is that you have all of the objects that you are trying to influence called "BtnUpgrade". They should have differing names that way you can find a single one by its name.

Categories