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.
Related
I am trying to create a RuntimeReferenceImageLibrary and I have always this error:
NotSupportedException: No image tracking subsystem found. This usually
means image tracking is not supported.
UnityEngine.XR.ARFoundation.ARTrackedImageManager.CreateRuntimeLibrary
(UnityEngine.XR.ARSubsystems.XRReferenceImageLibrary
serializedLibrary) (at
Library/PackageCache/com.unity.xr.arfoundation#4.2.6/Runtime/AR/ARTrackedImageManager.cs:95)
Is there any way to change my subsystem and make it possible ?
I used the same project with the same XRReferenceImageLibrary and the ARTrackedImageManager and if you add the picture in the editor everything is working fine.
The problem is when you want to create a RuntimeReferenceImageLibrary for adding pictures in runtime.
//Definition
public XRReferenceImageLibrary serializedLibrary; //Set up in the editor
private ARTrackedImageManager trackedImageManager; //Set up in the awake function
I called this function in the Start function and also I tried to call it afterwards. Always I got the same result
private void TryOut()
{
if (trackedImageManager != null)
{
if (serializedLibrary != null)
{
if (trackedImageManager.enabled == true)
{
Debug.Log("Image manager and XR Reference found");
RuntimeReferenceImageLibrary runtimeLibrary = trackedImageManager.CreateRuntimeLibrary(serializedLibrary);
}
}
}
}
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.
I've been working on making a project of mine more modular. Something I've wanted to do is have multiple buttons use the same function when they perform a similar action, but with different values. I've been stuck on trying to apply this to the following situation:
"When this button is clicked, have the user select an image, and then have a PictureBox display the selected image". Each button has its own PictureBox. All Controls have been created before runtime.
Hope that makes sense!
My last attempt can be seen in the code below- I have tried assigning the Controls(Button and PictureBox) to variables to be stored together in a class. There's 6 of these classes all included within a single List.
I've also tried to store only the Control Names and then using this.Controls.Find to retrieve the Controls.
I've tried quite a few smaller changes such as passing by reference, making the List static, and things such as that would (somehow)magically do the trick- I've gotten desperate.
public class score_control
{
public Button score_button;
public PictureBox score_picture;
public int picture_index;
}
public List<string> score_boxes_names = new List<string>();
public List<score_control> score_boxes = new List<score_control>();
public void add_score_control(Button button, PictureBox pictureBox)
{
score_control new_score = new score_control();
new_score.score_button = button;
new_score.score_picture = pictureBox;
new_score.picture_index = score_boxes.Count();
score_boxes.Add(new_score);
score_boxes_names.Add(button.Name);
}
public score_control find_score_control(string name)
{
int index = score_boxes_names.IndexOf(name);
return score_boxes[index];
}
public frm_settings()
{
InitializeComponent();
add_score_control(btn_score1_image1, pic_score1_image1);
add_score_control(btn_score1_image2, pic_score1_image2);
add_score_control(btn_score1_image3, pic_score1_image3);
add_score_control(btn_score2_image1, pic_score2_image1);
add_score_control(btn_score2_image2, pic_score2_image2);
add_score_control(btn_score2_image3, pic_score2_image3);
}
private void score_button_Click(object sender, EventArgs e)
{
Button image_button = (Button)sender;
if (ofd_png.ShowDialog() == DialogResult.OK)
{
score_control clicked_control = find_score_control(image_button.Name);
score_image[clicked_control.picture_index] = ofd_png.FileName;
clicked_control.score_picture.Image = Image.FromFile(ofd_png.FileName);
}
}
The problem seems centered around this line:
clicked_control.score_picture.Image = Image.FromFile(ofd_png.FileName);
The program throws a NullReferenceException , but clickedcontrol is being recognized in the Local Watch, as well as score_image being noted to be a PictureBox(as it should be).
When I instead held the Control Names in the class, I had broke this line down into multiple lines, but the following line produced a NullReferenceException:
Control[] find_control = this.Controls.Find(clicked_control.score_picture, true);
In this case, clicked_control.score_picture would be a string containing the PictureBox Name. Again, the Local Watch showed that it clicked_control was not null, and neither was score_picture.
Any help figuring out how to properly store a Control within a variable to later be used to modify that Control's properties would be greatly appreciated.
dontpanic was able to help me out with this one. The issue was actually outside of this code - it had to do with the line score_image[clicked_control.picture_index] = ofd_png.FileName;. The way score_image was initialized as an array was incorrect. Fixing that made everything work fine.
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.
Little silly question, but got stuck for a long time.
I have written two classes one which is a Form (TreeDisplay class) and other which contains buiseness logic (MyTreeNode class).
TreeDisplay class contains browse button to select a file pass it to a method initiatingTree(string filename) which is in MyTreeNode class.
Now I have to pass this string parameter filename to MyTreeNode class. When I run my code the XML file which I have selected is shown in the textbox but not in treeview.
I have written the part of code but it is throwing NullReferenceException(Object reference not set to an instance of an object).
When the whole code was writeen in Form.cs the code was running successfully but on separating the business logic the exception has occured.
Can you please tell me where I am wrong?
This is the code in Browse button of TreeDisplay class (My main form):
if (open.ShowDialog(this) == DialogResult.OK)
{
txtFileName.Text = open.FileName;
MytreeNodeClass treenodeClass = new MytreeNodeClass();
treenodeClass.initiatingTree(open.FileName,treeView1);
}
Here is the code of initiatingTree() in my MyTreeNode class:
public class MytreeNodeClass
{
private readonly System.Windows.Forms.TextBox txtFileName;
private TreeView treeView1;
private readonly ToolStripStatusLabel toolStripStatusLabel1;
public string Filename
{
get { return filename; }
}
protected string filename;
public MytreeNodeClass()
{
}
public void initiatingTree(string nameofFile,TreeView treeView1)
{
try
{
//Create XML document & load the XML file.
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(nameofFile);
treeView1 = new System.Windows.Forms.TreeView();
treeView1.Nodes.Clear();
if (xmlDocument.DocumentElement != null)
{
TreeNode treeNodedoc = new TreeNode(xmlDocument.DocumentElement.Name);
treeView1.Nodes.Add(treeNodedoc);
}
On using breakpoint treeView1.Nodes.Clear(), the code comes out from this line and enters the catch block throwing NullReferenceException.
Please help to find root cause of exception. Thanks.
What is the value of treeView1 at your breakpoint?
I suggest this may be null, as the reference isn't available in your Business Logic Layer.
Updated with sample code:
public void initiatingTree(string nameofFile, TreeView treeView1)
{
try
{
//Create XML document & load the XML file.
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(nameofFile);
treeView1.Nodes.Clear();
if (xmlDocument.DocumentElement != null)
{
TreeNode treeNodedoc = new TreeNode(xmlDocument.DocumentElement.Name);
treeView1.Nodes.Add(treeNodedoc);
}
}
}
and where you call this:
if (open.ShowDialog(this) == DialogResult.OK)
{
txtFileName.Text = open.FileName;
MytreeNodeClass treenodeClass = new MytreeNodeClass();
treenodeClass.initiatingTree(open.FileName, treeView1);
}
As c.k said.
You don't have access to the usercontrols from your business layer as a standard.
May i suggest that you keep you control code in the gui code behind for simplicity.
An example how to sort your code
(Gui Layer) Codebehind for control interaction
Business Layer for data manipulation
Data Layer for database manipulations and such
Initialize the treeView1 object before accessing it.
I guess you copied and pasted, right?
Anyways here's a little note:
When you drag controls on a form in VS Designer, vs generates code for these controls "usually in InitializeComponent()". VS writes the references in your class (e.g form1.cs) like the following:
private System.Windows.Forms.TreeView treeView1;
this is just declaring a variable of type System.Windows.Forms.TreeView this variable (itself) is stored on the stack, because it's just a reference, a reference that doesn't point to any actual heap objects till now (i.e NullReference). Now this reference is useless and you can't use it unless you initialize it and tell it to point to a real object on the heap, and that's what VS does for you in the designer, it simply adds the next line to InitializComponents:
this.treeView1 = new System.Windows.Forms.TreeView();
And this is the line that you forgot to copy to the other class, which left your reference uninitialized (i.e still NullReference), hence when you tried to use it, a NullReferenceException was thrown. I guess this is your problem or at least this is how i could understand it. Forgive me if i failed to understand you!