I'm trying to get variable from an empty gameObject's script, but I can't assign that gameObject on the inspector. These are the screen shots and codes from my game.
Well, I have this code to load when the game is starting. Land and Prince are objects that made from this code.
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class loadGame : MonoBehaviour
{
public static loadGame loadSave;
public GameObject objPrince;
public Pangeran charPrince;
public Transform prefPrince;
public Sprite[] spriteTanah;
public Dictionary<string, Tanah> myTanah = new Dictionary<string, Tanah>();
public Dictionary<string, GameObject>objTanah = new Dictionary<string, GameObject>();
public Tanah tempTanah;
public GameObject tempObjTanah;
public Transform prefTanah;
public float mapX;
public float mapY;
public int i = 0;
public int j = 0;
public int rows = 9;
public int column = 9;
void Awake(){
if(loadSave == null)
{
DontDestroyOnLoad(gameObject);
loadSave = this;
}
else if(loadSave != this)
Destroy(gameObject);
}
// Use this for initialization
void Start ()
{
Load ();
}
// Update is called once per frame
void Update ()
{
}
public void Load()
{
if(File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
{
}
else
{
charPrince = new Pangeran ("Prince", "04Okt1993", 0, 0, 0, 0, 0, false, false);
objPrince = GameObject.Instantiate (prefPrince, new Vector3 (0, 0, 0), Quaternion.identity) as GameObject;
//objPrince.name = "Prince";
charPrince.locationY = 0f;
charPrince.locationX = 0f;
charPrince.hadapAtas = false;
charPrince.hadapKanan = true;
charPrince.stamina = 100f;
charPrince.exp = 0f;
charPrince.speed = 0f;
for(i = 0 ; i < rows ; i ++)
{
for(j = 0; j<column ; j++)
{
mapX = (i-j) * 0.8f;
mapY = (i+j) * 0.4f;
if(i>=1 && j>=1 && i<=5 && j<=5)
{
prefTanah.name = "land-"+j.ToString("0#")+"-"+i.ToString("0#");
tempTanah = new Tanah("land-"+j.ToString("0#")+"-"+i.ToString("0#"),mapX,mapY,"land",spriteTanah[0],spriteTanah[1],spriteTanah[2]);
myTanah.Add("land-"+j.ToString("0#")+"-"+i.ToString("0#"),tempTanah);
tempObjTanah = GameObject.Instantiate(prefTanah, new Vector3(mapX,mapY,0),Quaternion.identity)as GameObject;
objTanah.Add("land-"+j.ToString("0#")+"-"+i.ToString("0#"),tempObjTanah);
}
else
{
prefTanah.name = "snow-"+j.ToString("0#")+"-"+i.ToString("0#");
tempTanah = new Tanah("snow-"+j.ToString("0#")+"-"+i.ToString("0#"),mapX,mapY,"snow");
myTanah.Add("snow-"+j.ToString("0#")+"-"+i.ToString("0#"),tempTanah);
tempObjTanah = GameObject.Instantiate(prefTanah, new Vector3(mapX,mapY,0),Quaternion.identity)as GameObject;
objTanah.Add("snow-"+j.ToString("0#")+"-"+i.ToString("0#"),tempObjTanah);
}
}
}
}
}
}
I'm trying to access one of some variables from code above, but I can't assign it in the inspector.
but I can't do it.
please help me. Thank you.
The problem is that the loadLand variable is of type LoadGame which is a script. What you are trying to do is to add a GameObject to this variable. So change the public variable type to
public GameObject LoadLandObject;
private LoadGame loadLand;
and create a private LoadGame variable which is the reference to your script.
Add in the Start() method
loadLand = (LoadGame)LoadLandObject.GetComponent<LoadGame>();
With this you load the script LoadGame of the GameObject into the variable.
Do you ever set your plantingScript.loadLand to the instance of loadGame.loadSave? This must be done after Awake in your case to be sure the instance has been set.
Can I ask, what are you trying to do?
You should simply just assign you loadGame script in the inspector of plantingScript and not use statics at all. They will bite your ass sooner or later (and I'm guessing it already is).
Have a similar problem. Did n't find simple and clear solution. May be what i did help to you.
Create empty game object.
Attach loadGame.cs to it (if you whant to control when script starts - uncheck it,in this case don't foget to set loadLand.enabled to true in plantingScript when needed)
Drag this object to you loadLand field
Sample project
Related
I have created a script who will spawn objects and give tag and color for one element of prefab. But script not working with clones. This 2 scripts, GameManager( he must spawn objects) and
RandomTagAndColor( he give to element of prefab tag and name). And in scene of game, where objects is spawning, script give tag and colour only to first prefab. In game those prefabs 10. Well, I'm sorry if question is stupid, this first thing, what i doing without books,guides.
GameManager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class GameManager : MonoBehaviour
{
// Start is called before the first frame update
public GameObject firstBarrier;
public GameObject secondBarrier;
public int numOfBarriers = 0;
System.Random rnd = new System.Random();
System.Random rndY = new System.Random();
Vector3 vector = new Vector3(5, 1/3 , 1);
void Start()
{
for (numOfBarriers = 0; numOfBarriers < 10; numOfBarriers++)
{
int ewq = rnd.Next(1, 20);
int rY = rndY.Next(1, 4);
if(ewq <= 10)
{
Instantiate(firstBarrier, vector, Quaternion.identity);
}
else
{
Instantiate(secondBarrier, vector, Quaternion.identity);
}
vector.x -= 7;
vector.y = rY;
}
}
void Update()
{
}}
RandomColorAndTag script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class RandomColorAndTag : MonoBehaviour
{
GameObject Bar;
System.Random randomElement = new System.Random();
int el = 0 ;
void Start()
{
el = randomElement.Next(2, 6);
GameObject.Find($"Cube ({el})").GetComponent<Renderer>().material.color = Color.green;
if (GameObject.Find($"Cube ({el})").GetComponent<Renderer>().material.color == Color.green)
{
GameObject.Find($"Cube ({el})").transform.tag = "Green";
}
}
void Update()
{
}
}
As mentioned there are lot of unclear issues in your codes.
I will assume the RandomColorAndTag is attached to the objects you spawn. In that case don't use Find but rather simply assign the random color and tag to yourself
what is a random value between 1 and 19 good for, of all you ever do with it is check whether it is bigger or smaller than 10? => Simply use only a random 0 or 1 and check whether it is 0 ;)
I'm unsure exactly what items should be green now .. I assume among the 10 spawned items you want to pick one and make it special..
finally I wouldn't even let the objects assign their own tag and color but let the GameManager trigger it
So I would do something like
public class GameManager : MonoBehaviour
{
public TagAndColorController fortBarrier;
public TagAndColorController secondBarrier;
public int numOfBarriers = 10;
public Vector3 vector = new Vector3(5, 1f/3f , 1);
public Color specialColor = Color.Green;
public string specialTag = "Green";
private void Start()
{
var specialIndex = Random.Range(0, numberOfBarriers);
for (var i = 0; i < numOfBarriers; i++)
{
// upper bound is exclusive -> this returns 0 or 1
var rndBarrier = Random.Range(0, 2);
// not sure if intended but again: upper bound is exclusive -> this return 1, 2, or 3
var rY = Random.Range(1, 4);
var tagAndColor = Instantiate(rndBarrier == 0 ? firstBarrier : secondBarrier, vector, Quaternion.identity);
if(i == numberOfBarriers)
{
tagAndColor.SetColorAndTag(specialColor, specialTag);
}
vector.x -= 7;
vector.y = rY;
}
}
}
And the other script has no logic whatsoever but rather only is a quick access to the objects renderer and bundles the behavior
public class TagAndColorController : MonoBehaviour
{
[SerializeField] private Renderer _renderer;
public void SetColorAndTag(Color newColor, string newTag)
{
gameObject.tag = newTag;
if(!_renderer) _renderer = GetComponent<Renderer>();
_renderer.material.color = newColor;
}
}
I am currently working on an Unity project in C# and my rigidbody isn't moving but I don't get an error. It should get thrown forward and upward but it does nothing - what am I doing wrong here?
Or can it be that my code isn't the problem but I messed something up unn unity?
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public GameObject ThrowObject;
public Canvas StartMenuC, m_SettingsC, m_ShopC;
public Button m_Start, m_Settings, m_Shop, m_CloseShop;
public RawImage m_SettingsImage, m_RTXON, m_RTXOFF;
public Texture m_Texture, m_Texture2;
public Toggle m_RTX;
public Text MoneyText;
string m_ForceXString = string.Empty;
string m_ForceYString = string.Empty;
public Rigidbody rb;
public Transform Forward, Upward;
private Vector3 m_StartPos, m_StartForce;
private Vector3 m_NewForce;
float m_ForceX, m_ForceY;
private int Money = 100;
// Start is called before the first frame update
void Start()
{
// rb = GetComponent<Rigidbody>();
m_NewForce = new Vector3(-5.0f, 1.0f, 0.0f);
m_ForceX = 10;
m_ForceY = 10;
m_ForceXString = "0";
m_ForceYString = "0";
m_StartPos = transform.position;
m_StartForce = rb.transform.position;
m_NewForce = new Vector3(m_ForceX, m_ForceY, 0);
MoneyText = GetComponent<Text>();
m_CloseShop.onClick.AddListener(CloseShop);
m_Settings.onClick.AddListener(Settings);
m_Start.onClick.AddListener(StartGame);
m_Shop.onClick.AddListener(ShopOpen);
m_SettingsImage = GetComponent<RawImage>();
m_SettingsC.enabled = false;
m_ShopC.enabled = false;
m_RTX.onValueChanged.AddListener(delegate {
CheckToggleOn(m_RTX);
});
// PlayerPrefs.SetInt("Money", Money);
// MoneyText.text = "Money: " + Money.ToString() + " $";
}
// Update is called once per frame
void Update()
{
}
void Settings()
{
if (m_SettingsC.enabled == false)
{
m_SettingsC.enabled = true;
}
else
{
m_SettingsC.enabled = false;
}
}
void ShopOpen()
{
m_ShopC.enabled = true;
}
void CloseShop()
{
m_ShopC.enabled = false;
}
private void CheckToggleOn(Toggle change)
{
if (m_RTX.isOn)
{
m_RTXOFF.enabled = false;
m_RTXON.enabled = true;
}
else
{
m_RTXON.enabled = false;
m_RTXOFF.enabled = true;
}
}
private void StartGame()
{
m_SettingsC.enabled = false;
StartMenuC.enabled = false;
m_ShopC.enabled = false;
Instantiate(ThrowObject, new Vector3(0, 356, 26), Quaternion.identity);
Debug.Log("HelloWorld");
if (ThrowObject)
{
Debug.Log("Throw object = true");
rb.AddForce(m_NewForce, ForceMode.Impulse);
}
}
}
What is my error?
And bc of: "It looks like your post is mostly code; please add some more details." and I don't know what else I am supposed to write here I'll tell what the game should look like when done it will be a 3D Mobile Game where you have the objective to throw stuff out of the window I know it's idiotic but its based on a true story from my old school where someone often threw schoolbags out of the window and had to get them back and the school was in the 5. floor
So I guess you want to add force to your newly instantiated "ThrowObject", correct?
However, instead of referencing this object, you add force to "rb", which seemingly is not at all connected to the new object.
Instead, you might want to do something like this:
rb = Instantiate(ThrowObject, new Vector3(0, 356, 26), Quaternion.identity).GetComponent<Rigidbody>();
I have a SceneController that's supposed to initialize a set of empty GameObject spawners, each working together at the same rhythm. The RockSpawners receive an array of time delays and wait the X seconds between spawning another rock.
I set the _nextSpawn = float.maxValue when the spawners start and plan to overwrite this after "Initializing" them (my own method), however even though my debug logs say I've overwritten my _nextSpawn value while initializing, the update loop is still reporting float.maxValue and nothing ends up spawning because _timeSinceLastSpawn hasn't exceeded float.maxValue seconds.
Is there something I'm missing with the scope of my _nextSpawn variables? It doesn't seem to be a "this" vs "local" issue, at least at first glance.
Debug output: 0 0 3 3. 0's stay the same, 3's will vary based on rng.
SceneController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SceneController : MonoBehaviour {
[SerializeField] private GameObject _rockSpawnerPrefab;
public int numRocks = 6;
public int minSpawnDelaySec = 1;
public int maxSpawnDelaySec = 3;
private bool spawnersInitialized = false;
void Start () {
InitializeSpawners();
}
void Update () {
}
void InitializeSpawners() {
float[] pattern = new float[numRocks];
for (int i = 0; i < numRocks; i++) {
// Generate delays at half second increments within bounds
float delay = Mathf.Floor(Random.value * ((float)(maxSpawnDelaySec + 0.5f - minSpawnDelaySec) / 0.5f));
delay = delay * 0.5f + minSpawnDelaySec;
pattern[i] = delay;
}
GameObject spawner = Instantiate(_rockSpawnerPrefab) as GameObject;
spawner.transform.position = new Vector3(0, 4, 0);
RockSpawner rockSpawnerScript = spawner.GetComponent<RockSpawner>();
rockSpawnerScript.Initialize(pattern);
}
}
RockSpawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RockSpawner : MonoBehaviour {
[SerializeField] private GameObject _rockPrefab;
public float minSpawnDelay = 3f;
public float maxSpawnDelay = 6f;
private float[] _pattern;
private int _currentPattern;
private float _timeSinceLastSpawn;
private float _nextSpawn;
void Start () {
_currentPattern = -1;
_nextSpawn = float.MaxValue;
}
void Update () {
if (_pattern == null) return;
_timeSinceLastSpawn += Time.deltaTime;
if (_timeSinceLastSpawn > _nextSpawn) {
GameObject rock = Instantiate(_rockPrefab) as GameObject;
rock.transform.position = transform.position;
NextTimer();
}
}
public void Initialize(float[] pattern) {
_pattern = pattern;
NextTimer();
}
private void NextTimer() {
_timeSinceLastSpawn = 0;
_currentPattern += 1;
Debug.Log(_nextSpawn);
Debug.Log(this._nextSpawn);
this._nextSpawn = _pattern[_currentPattern];
Debug.Log(_nextSpawn);
Debug.Log(this._nextSpawn);
}
}
It's not about scoping, it's about call order. When you create a GameObject its Start method is called on the frame it's enabled, not when the object is created. So your code will call Initialize first, then Start which overwrites the values.
Remove the code in Start and handle everything in Initialize and it should work as you want.
Hi I am making a Multiplayer shooter in unity and im using arrays and need help
My situation is I want to make an unboxing system that chooses a random array and then set it to the list of the classes array list please help.
Please tell me if this would choose a random array: Classes[Random];
and also I need to know how to set an array from a different script
using UnityEngine;
using System.Collections;
public class SpawnNew : MonoBehaviour
{
public GameObject[] Classes;
public GameObject player;
public Transform[] spawnPoints;
public Camera spawnCam;
public AudioListener spawnListener;
public bool spawned = false;
void ClassList(){
Classes = new GameObject[10];
}
void OnGUI()
{
if (Network.isServer || Network.isClient)
{
if (!spawned)
{
if (GUI.Button(new Rect(Screen.width / 10 - 50, Screen.height / 10 - 25, 100, 50), "Spawn"))
{
SpawnPlayer();
}
}
}
}
void SpawnPlayer()
{
spawned = true;
int random = Random.Range(0, spawnPoints.Length);
Network.Instantiate(player, spawnPoints[random].position, spawnPoints[random].rotation, 0);
spawned = true;
spawnCam.enabled = false;
spawnListener.enabled = false;
spawned = true;
}
public void Die()
{
Screen.lockCursor = false;
spawned = false;
spawnCam.enabled = true;
spawnListener.enabled = true;
}
}
First of all your array is not initialized. You have to make sure the array is populated before calling SpawnPlayer method, otherwise this will through a NullReferenceException.
Yes, this int random = Random.Range(0, yourArray.Length); would give you a random index within your array.
You can access your array / method from within another script like this
GameObject yourObject = GameObject.Find("GameObjectNameThatHasYourScriptAttachedToIt");
if(yourObject !=null){
yourObject.GetComponent<SpawnNew>().Classes = someOtherArray;
// or if you want to access the method
// yourObject.GetComponent<SpawnNew>().SpawnPlayer();
}
I have a issue with a script. I am trying to create a star field randomly in a sphere for my unity scene. But I am new to unity and c# so I am a bit confused.
The stars have a fixed place so they should not move and so are created in Start(); and then are drawn in Update();
The problem is I get this error:
MissingComponentException: There is no 'ParticleSystem' attached to the "StarField" game object, but a script is trying to access it.
You probably need to add a ParticleSystem to the game object "StarField". Or your script needs to check if the component is attached before using it.
Stars.Update () (at Assets/Stars.cs:31)
If i add a particle system component manually it causes a load of big flashing orange spots, which i don't want, so i want to add the component in the script some how.
This is my script attached to an empty game object:
using UnityEngine;
using System.Collections;
public class Stars : MonoBehaviour {
public int maxStars = 1000;
public int universeSize = 10;
private ParticleSystem.Particle[] points;
private void Create(){
points = new ParticleSystem.Particle[maxStars];
for (int i = 0; i < maxStars; i++) {
points[i].position = Random.insideUnitSphere * universeSize;
points[i].startSize = Random.Range (0.05f, 0.05f);
points[i].startColor = new Color (1, 1, 1, 1);
}
}
void Start() {
Create ();
}
// Update is called once per frame
void Update () {
if (points != null) {
GetComponent<ParticleSystem>().SetParticles (points, points.Length);
}
}
}
How can i set it to get a static star field, because adding a particle system component manually gives me these annoying orange particles and am wanting to do it purely via scripts.
It will be easier for you if you add the particle system manually and change the settings so that you don't see any funny shapes at runtime or in the Editor.
As a side note, you don't need to set the particles every frame in Update. Even if you did, calling GetComponent is expensive, so you should save the ParticleSystem as a field of the class in the Start() method.
Here is some modified code that worked for me:
using UnityEngine;
public class Starfield : MonoBehaviour
{
public int maxStars = 1000;
public int universeSize = 10;
private ParticleSystem.Particle[] points;
private ParticleSystem particleSystem;
private void Create()
{
points = new ParticleSystem.Particle[maxStars];
for (int i = 0; i < maxStars; i++)
{
points[i].position = Random.insideUnitSphere * universeSize;
points[i].startSize = Random.Range(0.05f, 0.05f);
points[i].startColor = new Color(1, 1, 1, 1);
}
particleSystem = gameObject.GetComponent<ParticleSystem>();
particleSystem.SetParticles(points, points.Length);
}
void Start()
{
Create();
}
void Update()
{
//You can access the particleSystem here if you wish
}
}
Here is a screenshot of the starfield with the settings used in the particle system. Note that I switched off looping and play on awake.