#I forgot as well

1 messages · Page 1 of 1 (latest)

modern quartz
#

This should do it

lilac mason
#

so cool

modern quartz
#

So yeah, I understand the basics of for loops at the simplest level.

lilac mason
#

Okay. So, you then say something like this:

for(i = currentCam; i = cameras.Length; i++)
modern quartz
#

Ok

#

Oh wait, would I have it in the for loop that if currentCam doesn't have the tag it exits the loop?

lilac mason
#

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;
wheat pier
#

I think you could do if (//doesnt have tag) return; you could stop the entire function at that point "return"

lilac mason
#

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

modern quartz
#

Would that not constantly add until its at the end of the array?

lilac mason
#

yes. wait for it

#

xDD

modern quartz
#

sorry

lilac mason
#

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

modern quartz
#

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

lilac mason
#

but if that assumption is safe, then maybe a while loop IS better

modern quartz
#

Then if I'm at 5, and 6 and 1 are locked, I want to go to 2

lilac mason
#

okay so

[
  0 => Untagged
  1 => Untagged
  2 => Untagged (but currentCam points here)
  3 => Locked
  5 => Untagged // <- next
]
modern quartz
#

Yeah

lilac mason
#

Cool. Okay. So instead of using cameras locked status in while condition, we're gonna use the currentCam I think.

modern quartz
#

What do you mean

lilac mason
#

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)
}
modern quartz
#

Does this also just go to the next one normally if there isn't a locked camera?

lilac mason
#

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.

modern quartz
#

Lemme test

#

Same problem as before. It doesn't loop back around and give me this

lilac mason
#

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

modern quartz
#

I did that, and it didn't work.

lilac mason
#

same thing still?

modern quartz
#

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;
    }```
lilac mason
#

and the error takes you to which line? presumably cameras[currentCam].tag?

modern quartz
#

49 which is cs cameras[currentCam].tag = "MainCamera";

lilac mason
#

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

modern quartz
#

Now it doesn't skip cameras with the locked tag

lilac mason
#

grah. I'm genuinely embarassed that I have not figured this out. It should be trivial 😄

modern quartz
#

I'm sorry

lilac mason
#

I'm also embarassed by using a while loop. Feels like the wrong answer still

#

xD

#

no worries, no worries!

modern quartz
#

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

lilac mason
#

yep yep

#

again, there are ways around that, I'm just apparently being dumb lol

modern quartz
#

It's ok.

lilac mason
#
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

modern quartz
#

What

lilac mason
#

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.

modern quartz
#

ok

lilac mason
#

imagine 5 divided by 5. It's equal to?

modern quartz
#

1

lilac mason
#

what about 6/5

modern quartz
#

1.2?

lilac mason
#

good

#

that can also be expressed as "1 remainder 1"

#

what do you thing 5/5 would be expressed as with remainders?

modern quartz
#

1 remainder 0

lilac mason
#

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

modern quartz
#

Got it i think

lilac mason
#

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

modern quartz
#

Doesn't skip

lilac mason
#

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

modern quartz
#

It works. Thank you very much.

lilac mason
#

YES!

modern quartz
#

I definitely realized how little I know.

lilac mason
#

sorry about the back and forth lol

modern quartz
#

No worries

lilac mason
#

hahaha okay so while I have you, show me that whole function

modern quartz
#
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?

lilac mason
#

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 🙂

modern quartz
#

Tried that and it doesn't work

lilac mason
#

oh

#

index out of range? right. absolute value

modern quartz
#

Yeah index

lilac mason
#

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

modern quartz
#

I get zero

#
while (true)
        {
            Debug.Log(currentCam);
            currentCam = (currentCam - 1) % cameras.Length;
            if (cameras[currentCam].tag != "Locked")
            {
                break;
            }

        }
lilac mason
#

so, it says zero and then the index out of range?

modern quartz
#

yes

lilac mason
#

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?

modern quartz
#

Currently 5

lilac mason
#

and how do you get the "cameras" array?

modern quartz
lilac mason
#

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?

modern quartz
#

Yes

lilac mason
#

oh, move the debug.log down underneath the modulus

#

that "should" be -1 for some reason. Or maybe -4

modern quartz
#

-1

lilac mason
#

yeah. okay, hmph. one moment

#

ahahahaha you've taught me something

modern quartz
#

Yeah?

lilac mason
#

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

modern quartz
#

ok?

lilac mason
#

this is a common complaint on stack exchange lol

modern quartz
#

so what's the fix?

lilac mason
#

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.

modern quartz
#

It works. Thanks.