Dictionary not read when using GetComponent<>() in Unity - c#

I have three scripts inside GameObjects strucured as following:
GameObjectA
└ Script1
GameObjectB
└ Script2
└ Script3
Script3 has a Dictionary I need to recall in Script2:
public void SomeMethod()
{
Dictionary<string, int> someDictionary;
someDictionary = gameObject.GetComponent<Script3>().myDictionary;
//other stuff
}
If I call the method in Script2 in its Start method, it gets called and normally, and the Dictionary is read without problems.
However, during code execution, I'll sometimes need to call Script2 from Script1:
Public GameObject GameObjectB;
GameObjectB.GetComponent<Script2>().SomeMethod();
and, if I do so, when stepping through code during execution I realize the Dictionary SomeDictionary is empty.
Is this normal? I can give more information or the real snippets if needed, I find this behavior weird and I don't know if it acts regularly.
Edit: real codes below.
Script1, PauseMenu:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PauseMenu : MonoBehaviour
{
public GameObject tracksMenuContent;
public void TracksList()
{
tracksMenuContent.GetComponent<PopulateGrid>().Populate();
}
}
Script2, PopulateGrid:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PopulateGrid : MonoBehaviour
{
[SerializeField] private TileDescr _prefab;
public static PopulateGrid instance;
private void Awake()
{
Populate();
}
public void Populate()
{
Dictionary<string, TileSupply> tilesList;
tilesList = gameObject.GetComponent<TileDB>().tiles30;
TileDescr newObj; // Create GameObject instance
foreach (KeyValuePair<string, TileSupply> tile in tilesList)
{
Sprite tileSprite = Resources.Load<Sprite>("Tiles/tile" + tile.Key);
string tileText = "[" + tile.Key + "] " + tile.Value.available + "/" + tile.Value.total;
newObj = Instantiate(_prefab, transform);
newObj.Initialize(tileSprite, tileText);
}
}
}
Script3, TileDB:
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TileSupply
{
public int available;
public int total;
}
public class TileDB : MonoBehaviour
{
public Dictionary<string, TileSupply> tiles30 = new Dictionary<string, TileSupply>();
public void Awake()
{
tiles30.Add("1", new TileSupply() { available = 1, total = 1 });
//many more elements, all pretty similar
}
}

a possible solution is to use static:
public class TileDB : MonoBehaviour
{
public static Dictionary<string, TileSupply> tiles30 = new Dictionary<string, TileSupply>();
public void Awake()
{
tiles30.Add("1", new TileSupply() { available = 1, total = 1 });
}
}
after to use the tiles30 in other script, just call the dictionary like that
TileDB.tiles30

Related

How to Access public static variable of a instantiated object from another script in Unity using GetComponent

I have a unity C# script that has Some "Public static Variables" as shown below. This script is attached to the instantiated object.
public class PlaceAtLocation : MonoBehaviour
{
public static double Longitude, Latitude;
}
I want to access these static variables "Latitude" and "Longitude" in another script. That is shown below
public class Instansiate_object : MonoBehaviour
{
public GameObject GpsStageObject;
public GameObject tempbject;
public void InstansiateGpSStageObject()
{
tempbject= Instantiate(GpsStageObject, new Vector3(0, 0, 0), Quaternion.identity);
tempbject.GetComponent<PlaceAtLocation>().lat =1;
tempbject.GetComponent<PlaceAtLocation>().lon =1;
//I want to access latitude and longitude here
//=============================================
//tempbject.GetComponent<PlaceAtLocation>().Longitude =1;
//tempbject.GetComponent<PlaceAtLocation>().Latitude =1;
//=============================================
print("Instansiated");
}
}
try using this format
using UnityEngine;
using System.Collections;
public class YetAnotherScript : MonoBehaviour
{
public int numberOfPlayerDeaths = 3;
}
using UnityEngine;
using System.Collections;
public class UsingOtherComponents : MonoBehaviour
{
public GameObject otherGameObject;
private YetAnotherScript yetAnotherScript;
void Awake ()
{
yetAnotherScript = otherGameObject.GetComponent<YetAnotherScript>();
}
void Start ()
{
Debug.Log("The player has died " + yetAnotherScript.numberOfPlayerDeaths + " times");
}
}

Save current Scrollrect position Unity3D

