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);
}
Related
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;
}
I have this counter programm based on object oriented programming in C# and
the counter has an Increment Method which counts up so like it goes from 0..1...2.. to 30.
The for loop was working perfectly fine but then I decided to add a class with two Methods that either count up in odd or even steps which also works fine. The only problem is that after changing the main class now it doesn't work in a loop anymore until its on 30, so I have to enter every step individually.
This is my main code (I'm pretty sure the problem is due to the Console.ReadLine and input in general but I don't know what exactly is the issue)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Counter
{
class Program
{
static void Main(string[] args)
{
char confirm;
int input;
do
{
//int inNum;
Console.Clear();
ModusCounter b = new ModusCounter(0, 30);
for (; ; )
{
b.Display(19, 7);
Console.Write("do you want (1)odd // (2) even // (0)standard ? ");
input = Convert.ToInt32(Console.ReadLine());
if (input == 1)
{
b.OddCount();
}
else if (input == 2)
{
b.EvenCount();
}
else
b.Increment();
System.Threading.Thread.Sleep(300);
if (Console.KeyAvailable) break;
}
//b.Increment();
b.Display(19, 7);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("do you want to restart? (J // N) ");
confirm = Convert.ToChar(Console.ReadLine());
}
while (confirm == 'J');
Console.ReadLine();
}
}
}
ModusCounter:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Counter
{
public class ModusCounter:CCounter
{
private int wholenum;
public int Wholenum
{
get => wholenum;
set
{
wholenum = value;
}
}
public ModusCounter(int start, int limit) : base(start, limit)
{ }
public void EvenCount() //2
{
Wholenum = 2;
Level += Wholenum;
if (Level % 2 == 0)
{
Level += Wholenum - 2;
}
else
{
Level += Wholenum -1;
}
if (Level > Limit)
Level = Start;
}
public void OddCount() //1
{
Wholenum = 1;
Level += Wholenum;
if (Level % 2 == 0)
{
Level += Wholenum;
}
else
{
Level += Wholenum + 1;
}
if (Level > Limit)
Level = Start;
}
}
}
base class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Counter
{
public class CCounter
{
private int start;
private int limit;
private int level;
public int Start
{
get => start;
protected set
{
start = value;
}
}
public int Limit
{
get => limit;
protected set
{
limit = value;
}
}
public int Level
{
get => level;
protected set
{
if (value < Start)
level = Start;
else if (value > Limit)
Level = Limit;
else
level = value;
}
}
public CCounter(int start_, int limit_)
{
Start = start_;
Limit = limit_;
Level = Start;
}
public void Increment()
{
int level = Level + 1;
if (level > Limit9
Level = Start;
else
Level = level;
}
public void Display(int x_, int y_)
{
Console.SetCursorPosition(x_, y_);
Console.Write(Level.ToString("00"));
}
}
}
First, welcome to S/O. Hope you get good info out here during your obvious learning curve into development. A couple things could get simplified, but that will come with learning, so I wont pounce, but you will see as your skills improve over time.
First, your for(;;) loop. That is in-itself causing an infinite loop. The console read line to get input is always waiting for the next option from your prompt asking for odd, even or standard, so it keeps cycling through.
I dont think your Console.KeyAvailable is ever really getting triggered to break out of the for loop to get you to the next prompt of allowing the user to retry J/N option. You have the console.ReadLine which reads the entire buffer until you hit the enter key. By that time, you are incrementing your cycle, displaying the results and giving a 300 millisecond delay from your Thread.Sleep(300) call, of which you are probably not clicking a key in that short span to break the loop. Now, if you changed the Thread.Sleep(2000) you would be giving the user 2 seconds (1 second = 1000 milliseconds) AFTER the display to press any key to break the loop.
Next item/question I have for you. Your incrementing you appear to be ok with that functionality, but what / why do you want to break. When it gets to the limit? If so, then test for that after the increment process has completed such as (before the Thread.Sleep call)
if (b.Level >= b.Limit)
break;
Getting to your CCounter class and looking at its Increment method. You have a check that if the local "level" variable is greater than the limit to set the level = START value. Was that intended, or not. Also, by using a new int value by the same name as a property on your class (int level vs property level) is not a good practice and can add confusion.
public void Increment()
{
int level = Level + 1;
if (level > Limit)
Level = Start;
else
Level = level;
}
It appears you are trying to use a local temporary variable but is not necessary. It could just as easily be done with slight alteration as I have below.
public void Increment()
{
if (Level +1 > Limit)
Level = Start;
else
Level = Level +1;
}
Because I am not ASSIGNING a value to the "Level" public property, it in essence is doing the +1 before its COMPARISON to the LIMIT property. Only in the ELSE condition do I assign.
Also, a shortcut on adding to a variable or subtracting could be seen as
Level++
or
Level--
Hopefully this helps add SOME clarity to what you are looking to get resolution to and can get you further in your development.
I'm new to threading, and the examples I see online construct threads by passing a void function. However, I want to speed up computation time by returning integer values in multiple threads. Here's the relevant part of my code:
public int CalculateLineWins5(List<List<Symbol>> _screen)
{
int wins = 0;
foreach (List<int> line in lines)
{
for (int i = 0; i < reelsNumber; i++)
{
lineSymbols[i] = _screen[i][line[i]];
}
//evaluate the win per line
wins += CalculateWinsInLine5(lineSymbols);
}
return wins;
}
public int CalculateWinsInLine5(List<Symbol> _symbolsOnLine)
{
// this function assumes there could be wilds on reel 1 (and there are only 5 reels)
int wildMultiplier = 1;
int win = 0;
Symbol symbol = _symbolsOnLine[0];
if (symbol.IsPayTableSymbol)
{
int oak = 0;
int oakWild = 0;
if (symbol.IsWild)
{
symbol = _symbolsOnLine[1];
if (symbol.IsWild)
{
oakWild++;
symbol = _symbolsOnLine[2];
if (symbol.IsWild)
{
oakWild++;
symbol = _symbolsOnLine[3];
if (symbol.IsWild)
{
oakWild++;
symbol = _symbolsOnLine[4];
if (symbol.IsWild)
{
oakWild++;
}
}
}
}
}
if (symbol.IsPayTableSymbol)
{
if (_symbolsOnLine[1].Index == symbol.Index || _symbolsOnLine[1].IsWild)
{
oak++;
if (_symbolsOnLine[1].IsWild) wildMultiplier *= _symbolsOnLine[1].Multiplier;
if (_symbolsOnLine[2].Index == symbol.Index || _symbolsOnLine[2].IsWild)
{
oak++;
if (_symbolsOnLine[2].IsWild) wildMultiplier *= _symbolsOnLine[2].Multiplier;
if (_symbolsOnLine[3].Index == symbol.Index || _symbolsOnLine[3].IsWild)
{
oak++;
if (_symbolsOnLine[3].IsWild) wildMultiplier *= _symbolsOnLine[3].Multiplier;
if (_symbolsOnLine[4].Index == symbol.Index || _symbolsOnLine[4].IsWild)
{
oak++;
if (_symbolsOnLine[4].IsWild) wildMultiplier *= _symbolsOnLine[4].Multiplier;
}
}
}
}
win += Mathf.Max(payTable[symbol.Index][oak], payTable[0][oakWild]) * wildMultiplier;
}
else
{
win += payTable[0][oakWild] * wildMultiplier;
}
}
return win;
}
Essentially, I want to run the computations within the foreach loop above in parallel. Typically that's going to be 40 to 50 iterations of the CalculateWinsInLine5 method, so I think I'd have to create 40 to 50 threads that are computed in parallel and each return an integer value. I just don't know how. Any help or feedback on how to approach this is welcome.
Edit: My project runs random simulations of slot machine payouts. In each simulation the program goes through a large number of iterations where it generates a random set of reel stops which generate a matrix of symbols (the screen). In each iteration, the screen pay is evaluated using the CalculateLineWins5 method.
This is actually a Unity project, and interestingly enough, I already tried using the Burst compiler which makes the simulations 1.5x slower, just like Parallel.ForEach.
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!
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.