So when developing a small little web-player, I ran into the problem of trying to render multiple instances of the same window function.
My plan was for my user interface component to iterate through all the thought components and for each thought, render its contents in a new window. The windows need to be draggable also.
My first attempt of this implementation failed.
For those who don't see the problem with this, I'll explain.
All three windows are using the same Rect thoughtRect so all the windows are drawn on top of eachother. You might think this won't pose a problem due to the windows being draggable, you can just move one away from the other, but this is Unity's GUI class, it's not fun. The GUI.DragWindow adjusts the thoughtRect, which in turn moves all 3 windows at once, still keeping them on top of each other.
So on my second attempt of implementing my feature, I got it thankfully. I probably coded my program differently from what others would, but I hope at-least it might give you an idea to fix a problem now or in the future.
In my thought class, I made a variable "Rect positionOnScreen", which keeps up of that thoughts position. I've also added two new methods in the thought class.
One, GetPosition(), returns a Rect, the positionOnScreen;
The other SetPosition(), is called to set the new Rect in the Though class's positionOnScreen.
When it gets to a certain thought in the for statement, it sets that certain thought to the currentThought. The point in this is so the DoThoughtWindow method has something to reference when its rendering it's contents. ***Notice currentThought = allthoughts[i]; is called BEFORE the DoThoughtWindow() is***
My plan was for my user interface component to iterate through all the thought components and for each thought, render its contents in a new window. The windows need to be draggable also.
My first attempt of this implementation failed.
Rect thoughtRect = new Rect(20, 20, 200, 100);
void OnGUI(){
for (int i = 0; i < allthoughts.Length; i++){
thoughtRect = GUI.Window(0+i, thoughtRect, DoThoughtWindow, ""+allthoughts[i].GetContent());
}
}
void DoThoughtWindow(int windowID) {
GUI.DragWindow(new Rect(0, 0, 10000, 10000));
}
For those who don't see the problem with this, I'll explain.
All three windows are using the same Rect thoughtRect so all the windows are drawn on top of eachother. You might think this won't pose a problem due to the windows being draggable, you can just move one away from the other, but this is Unity's GUI class, it's not fun. The GUI.DragWindow adjusts the thoughtRect, which in turn moves all 3 windows at once, still keeping them on top of each other.
So on my second attempt of implementing my feature, I got it thankfully. I probably coded my program differently from what others would, but I hope at-least it might give you an idea to fix a problem now or in the future.
In my thought class, I made a variable "Rect positionOnScreen", which keeps up of that thoughts position. I've also added two new methods in the thought class.
One, GetPosition(), returns a Rect, the positionOnScreen;
The other SetPosition(), is called to set the new Rect in the Though class's positionOnScreen.
When it gets to a certain thought in the for statement, it sets that certain thought to the currentThought. The point in this is so the DoThoughtWindow method has something to reference when its rendering it's contents. ***Notice currentThought = allthoughts[i]; is called BEFORE the DoThoughtWindow() is***
Thought currentThought;
void OnGUI(){
for (int i = 0; i < allthoughts.Length; i++){
currentThought = allthoughts[i];
currentThought.SetPosition(GUI.Window(0+i, currentThought.GetPosition(), DoThoughtWindow, ""+currentThought.GetTitle()));
}
}
void DoThoughtWindow(int windowID) {
if (GUI.Button(new Rect(currentThought.GetPosition().width-120, currentThought.GetPosition().height-30, 100, 20), "Edit")){
Debug.Log ("We need to edit this");
}
GUI.Box(new Rect(10,25 ,currentThought.GetPosition().width - 20,currentThought.GetPosition().height-65),"");
GUI.DragWindow(new Rect(0, 0, 10000, 10000));
}
My thought class so far in case you want to look at it yourself.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Thought : MonoBehaviour {
string thoughtTitle = "Thought";
public string thoughtContent = "Substance Goes Here";
List<GameObject> connectedThoughts = new List<GameObject>();
Rect positionOnScreen = new Rect(20, 20, 200, 200);
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public string GetContent(){
return thoughtContent;
}
public string GetTitle(){
return thoughtTitle;
}
public Rect GetPosition(){
return positionOnScreen;
}
public void SetPosition(Rect newPos){
positionOnScreen = newPos;
}
}
And a look at it being rendered.
Hello, I'm with this problem, but I can't set your code in my app.. First of all, who is this allthoughts? I imagine that is an array of Toughts, but where did you declare it? And how? I'm trying to set toughts objects in the allthoughts, but I'm getting a null exception when accessing them. Please, you're the only one who tells about it in whole internet and I'm desperate!
ReplyDelete