Why doesn't Debug.Log work in this for loop? - c#

Here is what I have. This DrawPoints() method is called in an Update() method, meaning it is called repeatedly if it doesn't have extra conditions if I understand correctly. So basically I'm trying to make the for loop only run once by putting the outside if (iTrack == 0) check on it.
What is weird is that the Debug.Log commands will not run at all (the text "Here 1" or "Here2" never show up in Console), BUT the other code inside like var lerpedPosition and whatToSpawnClone run.
Why don't the Debug Log commands work? Is there something obviously wrong I'm doing with this code? This is very confusing.
int iTrack = 0;
int matricesNumber = 2;
public void DrawPoints()
{
int startIndex = 0;
int endIndex = mesh.vertexCount;
float t = Mathf.Clamp((Time.time % 2f) / 2f, 0f, 1f);
if (iTrack == 0) {
if (matricesNumber == 2)
{
for (int i = startIndex; i < endIndex; i++)
{
Debug.Log("Here 1");
var lerpedPosition = Vector3.Lerp(matrices1[i].position, matrices2[i].position, t);
whatToSpawnClone = Instantiate(whatToSpawnPrefab, lerpedPosition, matrices2[i].rotation) as GameObject;
if (i == (endIndex - 1))
{
Debug.Log("Here 2");
iTrack = 1;
}
}
}
}
}

Based on the description of your question I will assume that you are creating a script for Unity from here on out. Take a look at this. It offers two solutions that would be worth a try, mainly the second one as it is as simple as a check to make sure you have Debug output enabled for the console.

Related

C# loop going back and forth

I'd like to make a for loop that goes backwards after it reaches the end.
So when "i" reaches 10, instead of "i++" it should do "i--".
I've looked online for a little bit and couldn't find anything in C#. There's this post here, yet it's in JavaScript. I've rarely coded in JavaScript before, so I'm not sure how to translate that code into C# (if that even is possible).
I've successfully achieved this using the code below, yet it's lacking in the "readability" department. It also requires an extra variable, which I don't think is the most elegant solution.
Here's the code that I've written:
static void Main(string[] args)
{
bool reverse = false;
for(int i = 0; i <= 10;)
{
Console.WriteLine(i);
if(i == 10) reverse = true;
if(i == 0) reverse = false;
if(reverse == false) i++;
if(reverse == true) i--;
// Slow down the output
Thread.Sleep(20);
}
}
Again, this code works fine, yet I'm looking for a better solution than this mess.
Thanks in advance!
As small readability improvement I would suggest to change from the boolean flag to an integer increment value:
int increment = 1;
for (int i = 0; i >= 0 && i <= 10; i += increment)
{
Console.WriteLine(i);
if (i == 10) increment = -1;
else if (i == 0) increment = 1;
}

checkpoints c# in unity

i am making a game with c# in unity and i want that if you die in level 4 that you go back to level 0 but if you are in level 5 that you respawn in level 5
the code:
{
int currentSceenIndex = SceneManager.GetActiveScene().buildIndex;
if (currentSceenIndex <= 4)
{
SceneManager.LoadScene(0);
}
else if (currentSceenIndex == 4)
{
SceneManager.LoadScene(4);
}
}
what did i do wrong the respawn still works but i am always going back to level 0 how to fix this. I tried to follow an tutorial but it still did not work. I can't see the mistake and also I don't get any errors when playing the game so I don't know where the error is at.
It sounds like you would rather want to use
if (currentSceenIndex < 4)
instead of <= since currently the second block would never be reached since for currentSceenIndex == 4 it already executes the if block
var currentSceenIndex = SceneManager.GetActiveScene().buildIndex;
if (currentSceenIndex < 4)
{
SceneManager.LoadScene(0);
}
else if (currentSceenIndex == 4)
{
SceneManager.LoadScene(4);
}
public const int MinimumRespawnSceneIndex = 4;
public void Respawn()
{
int currentSceenIndex = SceneManager.GetActiveScene().buildIndex;
int spawnAtSceneIndex = currentSceenIndex < MinimumRespawnSceneIndex ? 0 : currentSceenIndex;
SceneManager.LoadScene(spawnAtSceneIndex);
}

For loop not executing all code - no errors

