- Home /
Inverse Modulo?
if (Input.GetKeyDown("q"))
{
int i = 0;
while (!Players[i].GetComponent<PlayerSelectionCheck>().Active && (i < Players.Count))
{ i++; }
Players[i].GetComponent<PlayerSelectionCheck>().Active = false;
Players[i].GetComponent<PlayerSelectionCheck>().OneTime = false;
//if active
Players[(i + 1) % Players.Count].GetComponent<PlayerSelectionCheck>().Active = true;
Players[(i + 1) % Players.Count].GetComponent<PlayerSelectionCheck>().OneTime = false;
}
in this Script it turns off Active for the current active object and turns it on for the next one in the list.
if (Input.GetKeyDown("e"))
{
int i = 0;
while (!Players[i].GetComponent<PlayerSelectionCheck>().Active && (i < Players.Count))
{ i++; }
Players[i].GetComponent<PlayerSelectionCheck>().Active = false;
Players[i].GetComponent<PlayerSelectionCheck>().OneTime = false;
//if active
Players[(i - 1) % Players.Count].GetComponent<PlayerSelectionCheck>().Active = true;
Players[(i - 1) % Players.Count].GetComponent<PlayerSelectionCheck>().OneTime = false;
}
this script should do the same but in the inverted direction but the modulo does not work with - numbers. so i made this script:
if (Input.GetKeyDown("e"))
{
int i = 0;
while (!Players[i].GetComponent<PlayerSelectionCheck>().Active && (i < Players.Count))
{ i++; }
Players[i].GetComponent<PlayerSelectionCheck>().Active = false;
Players[i].GetComponent<PlayerSelectionCheck>().OneTime = false;
//if inactive
i--;
if (i < 0){i = Players.Count;}
Players[i].GetComponent<PlayerSelectionCheck>().Active = true;
Players[i].GetComponent<PlayerSelectionCheck>().OneTime = false;
}
but for some reason this still does not work... can someone tell me where the mistake is?
the mistake was not with the modulo. id had to do with Players.Count it is the number of objects in player list counted from 1 and not 0 (so just Player.Count-1)
No, that doesn't make much sense. You have to use Player.Count as divisor. The remainder is always smaller than the divisor. So for example if the count is 9 the remainder can never be larger than 8. That should make sense since a value of 9 would be divisible by 9 with 0 remainder. So using (Player.Count-1) as divisor makes no sense and won't solve the -1 issue.
Answer by Bunny83 · Mar 02, 2020 at 12:33 AM
Your issue is that the modulo operator will keep the sign of the number you're dividing, This is explained in the documentation. So if you have a value smaller than 0 (namely "-1" the modulo operator will return "-1" and not the divisor-1).
Your last code does actually work, however the value you set inside your if statement is wrong. The highest valid index is Player.Count - 1
.
ps: Now I maybe understand what you meant by your comment above, however it's misleading the way it's worded. The modulo operator doesn't work for negative numbers since it will return just the negative modulo. A common solution is to just "add" Player.Count to your modulo result if it's negative. So if the result is "-1" and you add Player.Count you actually get "Player.Count - 1". Of course since we need an if statement anyways we don't need to do the modulo since you always just decrement by 1. However a more general solution is this:
int w = i % Player.Count;
if (w < 0)
w += Player.Count;
This should works properly for any integer number i and it will be wrapped properly on both ends.
Some examples with a Count of "5":
// i | i%c | w | c
//-------|-----|-------|---
// 11 | 1 | 1 | 5
// 3 | 3 | 3 | 5
// 2 | 2 | 2 | 5
// 1 | 1 | 1 | 5
// 0 | 0 | 0 | 5
// -1 | -1 | 4 | 5
// -2 | -2 | 3 | 5
// -3 | -3 | 2 | 5
// -4 | -4 | 1 | 5
// -5 | 0 | 0 | 5
// -6 | -1 | 4 | 5
// -7 | -2 | 3 | 5
thanks for your explanation this will help for future scripts. but the way I did it works flawlessly for the purpose I'm using it for so I don't really care ;D.