#What s your current code or function
1 messages · Page 1 of 1 (latest)
I understand that, but I highly doubt that my baseoffset will change, so I don't see the need to make it a variable
technically I could
I'm working on code that dynamically spawns UI elements based on the amount of items already existing
and places them accordingly
But it's zero.. and you said it would become 75 (the next iteration?)
0 elements
1 element
2 elements
and so on
I'm trying to make this behaviour in code
So I'm guessing you were going to copy and paste it a bunch of times?
copy and paste what?
busGroups[iOffset].Panel.GetComponent<RectTransform>().position = new Vector2(0, 0 + iOffset * (-iPreviousItemHeight));```
this line?
I plan on repurposing the formula for items that go inside the group
and those items start at a base offset ot 75
then the offset (calculated on existinig elements) would be around -100
so the UI elements don't overlap, and get placed properly
so the whole thing should scale according to how many elements the user creates
So.. how does 0 + iOffset ... play a part in this?
When does 0 change? (in code)
this is my end goal
it doesn't
there is no use for the 0
I know
it's just a me-thing
for the calculation for the Bus itself (the item that goes inside the group) I'll use
0, 75 + iOffset * (-100)
or something like that
in this case it's not
But this implies you're not reusing but likely copying/pasting many lines.
not really copy-pasting, I don't trust myself blindly doing that
I'll be copying manually, typing it out as I go
because I'll be using different variables
for the other calculations
So what the next value after 75?
the Time with the text field will also use the calculation, since the user can add more timeslots
that offset would be...
125
and each new item will have an additional offset of 65
those are the 3 layers of UI elements I'm working with
I'm still working on the first, the groups, however
I'm one to over-engineer stuff, but I always have trouble thinking of easier ways to do things
this is my first major project so...
¯_(ツ)_/¯
So it would be ```cs
0, i * 65 + offset * (-100)
Or so.. excluding the initial 75 at second attempt
I guess, except i would be static, and the (-100) would change based on which element this formula was applied
i would also change baseed on which element the forumla was calculating for
i is not static but possibly a argument passed into the function 🤔
here are the values I'm working with
they're 3 separate methods
so I'll have 3 copies of that math formula
oh. I just realized a massive flaw with my math formula
0 is the base offset, the starting position of the UI element. That's fine.
iOffset is the number of elements that already exist.
iPreviousItemHeight is the height of the previous UI element.
0 + iOffset * (-iPreviousItemHeight)
I just noticed that not all the UI elements have the same height, the first one could have a height of 500, the second 750 etc. this formula wouldn't calculate the position for the new element correctly
I need to gather the heights for all the elements
So what's the name of the first function? I'm trying to figure out how exactly these three relate and if consolidation is possible.
lol atm I'm trying to figure out how to even calculate the location of the new element dynamically
from the pictures above, you can see, if the user presses the "new group" button, a new UI element will be spawned from a prefab, and it has to somehow calculate where to position itself
I want it to position itself right below the previous element
I'm stuck working out a math formula for this
I'd just have some collection of data and then when evaluating new position, offset, or height calculate their necessary adjustments dynamically.
as of now my plan is - every time a new panel is spawned, the panel position and height is stored in the class
and I can use that
Give me the name of the first function then I'll provide a pseudo code example
first function?
the one that handles the group spawning is called SpawnNewBusGroup()
I don't see a name for the first. Spawn new bus is the second and add bus time slot is the third.
I think I'll need to create some sort of for loop - cycle through every index of the panelHeight variable, and add it to a temporary variable
then I can use that as a flat offset
added with the base offset
Right
that would make more sense, yes?
Yes
now the question is how do I set up that for loop
It's greatly preferred over hard coding (manually copying pasting)
I think for (i = 0, busGroups.Count >= i)
I'm trying to help you out here but I'm unsure of the data to be changed
I'm guessing they're all just Buses?
I know my stuff is really damn complex and all over the place
I appriciate you trying to help me
this was my crappy rough sketch of how the system is supposed to work
the user can create groups. they can add busses into that group. the user can also add timeslots to each bus.
and as of now, I want to figure out how to make code that is able to dynamically calculate where to position the UI elements based on how many already exist
timeslot is a child of bus, so position is relatiive and only affected by the number of timeslots the bus has
bus is a child of group, so position is also relative to the number of buses in teh grou
that's how I'm working with those offset numbers, since everything is relative, I only need the fixed offset numbers based on how big the element is
but the complicating factor is that the bus element can be made longer by adding moroe timeslots, thus affecting the offset of the next bus element
and same for the groups - the more busses added into the group, the bigger it gets, and the more the offset needs to be for the next group to spawn
and not all groups have the same siize as well...
ugh this is so confusing
honestly, is this even considered "beginner code" anymore? I think I'm biting off way more than I can chew, I just started back up with unity a few days ago...
So a List of Group which consist of up to three Buses(?) each with a List of Time(s)?
not up to three busses, any number
it's up to the user to create as many as needed
Alright, even easier
but now that I think about it I should probably add a cap
Group:
List of Buses.
Bus:
List of Times.
Project:
List of Groups.
yep, that's the gist of it
group and bus are already classes.
bus has a list of times.
group has a list of bus.
the main project (unity class) has the list of groups.
this is what I'm triyng to figure out right now. I need to get the length of all the previous elements in that "grouP" so I can calculate the offset for the new UI element
I'm absolutely destroying my brain right now
I'm starting to have a personal connection with one meme I saw from r/programmerhumor
Well, the idea is.. You'd Create the UI object Group and it'd have UI Bus objects and Bus would have UI Time.
However much space it takes, you'd just move the parent of the next Group down.
Where the parent would maintain their actual positions and children just grow inside.
As you add more elements, the Groups thereafter adjusts their positions.
So if Group 5 added some new UI stuff like Buses and Time, we'd just adjust the Groups after 5 (not their children of Buses and Times)
That way, you could easily insert in between without having to manage ever single ui element.
You'd only really be managing Group positions and that groups children.
The Groups below would move as a whole.
Group?
I've got prefabs set up that have all the elements in them
and all I have to do is set the size of the element, specifically, the height
I'll try building an example, give me a couple of minutes.
since everything inside is anchored nicely
no problem
is the example about how to make the UI elements? because I got that down
all 3 element groups can be resized and the elements inside will stay in place properly
theoretically there is no problem with this code, right? sets the position of the newly spawned panel to the offset. (in this case, iTotalPanelHeights is 0, so the offset is 0)
but when I test out the code...
busGroups[iOffset].panel.GetComponent<RectTransform>().position = new Vector2(0, 0 + iTotalPanelHeights); //uses the total panel height to calculate the offset for the new element.
it gets put at (0, 0) in world, not relative to the parent
ah nevermind, found the solution
closer but not quite
the width...
Likely has to do with your camera and free aspect. Busy day, probably won't get back to this for a while.
I think I got everything worked out
the group UI element can spawn and adjusts itself accordingly to the number of elements
now I need to repeat the code for the bus element inside the group element, and make the group resize itself accordingly
this is the final result for the spawning of the UI element, it works yay
public void SpawnNewBusGroup()
{
int iOffset = busGroups.Count; //called first because it's a 0-based counting system, so first index is 0 offset, second item is 1 offset etc.
float iTotalPanelHeights = 0;
busGroups.Add(new BusGroup() {panel = Instantiate(busGroupPrefab, contentPanel), panelHeight = 250f});
for(int i = 0; busGroups.Count > i; i++)
{
iTotalPanelHeights = busGroups[i].panelHeight + iTotalPanelHeights; //loops through every entry, adding the panel height to the total.
}
busGroups[iOffset].panel.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, 0 - iTotalPanelHeights + busGroups[iOffset].panelHeight); //uses the total panel height (minus itself) to calculate the offset for the new element.
contentPanel.sizeDelta = new Vector2(0, 150 + iTotalPanelHeights); //content panel set to the height of all group UI elements.
/*
Notes: to add:
- panelheight modified in SpawnNewBus
- busGroups.name to be updated in a separate method, UpdateBusGroupData?
*/
//content height: item height + 150
//starting position: 0
//offset: -previous item height
//height starting: 500
//height offset: 300
}
now I can move on to the next roadblock - figuring out how to find the parent for UI elements
since the UI elements are part of a prefab, I don't know how to figure out which is the parent object.
goal:
take the input in the field, and use that to set a string in the related index in the list.
example: Group 1's field gets edited. The code should: busGroup[0].name = textfield.value or something like that. How do I know which index to use? that's what I'm trying to figure out now
Not gonna read the whole thing, so might be misunderstanding the issue, but you can get the parent transform with transform.parent, the get a GO/component from it, or use GetComponentInParent to get a component directly.
GetComponentParent eh? interesting
this is the best summary of what I'm working on. the user can create groups. inside the groups, the user can add busses. each bus can also have timeslots added by the user.
GetComponentInParent. I suggest also looking at the GameObject and MonoBehaviour pages of the docs. There are many useful functions to discover.
right now I'm trying to get the UI working
since this invoolves instantiating prefabs, I have no idea how to make dynamic code
since so far I've only been hard-coding stuff
for example, a runtime-spawned user input field wouldn't know under which group it was
meaning I don't know where to store the data
It's pretty straight forward. Instantiate, get the component, set it up.
You can pass the group in when setting it up.
but the input field is part of the group
I instantiate the prefab, which includes the input field, and the prefab is added to the list directly. How does the input field know which list index it is in?
Then the input field needs to know what group it belongs to. Or do even smarter and don't make the input field responsible for something that's no it's function.
By setting it up.
Or whatever is responsible for it.
hm. is it possible instead to get the inputfield's component from a "manager script", and have a function trigger when the value is updated?
up until now I've been operating under the assumption that only the inputfield can trigger something when the value is updated
controller = Instantiate (prefab)
controller.Setup(myGroup)
Or something
not that somethingn viewing it could be triggered on it's own
There are many ways. You could monitor the input field from somewhere else, or subscribe to it's value changed events.
now that seems more reasonable
how do I "subscribe" to the input field? since my manager script already accesses most of the things inside the UI element, I might as well just add that there
is there a function that gets called when the value is changed, or do I have to manually check in the Update() function?