UNity3D error displaying variable from another script c# - c#

I got a UI Text element (inside a canvas) that I need to grab a value from another script.
The way I'm doing right now (and that was the closest I got to get it working) is:
public class AttributeValueController : MonoBehaviour {
//public AttributeName attribute;
[SerializeField]
private Text attributeValue = null;
// Use this for initialization
void Start () {
attributeValue.text = CharacterGenerator._toon.GetPrimaryAttribute("Might").AdjustedBaseValue.ToString();
}
I got the text component I want to be changed set on on the inspector to the "attributeValue".
When I run this I get the errors
Assets/Scripts/HUD Classes/AttributeValueController.cs(19,58): error CS0120: An object reference is required to access non-static member `CharacterGenerator._toon'
and
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.UI.Graphic.OnRebuildRequested () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Graphic.cs:480)
UnityEngine.UI.GraphicRebuildTracker.OnRebuildRequested () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/GraphicRebuildTracker.cs:33)
UnityEngine.CanvasRenderer.RequestRefresh () (at C:/buildslave/unity/build/artifacts/generated/common/modules/UI/CanvasRendererBindings.gen.cs:314)
Anyone can help? When I replace this function by "0" it works... I've searched everywhere and I cannot fix it

If CharacterGenerator isn't a static class, you can't access it like that. You would have to make an instance of the class to access properties.
CharacterGenerator cGen = new CharacterGenerator();
attributeValue.text = cGen._toon.GetPrimaryAttribute("Might").AdjustedBaseValue.ToString();
Although, given this is a new instance of the class, I would not expect these properties to be populated, but perhaps your class is structured so that they are.

Related

Question about PhotonNetwork.CurrentRoom.CustomProperties

When the game starts in multiplayer, the master client sends a PunRPC to have all clients run a function. This function tries to get the room properties to see if the game is active, if so it does something. For some reason a client gets a null reference error, but the master client does not. The strange thing is, a debug of the hash table for room properties is visible but I cannot get a specific item in it.
Tried Debugging the hash table to make sure that the key was set when the code was run. It was. "(System.String)ag=(System.Boolean)True ag=activeGame" This shows in Debug.Log(hash); But (bool)hash[rpk.activeGame] gets a null reference error. But only on the client side not the master client. So the key also works.
// Call all the clients to set up the room settings in the sub menu.
[PunRPC]
private void GameRoomSetup (string pOne, string pTwo, int pOneColor, int pTwoColor)
{
GameObject gameMenu = GameObject.Find ("GameMenu");
gameMenu.GetComponent<SubMenu> ().UpdatePlayers (pOne, pTwo, pOneColor, pTwoColor);
gameMenu.GetComponent<SubMenu> ().StartGameSetup ();
// If you are a player, change the active buttons that are visible.
if (PhotonNetwork.NickName == pOne || PhotonNetwork.NickName == pTwo)
{
gameMenu.GetComponent<GameButtonManager> ().GameStart ();
}
hash = PhotonNetwork.CurrentRoom.CustomProperties;
Debug.Log(hash);
if ((bool)hash[rpk.activeGame]) // Error on this line on client but not on master client. Says null reference.
{
GameObject.Find ("SoundManager").GetComponent<SoundManagerScript> ().PlayBackgroundTwo ();
GameObject.Find ("GameMenu").GetComponent<SubMenu> ().ChangeSubMenuActive (false);
}
}
I'm trying to run my if statement as a client but I get an error.
Thank you for choosing Photon!
To get a custom property, I recommend you use TryGetValue method as follows:
hash = PhotonNetwork.CurrentRoom.CustomProperties;
object temp;
string key = rpk.activeGame;
if (hash.TryGetValue(key, out temp))
{
if (temp is bool)
{
bool activeGame = (bool)temp;
}
else
{
// unexpected custom property value type
}
}
else
{
// custom property not found
}
If the custom property is not available yet, wait for the callback IInRoomCallbacks.OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) (reference API).
Other notes and recommendations:
private void GameRoomSetup (string pOne, string pTwo, int pOneColor, int pTwoColor)
Not sure if it's supported or if it's a good idea to pass multiple parameters to a PUN RPC method.
To debug log a Dictionary or a Hashtable you could make use of SupportClass.DictionaryToString() method.
so instead of
Debug.Log(hash);
use
Debug.Log(SupportClass.DictionaryToString(hash));
Avoid calling expensive methods like GameObject.Find:
GameObject gameMenu = GameObject.Find ("GameMenu");
Also here you have duplicate calls to gameMenu.GetComponent<SubMenu>(), at least call it once and cache the component result found if any.
gameMenu.GetComponent<SubMenu> ().UpdatePlayers (pOne, pTwo, pOneColor, pTwoColor);
gameMenu.GetComponent<SubMenu> ().StartGameSetup ();
Comparing strings should not be done using == operator. At least use Equal method and proper StringComparison type. Read "How to compare strings in C#".
// If you are a player, change the active buttons that are visible.
if (PhotonNetwork.NickName == pOne || PhotonNetwork.NickName == pTwo)
{
gameMenu.GetComponent<GameButtonManager> ().GameStart ();
}
Besides, why do you use the Nickname to check if it's player one or two? maybe use ActorNumber or a custom player index. Or use the player count if the room is for 2 players only.

How to read a textBox's Text in another window

I have a textBox, textBoxQuery, in window QueryWindow.
I need to access textBoxQuery's Text in another window, MainWindow.
I have the following accessor in QueryWindow:
public string QueryString
{
get { return textBoxQuery.Text; }
set { textBoxQuery.Text = value; }
}
And I attempt to use it in MainWindow:
cmdLine += QueryString;
However, I am thrown a CS0120 error. "An object reference is required for the nonstatic field, method, or property."
I have also attempted to implement the following method in QueryWindow:
public string queryString()
{
return textBoxQuery.Text;
}
Then using the following in MainWindow:
cmdLine += QueryWindow.queryString();
But none of the above worked.
I have searched through Google, but none of the solutions I found seemed to work. What is the correct way of accessing a control's properties from another window/class?
Oh!
The assessor is used to access an instance of a class (an object) of type QueryWindow!
Basicly, you could create a bunch of query windows (each would be their own instance) by doing this:
QueryWindow myQueryWindow1 = new QueryWindow();
myQueryWindow1.show()
QueryWindow myQueryWindow2 = new QueryWindow();
myQueryWindow2.show()
// Note, the shows are only needed to make instances visible to the user.
For as long as you have the reference to myQueryWindow1 or myQueryWindow2, you can use an acessor to get the state of the instance:
string myString = myQueryWindow1.queryString();
So QueryWindow.queryString() wouldn't work, because there is no way for the program to tell which instance of QueryWindow you want!
Hope this helps!

Unity3D C# - NullReferenceException although Text is attached and methods work

have no idea what is going wrong. There is a problem by outsourcing some code in another class. If the following code is in the same class, it works fine.
SearchClient.cs
void callExposeAPi (string id)
{
ExposeClient exposeClient = (new GameObject("ExposeClient")).AddComponent<ExposeClient>();
exposeClient.loadExpose(id);
}
ExposeClient.cs
public Text _baserentText; // is attached to Text in Unity
public void loadExpose(string id)
{
[some API stuff...]
Debug.Log(result.exposeexpose.realEstate.baseRent); // 480
makeUseOfExposeUI(result.exposeexpose.realEstate);
}
void makeUseOfExposeUI (Realestate realestate)
{
Debug.Log(realestate.baseRent); // 480
_baserentText.text = realestate.baseRent.ToString();
}
I see what is happening, in your callExposeAPi method you are creating a new instance of ExposeClient and then by looking at your comments in ExposeClient.cs you mentioned "is attached to Text in Unity" well when you assigned variables through the editor the association of _baserentText occurs with the object you manually associated through the editor, if you dynamically create an instance this association would have to be done in a different way or you could do something like this:
void callExposeAPi (string id)
{
ExposeClient exposeClient = GameObject.Find("ExposeClient").GetComponent<ExposeClient>();
exposeClient.loadExpose(id);
}
The difference here is that you are using a game object which already contains an ExposeClient script attached and its serialized field "_baserentText" has already been defined which will not throw a null exception.

Calling a constructor within another constructor using 'this' as an argument

I have the following code
public Insight3DPluginControl(Insight3DPlugin plugin, MapViewModel viewModel)
: base(plugin)
{
InitializeComponent();
RXMouse = new RXMapMouse(this);
eob_tool = new EOBTool(RXMouse);
}
and I've been trying to wrap my head around the use of 'this' in new RXMapMouse() that is being called by 'this's constructor. I'm trying to understand the reason for doing this and what the design pattern would be called.
I understand that the object before being passed to RXMapMouse() is already initialized, but does that mean by changing the current Insight3DPluginControl object when we assign the RXMouse field, will then change the one inside of RXMapMouse()?
The "this" keyword is a "variable" representing the current object.
Maybe this ( :D ) will let you undestand it better:
public Insight3DPluginControl(Insight3DPlugin plugin, MapViewModel viewModel)
: base(plugin)
{
InitializeComponent();
Insight3DPluginControl theControl = this;
RXMouse = new RXMapMouse(theControl);
eob_tool = new EOBTool(RXMouse);
}
So, basically the "RXMapMouse" needs an instance of an "Insight3DPluginControl" int it's constructor and in that line the current Insight3DPluginControl where the code lives is being sent.

How can I edit a created control from another function?

If I have the following code:
Button[] _buttonarray = new Button[40]; // it is outside any function (situated in the public partial class MainWindow : Window)
And a new created button in a function called
private void createbutton()
{
_buttonarray[b]=new Button();
_buttonarray[b].Content = "Content";
...
}
How Can I edit _buttonarray[b] content from another function like,
private void editbutton()
{
_buttonarray[b].Content = "New Content";
}
Note: variable b is outside so it can be change from any function.
Make it Static:
public static Button[] ButtonArray = new ..
and use MainWindow.ButtonArray to access it.
Worth pointing out that by doing that, it is shared throughout every instance of your MainWindow.
Edit:
Just to point out - rather than saying 'outside' it is more common to use the definition of Scope , simply put - if you can access something A from somewhere B,then A is in B's Scope.
Also - read more regarding static here: Static and instance fields
If you want to edit a specifically created button, you can keep that button in a designated field, which is in both the creation code's scope and the alteration code's scope:
var myButton = new Button(){Content="Content"};
_buttonarray[b]=myButton;
SomethingInCommon.SpecificButton = myButton;
and the access it elsewhere that have access to SomethingInCommon.
Keep SpecificButton value until you don't need it any longer.
You're editing a button with the code you have, it's just that it's probably not the one you're expecting because the index of b has likely been iterated. Just access the right index, possibly by using Find and a predicate on Content to make sure you're editing the right button.

Categories