https://simmer.io/#JammerLamma/~c09dd45e-0528-01ce-e641-e4a56fb9cfed
https://github.com/JammerLamma/Number-Muncher-Clone
I'm creating a number munchers clone, and the integer variables are not getting properly assigned. It works for a few games, but after a few times of winning, and/or clicking quit, and choosing another game it appears the for loop goes through properly. The game says there are 5 maxCorrect, and correctOnBoard is also set to 5, so I assume the loop goes through 5 times, however, only 4 tiles get set as correct, then sometimes 2, or 4, but never 5 again. It always works as intended the first game.
If I comment out //AssignRest(); the problem still persists.
public void GenerateEven()
{
//GameObject smasher = Instantiate(smasherPF, transform.position, transform.rotation);
remainingNumbers = totalTiles - maxCorrect;
GetLists();
GetTiles();
AssignEven();
RemoveDuplicates(evenNumbers);
AssignRest();
}
private void AssignEven()
{
int maxCorrect = 5;
for (int i = 1; i <= maxCorrect; i++)
{
randomChild = children[UnityEngine.Random.Range(0, children.Count)];
int maxLength = evenNumbers.Count;
int tempTileNum = evenNumbers[UnityEngine.Random.Range(0, maxLength)];
randomChild.GetComponent<Tile>()._TileNumber = tempTileNum;
randomChild.GetComponent<Tile>()._IsCorrect = true;
correctOnBoard++;
randomChild.GetComponent<SpriteRenderer>().sprite = numberSprite[tempTileNum - 1];
Debug.Log(tempTileNum);
}
}
Some things are serialized for debugging purposes. All of the lists get generated correctly.
Changed the code to
private void AssignEven()
{
for (int i = 1; i <= maxCorrect;)
{
randomChild = children[UnityEngine.Random.Range(0, children.Count)];
if(randomChild.GetComponent<Tile>()._IsCorrect == false)
{
int maxLength = evenNumbers.Count;
int tempTileNum = evenNumbers[UnityEngine.Random.Range(0, maxLength)];
randomChild.GetComponent<Tile>()._TileNumber = tempTileNum;
randomChild.GetComponent<Tile>()._IsCorrect = true;
correctOnBoard++;
randomChild.GetComponent<SpriteRenderer>().sprite = numberSprite[tempTileNum - 1];
Debug.Log(tempTileNum);
i++;
}
}
}
Thanks to John Wu!

Why when making a loop it's all the time reset to 0 on next iterations?