I am new with unity and C#, I have question about how I save current scrollrect position.
Example : I am scrolling the view , and move to another scene and then back to previous scene but the scroll shows the previous position before I moved the scene, not resetting the scroll to default.
Unfortunately, what you want to make is not available ready-made, you have to make it yourself
first use Recyclable-Scroll-Rect
When scrolling to the bottom of the scroll, you have to save the id you sent to DemoCall via PlayerPrefs, then when you go to another scene and back again to the selected scene, call the scroll info from the point it left off, which is the id you saved
EDIT
After adding the Recyclable-Scroll-Rect, you can use this code
using System.Collections.Generic;
using UnityEngine;
using PolyAndCode.UI;
using System.Collections;
public struct ContactTsnif
{
public string id;
}
public class Objx
{
public string id;
}
public class RecyclTsnif : MonoBehaviour, IRecyclableScrollRectDataSource
{
[SerializeField]
RecyclableScrollRect _recycHat;
public GameObject RecyScrHat;
[SerializeField]
public int _dataLenHat;
public int beginning;
private List<ContactTsnif> _contactList = new List<ContactTsnif>();
public List<string> id = new List<string>();
void Start()
{
beginning = PlayerPrefebs.GetInt("Start", 5)// start with 5
GetHat();
}
public void GetHat()
{
_dataLenHat = 0;
_recycHat.DataSource = this;
InitDataHat();
RecyScrHat.GetComponent<RecyclableScrollRect>().Initialize();
}
public void InitDataHat()
{
if (_contactList != null) _contactList.Clear();
for (int i = beginning; i < _dataLenHat;)
{
ContactTsnif obj = new ContactTsnif();
obj.id = id[i];
i++;
_contactList.Add(obj);
}
}
#region DATA-SOURCE
public int GetItemCount()
{
return _contactList.Count;
}
public void SetCell(ICell cell, int index)
{
var item1 = cell as DemoTsnif;
item1.ConfigureCellSor(_contactList[index], index);
}
#endregion
}
Demo
using UnityEngine;
using System;
using System.Collections;
public class DemoTsnif : MonoBehaviour, ICell
{
private ContactTsnif _ContactInfo;
private int _cellIndex;
public int id;
public void GetData()
{
}
public void ConfigureCellSor(ContactTsnif contactInfo,int cellIndex)
{
_cellIndex = cellIndex;
_ContactInfo = contactInfo;
id = contactInfo.id;
GetData();
}
}
Do you tried read / write normalizedPosition?
You basically need to do two things:
You need to attach this script to the GameObject which contains the ScrollRect in order to persist the position:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems; // Required when using event data
using UnityEngine.UI;
public class DragNotify : MonoBehaviour, IEndDragHandler // required interface when using the OnEndDrag method.
{
//Do this when the user stops dragging this UI Element.
public void OnEndDrag(PointerEventData data)
{
PlayerPrefs.SetFloat("scrollX", this.GetComponent<ScrollRect>().normalizedPosition.x);
}
}
You also need to apply the normalizedPosition once you initialized the ScrollRect and after you applied the desired content:
this.transform.Find("Scroll View").GetComponent<ScrollRect>().normalizedPosition = new Vector2(PlayerPrefs.GetFloat("scrollX"), 0F);

How to storage in runtime the data of GameObject? - Unity

