#I forgot as well
1 messages · Page 1 of 1 (latest)
so cool
So yeah, I understand the basics of for loops at the simplest level.
Okay. So, you then say something like this:
for(i = currentCam; i = cameras.Length; i++)
Ok
Oh wait, would I have it in the for loop that if currentCam doesn't have the tag it exits the loop?
this basically says "we're gonna start at the head of the collection (current cam). Every time we finish the block of code, increase i by one. Stop when we get to the end."
{
if(cameras[i].tag == "Locked") continue;
I think you could do if (//doesnt have tag) return; you could stop the entire function at that point "return"
This line (probably messed up some syntax sorry lol) is the guard clause. Continue means you just skip the rest of the block and go to the next iteration
// do stuff
}
sorry, got ahead of myself
Would that not constantly add until its at the end of the array?
sorry
no worries. I'm thinking through the problem myself
ah! Okay. So the issue is that if you're on element [3] of length 6, by you want to loop all the way back to 3 if everything is locked
hmm
that's why I was concerned about the while loop: it assumes at least one camera is unlocked
Or any combination of locked and unlocked. Say there's 6 in an array, I'm at 2, and numbers 3 and 4 are locked. I want to go to 5
but if that assumption is safe, then maybe a while loop IS better
Then if I'm at 5, and 6 and 1 are locked, I want to go to 2
okay so
[
0 => Untagged
1 => Untagged
2 => Untagged (but currentCam points here)
3 => Locked
5 => Untagged // <- next
]
Yeah
Cool. Okay. So instead of using cameras locked status in while condition, we're gonna use the currentCam I think.
What do you mean
yeah hold on lol I already mispoke
xD
I should jsut write in code
while(true)
{
if(cameras[currentCam].tag == "Locked")
{
currentCam++; // skip this camera
continue; // go back to beginning of the loop, skipping the remainder of the loop
}
currentCam++; // get next unlocked camera
if(currentCam == cameras.Length) { currentCam = 0; } // if we are at the end of the array, loop back to zero
break; // exit the loop, ignoring while(true)
}
Does this also just go to the next one normally if there isn't a locked camera?
I THINK this should work lol. It's weird, and "smelly". I would do it a much different way personally, creating a collection class that's dedicated to the process of iterating through things and returning to the beginning, but this might be closest to your skill level. The for loop someone else suggested using % is also great though. Just assume you don't understand modulus.
Oh right. Like I said. While loops are easy to f up lol
erm. editing
there lol
THAT should do it.
ahahahahaha I did a super dumb
edited. I put currentCam = cameras.Length
which means, in the above example array, EVERY loop iteration, currentCam would be 6. Every time. Which is, of course, outside the bounds of the array
double == is a comparison
I did that, and it didn't work.
same thing still?
Yeah
I even tried using a >= comparison
void incCamera()
{
cameras[currentCam].tag = "Untagged";
cameras[currentCam].GetComponent<AudioListener>().enabled = false;
cameras[currentCam].enabled = false;
while (true)
{
if (currentCam == cameras.Length) { currentCam = 0; } // if we are at the end of the array, loop back to zero
if (cameras[currentCam].tag == "Locked")
{
currentCam++; // skip this camera
continue; // go back to beginning of the loop, skipping the remainder of the loop
}
currentCam++;
break;
}
cameras[currentCam].tag = "MainCamera";
cameras[currentCam].GetComponent<AudioListener>().enabled = true;
cameras[currentCam].enabled = true;
}```
and the error takes you to which line? presumably cameras[currentCam].tag?
49 which is cs cameras[currentCam].tag = "MainCamera";
oh!
put if (currentCam == cameras.Length) { currentCam = 0; } // if we are at the end of the array, loop back to zero directly above the break instead of at the top of the loop
Now it doesn't skip cameras with the locked tag
grah. I'm genuinely embarassed that I have not figured this out. It should be trivial 😄
I'm sorry
I'm also embarassed by using a while loop. Feels like the wrong answer still
xD
no worries, no worries!
Only reason I use a while loop is because an If loop would only run once and wouldn't help if multiple locked cameras were in a row
It's ok.
cameras = [ // example array
0 => Locked
1 => Untagged // <-- goal
2 => Untagged
3 => Locked
4 => Untagged // <-- head
]
head = 4;
while(true)
{
head = (head + 1) % cameras.Length;
if(cameras[head].tag != "Locked")
{
break;
}
}
okay ima teach you about mod because it's extremely relevant and super common
for jobs like this
modulus is the % sing
sign
What
if head is 4, and cameras.Length is 5, then that one line reads head = (4+1) % 5
i.e. 5 % 5
mod is an operator that gives you a remainder.
ok
imagine 5 divided by 5. It's equal to?
1
what about 6/5
1.2?
good
that can also be expressed as "1 remainder 1"
what do you thing 5/5 would be expressed as with remainders?
1 remainder 0
yep1
!
so, mod tells us what the remainder is. It doesn't care about the first number
5%5 = 0. 10%5 = 0
This is the trick that lets you wrap around a range of numbers
Got it i think
try the code above. replace head with currentCam. I needed to use head because my brain is not wroking lol
just the while loop tho
wait
sorry
Doesn't skip
yeah, had to change it again
have to go to the next camera first, then check for locked status
otherwise head never changes
lol
by the way, i've been dabbling in coding for a decade, and got paid thousands this year for code I deployed. I've always had issues with these kinds of circular arrays
It works. Thank you very much.
YES!
I definitely realized how little I know.
sorry about the back and forth lol
No worries
hahaha okay so while I have you, show me that whole function
void incCamera()
{
disableCam();
while (true)
{
currentCam = (currentCam + 1) % cameras.Length;
if (cameras[currentCam].tag != "Locked")
{
break;
}
}
enableCam();
}
Any ideas how I can modify it for going the other way around? So go from 3 to 2 to 1?
oh cool you already refactored (extracted methods and renamed them). I would advise refactoring this while loop as well. Call it something like "getNextCamera"
(currentCam - 1) % cameras.Length
just change the sign 🙂
Tried that and it doesn't work
Yeah index
wait no, that's not right. -1%5 is still positive
that was me "thinking aloud". Ignore
huh. that really should work. Throw a Debug.Log(currentCam) at the beginning of the loop
I get zero
while (true)
{
Debug.Log(currentCam);
currentCam = (currentCam - 1) % cameras.Length;
if (cameras[currentCam].tag != "Locked")
{
break;
}
}
so, it says zero and then the index out of range?
yes
weird. 0 is the first item in the index
it should never be out of range unless an array is uninitialized
how many cams do you have in the scene?
Currently 5
and how do you get the "cameras" array?
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
ty one moment
So, just to clarify, on decrement, the Console says 0, then index out of range, and the index out of range points to line 67?
Yes
oh, move the debug.log down underneath the modulus
that "should" be -1 for some reason. Or maybe -4
-1
Yeah?
I've never really had to do negative mods in c# but APPARENTLY it works very differently than an actual modulo because it's a "remainder"
-1 / 5 = 0 remainder -1
which is why it's giving us -1
ok?
this is a common complaint on stack exchange lol
so what's the fix?
so to reverse it you have to write your own ACTUAL modulo function
int mod(int x, int y)
{
return (x % y + y) % y;
}
and then use that instead of %, so currentCam = mod(currentCam - 1, cameras.Length)
I think that should work.
It works. Thanks.