I have a method with some loops inside:
private void RefreshListBox()
{
int i = 0, j = 0, index, count;
Boolean bl = false;
index = listBox1.SelectedIndex;
count = windowsHandles.Count;
for (i = 0; i < count; i++)
{
if (!Constants.IsWindow(windowsHandles[j]))
{
windowsHandles.RemoveAt(j);
windowsText.RemoveAt(j);
windowsBitmaps.RemoveAt(j);
rectanglesList.RemoveAt(j);
isCroppedList.RemoveAt(j);
canDrawNormallyList.RemoveAt(j);
if (j < index)
{
index--;
}
else if (j == index)
{
}
else
{
}
}
else { j++; }
}
if (index == windowsHandles.Count)
{
index--;
}
for (int x = 0; x < windows.Count; x++)
{
for (j = 0; j < windowsHandles.Count; j++)
{
if (windowsHandles[j] == windows[x].Handle) { bl = true; break; }
}
if (bl == false && Constants.IsIconic(windows[x].Handle))
{
windowsHandles.Add(windows[x].Handle);
windowsText.Add(windows[x].Title);
windowsBitmaps.Add(null);
rectanglesList.Add(new Rectangle(0, 0, 0, 0));
isCroppedList.Add(false);
canDrawNormallyList.Add(false);
}
bl = false;
}
if (windowsHandles.Count > 0 && index == -1)
{
index = 0;
}
if (listBox1.Items.Count > 0) { listBox1.Items.Clear(); }
for (i = 0; i < windowsHandles.Count; i++)
{
listBox1.Items.Add(windowsText[i]);
}
if (index != -1)
{
listBox1.SelectedIndex = index;
}
textBoxIndex.Text = windowsHandles.Count.ToString();
drawPicBox(index);
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var item = listBox1.IndexFromPoint(e.Location);
if (item >= 0)
{
listBox1.SelectedIndex = item;
drawPicBox(listBox1.SelectedIndex);
}
}
}
The problem start when it's getting to the loop at this line:
for (int x = 0; x < windows.Count; x++)
The Count of windows List is 21 in this case.
Then it's entering first time but if i put a break point on this line and click continue all the time i see that x is 0.
When i put a break point on this line:
windowsHandles.Add(windows[x].Handle);
It stop there each time i click on continue but then i see that the variable x it's value is 20 all the time. And the List windowsHandles contain only 1 item.
Then i put a break point on the line:
listBox1.Items.Add(windowsText[i]);
And when i make continue it stop on the line but even if it does the line there are no items on the listBox1.
If i don't use any break points and just make continue to let it run it's never show/get to the form it's like stuck somewhere in this method can't figure out where and why.
In the constructor i'm calling two methods.
First GetWindows then RefreshList
GetWindows();
RefreshListBox();
In GetWindows:
private List<Window> windows = new List<Window>();
private void GetWindows()
{
windows = new List<Window>();
Constants.EnumWindows(Callback, 0);
}
private bool Callback(IntPtr hwnd, int lParam)
{
try
{
if (this.Handle != hwnd && (Constants.GetWindowLongA(hwnd, Constants.GWL_STYLE) & Constants.TARGETWINDOW) == Constants.TARGETWINDOW)
{
StringBuilder sb = new StringBuilder(100);
Constants.GetWindowText(hwnd, sb, sb.Capacity);
Window t = new Window();
t.Handle = hwnd;
t.Title = sb.ToString();
windows.Add(t);
}
}
catch(Exception err)
{
StreamWriter w = new StreamWriter(#"e:\errors.txt");
w.Write(err.ToString());
w.Close();
}
return true;
}
In the end of the GetWindows operation i see that windows contain 21 items.
The problem seems to be somewhere in the RefreshList method but i can't figure out where is the problem.
The goal of all this in the end is to add all the items in windowsText to the listBox1.
I just noticed something else:
windowsHandles.Add(windows[x].Handle);
windowsText.Add(windows[x].Title);
windowsBitmaps.Add(null); // <------
rectanglesList.Add(new Rectangle(0, 0, 0, 0));
isCroppedList.Add(false);
canDrawNormallyList.Add(false);
Is this a correct guess - The reason you're adding a null to windowsBitmaps is so that all six of these collections stay in sync. The items across each collection are related somehow if they have the same index.
It would be much easier if you created one class with properties for windowsHandle, windowsText, windowsBitmaps, etc, and then had a collection of that type. That way instead of managing six collections and trying to keep them in sync you only have one.
This isn't a direct answer, but I think it's a necessary step if you're going to get to the answer: break this up into smaller methods.
You could start with the loops. You could put each of those loops in a separate method and name the method very clearly so that it indicates what it's doing and what it's doing it to. (It might even be worthwhile to put some of the functions in separate classes.)
One of the reasons is that no one - not you or the programmer who works on this later - can expect to be able to hold the complexity of one long method in their head and follow through 'what if this happens, what if that happens.'
Same thing for variable names. It's okay if variable names and method names are long if they help make it clear what they are for. I find myself seeing x and having to scroll back up to see what x is, and then I lose track of where I was.
I know that's not a direct answer. But if you do that then the answer will likely be easier to see. If you break it up into smaller functions (or even write separate classes) then you can also write unit tests. That way instead of running the whole thing from top to bottom you can just test one part at a time.
More directly related
Somewhat more directly related to the code: If you do need to iterate through a collection and possibly remove items as you go, it's better to start from the Count and work backwards. That way your index stays in bounds.
An even easier way is to use Linq to query the elements and create a new collection. For example
Thing[] arrayOfSomething = GetAnArrayOfSomething();
var arrayWithElementsRemoved = arrayOfSomething.Where(
item => !item.DeleteThisOne).ToArray();
The second statement takes an array of Thing and returns a new array containing only the ones where DeleteThisOne is false. It's all in one statement, no looping or bounds to worry about.

Removing list items in C# / XNA

I am a beginner with XNA Game Studios and want to learn some basics in game programming.
I am currently creating a small space shooter, something like a variation of Space Invaders.
To make my rockets look better I've created some smoke trails to follow them, but would like to remove them after some time (400 milliseconds) so the screen is not blocked by that smoke.
To achieve this I have created the following code, which seems pretty logical to me.
for(int i=0; i < rocketPosition.Count; i++)
{
rocketPosition[i] = new Vector2(rocketPosition[i].X, rocketPosition[i].Y - rocketSpeed);
Vector2 smokePosition = rocketPosition[i];
smokePosition.X += Rocket.Width / 2 + smokeTexture.Width / 2 + randomizer.Next(10) - 5;
smokePosition.Y += Rocket.Height + randomizer.Next(10) - 5;
smokeList.Add(new Particle(smokePosition, gameTime.TotalGameTime.Milliseconds));
if (rocketPosition[i].Y < 0 - Rocket.Height)
{
rocketPosition.RemoveAt(i);
}
}
for(int i = 0; i < smokeList.Count; i++)
{
if (smokeList[i].Time < gameTime.TotalGameTime.Milliseconds - smokeDuration)
{
smokeList.RemoveAt(i);
}
}
Particle is a class I created in order to have both the creation-time of the list item (which represents the smoke particle), as well as its position Vector2.
However instead of deleting the smoke trail from bottom to top it stops in between and looks like the following picture:
I hope someone can help me with my code.
Removing an item from the iterating list decrement the count therefore:
for(int i=rocketPosition.Count; i > 0 ; i--)
{
rocketPosition[i] = new Vector2(rocketPosition[i].X, rocketPosition[i].Y - rocketSpeed);
Vector2 smokePosition = rocketPosition[i];
smokePosition.X += Rocket.Width / 2 + smokeTexture.Width / 2 + randomizer.Next(10) - 5;
smokePosition.Y += Rocket.Height + randomizer.Next(10) - 5;
smokeList.Add(new Particle(smokePosition, gameTime.TotalGameTime.Milliseconds));
if (rocketPosition[i].Y < 0 - Rocket.Height)
{
rocketPosition.RemoveAt(i);
}
}
for(int i = smokeList.Count; i > 0 ; i--)
{
if (smokeList[i].Time < gameTime.TotalGameTime.Milliseconds - smokeDuration)
{
smokeList.RemoveAt(i);
}
}

Categories

Resources