I want to save the attribute of a gameObject but in runtime without Serializing anything. This I want to do when the object is selected. That way when I touch the paint button for example, paint the object that was selected.
What I tested so far is the use of the event OnMouseDown that is in the GameObject script and I also made another empty GameObject with the script that saves the attribute, but I can't save for example the name of the selected object. Although it shows it in the Debug.Log but returns log at the time of assigning it.
I applied the same logic in a new project with ObjSelect, SelectScript, ButtonsEventsScript scripts with the same prefabs and GameObjects but without Vuforia and it worked great.
Repository: https://github.com/emicalvacho/MapaMentalAR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjSelect : MonoBehaviour
{
private string nombre;
void OnEnable() {
SelectScript.OnName += HandlerOnName;
}
void OnDisable() {
SelectScript.OnName -= HandlerOnName;
}
void HandlerOnName(string str){
Debug.Log("NOMBRE DEL OBJETO SETEADO: " + str);
nombre = str;
}
public string getNombre(){
return nombre;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class SelectScript : MonoBehaviour
{
public GameObject cube;
private GameObject findObj;
public GameObject gameObjectManager;
public delegate void _OnName (string str);
public static event _OnName OnName;
private bool band;
public void OnMouseDown()
{
if(OnName != null)
OnName(cube.name);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonsEventsScript : MonoBehaviour
{
public ObjSelect script;
private GameObject obj;
public void ChangeColor(){
Debug.Log("OBJETO A PINTAR ES: " + script.getNombre());
}
}
I don't have any error messages, but it returns a null instead of the name of the selected GameObject.
If anyone has any other way of doing this, I ask you to help me for more than a week that I've been stuck. I already asked in other forums and nobody gives me a solution or a way to solve.

Unity Changing the Text of an object in another script/scene

Basically, I have this Text (scoreText) which is in my "Menu" scene so hence I have initiated it in GameControlMenu.cs, however, I'm trying to change its text from my other script GameControl.cs whilst I'm currently on my "Main" scene.
GameControlMenu.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameControlMenu : MonoBehaviour
{
public static GameControlMenu instanceMenu;
public Text scoreText;
void Start()
{
//does stuff but not important to question
}
}
GameControl.cs:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class GameControl : MonoBehaviour
{
public static GameControl instance;
public int score = 5;
void Start()
{
GameControlMenu.instanceMenu.scoreText.text = "PREVIOUS SCORE: " + score;
}
}
This setup works for a couple of my other variables which I'm accessing from another file but for whatever reason this just keeps throwing me the error: NullReferenceException: Object reference not set to an instance of an object
Any help is appreciated :)
You can't do GameControlMenu.instanceMenu... since GameControlMenu is in another scene as you described, and the instance isn't in the current scene.
But what you can do is to store the value somewhere first, and let the GameControlMenu use it when the other scene loads like so:
GameControlMenu.cs
public class GameControlMenu : MonoBehaviour
{
public static GameControlMenu instanceMenu;
public static string StuffToShowOnScoreText { get; set; }
public Text scoreText;
void Awake()
{
// So that it loads the text on start
scoreText.text = StuffToShowOnScoreText;
// ...
}
}
GameControl.cs
public class GameControl : MonoBehaviour
{
public static GameControl instance;
public int score = 5;
void Start()
{
// Store the value
GameControlMenu.StuffToShowOnScoreText = "PREVIOUS SCORE: " + score;
}
}

Sending a Boolean as a field to another script

I saw this question asked some times but no one correlates to mine. I see people using the GetComponent() function but this one should work too.
First I receive a Bool value from a toggle button and assign it as a field of the object 'hydro':
hydroControl.cs
using UnityEngine;
using System.Collections;
using Assets.Code.PowerPlants;
public class hydroProwerControlPanel : MonoBehaviour {
private HydroElectric hydro;
public bool t1;
void Start ()
{
t1 = true;
}
public hydroProwerControlPanel (){
hydro = new HydroElectric();
}
public void turbine1State (bool t1) {
hydro.t1Bool = t1;
}
The I have the object where this bool change should be recognized and sent as an output, but it doesn't:
using System;
using UnityEngine;
namespace Assets.Code.PowerPlants
{
public class HydroElectric
{
public bool t1Bool;
float turbina1;
public float prod;
public HydroElectric ()
{
t1Bool = true;
prod = 0f;
}
public float ControlPanel ()
{
turbina1 = t1Bool ? 1.5F : 0;
prod = turbina1 ;
Debug.Log (prod);
return prod;
}
}
}
As requested, this is where the function ControlPanel() is called:
using System;
using UnityEngine;
using UnityEngine.UI;
using Assets.Code.PowerPlants;
namespace Assets.Code.Interfaces
{
public class PlayLevel1 : MonoBehaviour
{
private HydroElectric hydro;
public Text producao;
public PlayLevel1 ()
{
hydro = new HydroElectric();
}
public void OnGUI()
{
producao.text = hydro.ControlPanel().ToString();
}
}
}
Do you have any idea why does this Bool does not get updated? Any help appreciated.
PlayLevel1's Hyrdo and hydroProwerControlPanel's hydro object are two different instances. Change in one instance will not reflect the change in second instance both are independent instances .
The thing you want to achieve is only possible if you make HydroElectric static class with static members.
Hope it will help.

Categories

Resources