Song picking system - c#

I am trying to do a song picking UI in my project. Everytime u click on a button in the game it sends int to this function. Is there a better way to structure this code so i don't have to write IF statements for every single song?
public void SongPick(int song)
{
if (song == 0)
{
audioSource.clip = musicArray[0];
}
if (song == 1)
{
audioSource.clip = musicArray[1];
}
if (song == 2)
{
audioSource.clip = musicArray[2];
}
audioSource.Play();
string currentMusic = musicArray[song].name;
songName.text = "PLAYING: " + currentMusic;
}

Assuming song always references the correct index in musicArray you definitely don't need an ever-growing if statement.
public void SongPick(int song) {
if (song < musicArray.length) {
audioSource.clip = musicArray[song];
}
audioSource.Play();
string currentMusic = musicArray[song].name;
songName.text = "PLAYING: " + currentMusic;
}

Related

how to make a grid with the local space Unity?

I am gridding around an object but I need the grid to align in the local space of the pivot object
the code that i have
private void createColum()
{
for (int i =0; i<gridGame.Count;i++)
{
if(gridGame[i] == gridGame[0])
{
gridGame[i].localPosition = gridGame[0].localPosition;
}
if(gridGame[i]!= gridGame[0])
{
gridGame[i].localPosition = new Vector3(gridGame[i-1].localPosition.x + distX,gridGame[0].localPosition.y, gridGame[0].localPosition.z);
}
if(i +1 > limiteFila)
{
if(i%limiteFila==0)
{
gridGame[i].localPosition = new Vector3(gridGame[0].position.x, gridGame[0].position.y , gridGame[i-Mathf.RoundToInt(limiteFila)].position.z + distY);
}else
{
gridGame[i].position = new Vector3(gridGame[i-1].position.x + distX, gridGame[0].position.y , gridGame[i-1].position.z);
}
}
gridGame[i].rotation = gridGame[0].rotation;
}
}
with this the grid of objects is formed but only in taking the world space
picture of how you are at this moment
I'm not sure if this will help, but you can turn the grid into a child object and leave the worldPositionStays as false, to do so use the SetParent(Transform parent, bool worldPositionStays). For example as a reference for your script.
private void createColum()
{
for (int i =0; i<gridGame.Count;i++)
{
if(gridGame[i] == gridGame[0])
{
gridGame[i].localPosition = gridGame[0].localPosition;
gridGame[i].transform.SetParent(this.transform, false);
}
if(gridGame[i]!= gridGame[0])
{
gridGame[i].localPosition = new Vector3(gridGame[i-1].localPosition.x + distX,gridGame[0].localPosition.y, gridGame[0].localPosition.z);
}
if(i +1 > limiteFila)
{
if(i%limiteFila==0)
{
gridGame[i].localPosition = new Vector3(gridGame[0].position.x, gridGame[0].position.y , gridGame[i-Mathf.RoundToInt(limiteFila)].position.z + distY);
}else
{
gridGame[i].position = new Vector3(gridGame[i-1].position.x + distX, gridGame[0].position.y , gridGame[i-1].position.z);
}
}
gridGame[i].rotation = gridGame[0].rotation;
}
}

Image index not always changes

So, I'm trying to code simple memory game in Windows Forms but I've met a simple problem that somehow I can't pass.
This is a single button code(they all look very similar):
Match CheckForMatches = new Match();
private void Pathfinder_Click(object sender, EventArgs e)
{
CheckForMatches.AddButton(Pathfinder);
CheckForMatches.Matched();
}
(where CheckForMatches object is shared between all buttons in given form)
And here are called methods codes:
public void AddButton(Button newButton)
{
if (firstButtonPressed == null)
{
firstButtonPressed = newButton;
firstButtonPressed.ImageIndex = 0; //uncovering card
}
else
{
secondButtonPressed = newButton;
secondButtonPressed.ImageIndex = 0;
Thread.Sleep(1000);
}
}
public bool Matched()
{
if (firstButtonPressed != null && secondButtonPressed != null )
{
if (firstButtonPressed.Name != secondButtonPressed.Name)
{
if (firstButtonPressed.Text == secondButtonPressed.Text)
{
DisposeButtons();
return true;
}
else
{
NullButtons();
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
Now this method call one of two others, depending if last 2 clicked buttons are a pair or not(basing on their name and text):
This in case of succes disposes buttons and null Match class variables:
public void DisposeButtons()
{
firstButtonPressed.Dispose();
secondButtonPressed.Dispose();
firstButtonPressed = null;
secondButtonPressed = null;
}
This is case of failure covers cards and also nulls Match class variables:
public void NullButtons()
{
firstButtonPressed.ImageIndex = 1; //covering cards
secondButtonPressed.ImageIndex = 1;
firstButtonPressed = null;
secondButtonPressed = null;
}
The point is, no matter where I place Thread.Sleep(1000), user can never see second card he choses. He always see the first one and then, when he choses second one, either both cards are disposed(app is freezing due to that delay) or the first one becomes covered, without uncovering the second one.
EDIT:
I added output to debugger window, so now method AddButton looks like this:
public void AddButton(Button newButton)
{
if (firstButtonPressed == null)
{
firstButtonPressed = newButton;
Debug.WriteLine("Before index chaning: " + firstButtonPressed.ImageIndex);
firstButtonPressed.ImageIndex = 0; //uncovering card
Debug.WriteLine("After index chaning: " + firstButtonPressed.ImageIndex);
}
else
{
secondButtonPressed = newButton;
Debug.WriteLine("Before index chaning: " + secondButtonPressed.ImageIndex);
secondButtonPressed.ImageIndex = 0;
Debug.WriteLine("After index chaning: " + secondButtonPressed.ImageIndex);
Thread.Sleep(1000);
}
}
I can see there, that ImageIndex buttons' property actually changes between 1 and 0. However, in practice, it's only visible when first if block of this method is called. I would be grateful for answering why and how to change that.
Okay, I found out maybe not best solution, but it works. I simply forced button to refresh.
Correct form of AddButton method is:
public void AddButton(Button newButton)
{
if (firstButtonPressed == null)
{
firstButtonPressed = newButton;
Debug.WriteLine("Before index changing: " + firstButtonPressed.ImageIndex);
firstButtonPressed.ImageIndex = 0; //uncovering card
Debug.WriteLine("After index changing: " + firstButtonPressed.ImageIndex);
}
else
{
secondButtonPressed = newButton;
Debug.WriteLine("Before index changing: " + secondButtonPressed.ImageIndex);
secondButtonPressed.ImageIndex = 0;
secondButtonPressed.Refresh();
Debug.WriteLine("After index changing: " + secondButtonPressed.ImageIndex);
Thread.Sleep(500);
}
}
I hope it will be useful for someone one day.

From List to Graphical Interface

I'm creating a shop inside my game to buy virtual goods.
Main Shop Page
Each group has its own items. I've created a view where only one item is visible each time, with buttons to go to the previous and next item.
Specific group selection Menu - Teams
The question is that I don't know how to show the list where I have the items, in that last window and make that touching the buttons previous/next the list shows the different items.
Each item inside the list is called inventory[x] (x = the number in the loop) and has the properties itemName and itemDescription.
How can I make the code communicate with the graphical user interface?
I've created 6 inventory lists (each one for one type of unlockable virtual good) and I use GameSparks API for online features such a player profile.
The lists are declared at the beginning of the script:
public static List<Inventario> inventarioEquipos = new List<Inventario>(); //Inventory for Teams
public static List<Inventario> inventarioPelotas = new List<Inventario>(); //Inventory for Balls
public static List<Inventario> inventarioModos = new List<Inventario>(); //Inventory for Modes
public static List<Inventario> inventarioVitores = new List<Inventario>(); //Inventory for Cheers
public static List<Inventario> inventarioCampos = new List<Inventario>(); //Inventory for Fields
public static List<Inventario> inventarioFondos = new List<Inventario>(); //Inventory for Backgrounds
In the Awake method I call:
Info_Botones ("Equipos"); //I call this function for each group, to load its items and show how many items of a total of X the player owns. If you look at the first picture, will see below TEAMS: 1/2. That's what this function is for (besides to load all the unlockables in separated lists).
Info_Botones ("Pelotas");
Info_Botones ("Modos");
Info_Botones ("Vitores");
Info_Botones ("Campos");
Info_Botones ("Fondos");
The code of the main function is as follows:
private void Info_Botones(string tipoDeInventario) { //"tipoDeInventario" means InventoryType and I use it to pass to the function which type of inventory I want to load (Teams, Balls, Modes, Cheers, Fields or Backgrounds)
int numero = 0;
new LogEventRequest()
.SetEventKey("INVENTARIO")
.SetEventAttribute("TAG_TYPE", tipoDeInventario)
.Send((response) =>
{
if (!response.HasErrors)
{
List<object> entryList = response.ScriptData.GetObjectList("result") as List<object>;
for (int i = 0; i < entryList.Count; i++)
{
Dictionary<string, object> entry = entryList[i] as Dictionary<string, object>;
int itemId = i;
string itemName = (entry["name"]).ToString();
string itemDescription = (entry["description"]).ToString();
int itemPrice = int.Parse((entry["currency1Cost"].ToString()));
string itemInteractable = (entry["interactable"]).ToString();
Inventario inv = new Inventario(itemId, itemName, itemDescription, itemPrice, itemInteractable);
if(tipoDeInventario == "Equipos") {
inventarioEquipos.Add(inv);
if (inventarioEquipos[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Pelotas") {
inventarioPelotas.Add(inv);
if (inventarioPelotas[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Modos") {
inventarioModos.Add(inv);
if (inventarioModos[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Vitores") {
inventarioVitores.Add(inv);
if (inventarioVitores[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Campos") {
inventarioCampos.Add(inv);
if (inventarioCampos[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Fondos") {
inventarioFondos.Add(inv);
if (inventarioFondos[i].itemInteractable == "False") {
numero++;
}
} else {
}
}
if(tipoDeInventario == "Equipos") {
txtBtnCantidadEquipos.text = numero.ToString() + "/" + inventarioEquipos.Count;
} else if(tipoDeInventario == "Pelotas") {
txtBtnCantidadPelotas.text = numero.ToString() + "/" + inventarioPelotas.Count;
} else if(tipoDeInventario == "Modos") {
txtBtnCantidadModos.text = numero.ToString() + "/" + inventarioModos.Count;
} else if(tipoDeInventario == "Vitores") {
txtBtnCantidadVitores.text = numero.ToString() + "/" + inventarioVitores.Count;
} else if(tipoDeInventario == "Campos") {
txtBtnCantidadCampos.text = numero.ToString() + "/" + inventarioCampos.Count;
} else if(tipoDeInventario == "Fondos") {
txtBtnCantidadFondos.text = numero.ToString() + "/" + inventarioFondos.Count;
} else {
}
}
else
{
Debug.Log("ERROR AL OBTENER VG DEL JUGADOR: " + response.Errors.JSON);
}
});
}
I've achieved it using IF condictions. If anyone needs the code, ask for it and I will share it (I'm not at home right now).
Thanks!

Unity C# coroutine not working

I am trying to make a Simon game. Obviously, when one color is displayed, it should wait a second or so. I created a coruotine for when the game is showing you what to do. Inside the coroutine, it is supposed to pause first, which when I run the game, it does. Then it goes through and chooses a color and stuff. Then it should loop back up(I made a loop) and pause again, and do everything again. The problem is, the pause only works the first time. Then it displays the other colors for like half a second and ends. I don't understand why once it loops it seems to do everything except for the pause. Here is my code:
void Update () {
if (show == true) {
StartCoroutine(Show());
}
}
IEnumerator Show() {
do {
yield return new WaitForSeconds(2f);
round ++;
if (round == 1) {
on = Random.Range(1,5);
}
if (round == 2) {
on = Random.Range(1,5);
}
if (round == 3) {
on = Random.Range(1,5);
}
if (round == 4) {
on = Random.Range(1,5);
}
// Turn on/off lights
if (on == 1) {
green.GetComponent<Renderer>().material = greenMat;
}
if (on != 1) {
green.GetComponent<Renderer>().material = greenOff;
}
if (on == 2) {
red.GetComponent<Renderer>().material = redMat;
}
if (on != 2) {
red.GetComponent<Renderer>().material = redOff;
}
if (on == 3) {
yellow.GetComponent<Renderer>().material = yellowMat;
}
if (on != 3) {
yellow.GetComponent<Renderer>().material = yellowOff;
}
if (on == 4) {
blue.GetComponent<Renderer>().material = blueMat;
}
if (on != 4) {
blue.GetComponent<Renderer>().material = blueOff;
}
}while(show == true);
}
I wrote a coroutine which may help you. Put it on start.
IEnumerator Show()
{
while (true) // or show
{
yield return new WaitForSeconds(2f);
round ++;
if (round >= 1 && round <= 4)
on = Random.Range(1,5);
green.GetComponent<Renderer>().material = on == 1 ? greenMat : greenOff;
//Same for the other...
}
}

Debugging a windows form application

Im making a chat program that saves the messages in files like pub0.zzc, all computers that are using it will be connected to the hard drive that these files are in, so its fine. The method data.Chat.Read(MessageTypes type, string Channel) infinite loops through a try catch statement till it returns the messages. I used this before and works perfectly. But, my code was hard to manage so instead of just putting text boxes into the window and using the code each time, i created a user control (MessageViewer). It works fine, once again when I run it, BUT it freezes VS whenever I try to use the designer on the window housing the control. the probelm isnt the window because when i delete the control its fine. I think the possible errors are at RefreshMessages() and the Refresher_Tick(...)
Refresher.Stop() and .Start() is also not it, worked fine before
so here is the code:
private void Refresher_Tick(object sender, EventArgs e)
{
Refresher.Stop();
int RefreshRate = 4;
bool Live = true;
if (RefreshRateChoice == "Manual")
{
Live = false;
RefreshRate = 1;
}
else if (RefreshRateChoice == "4 ( Default )")
{
Live = true;
RefreshRate = 4;
}
else
{
Live = true;
RefreshRate = Convert.ToInt32(RefreshRateChoice);
}
if (data.Chat.Read(MessageType, ChannelChoice) != ContentPresenter.Text && Live)
{
RefreshMessages();
}
Refresher.Interval = RefreshRate;
Refresher.Start();
}
public void RefreshMessages() {
if (data.Chat.Read(MessageType, ChannelChoice) != ContentPresenter.Text)
{
ContentPresenter.Text = data.Chat.Read(MessageType, ChannelChoice);
}
}
and if you need it:
public static string Read(MessageTypes Type, string Channel)
{
string Loc;
if (Type == MessageTypes.Public && (Channel == "1" || Channel == "2"))
{
return "Can not view this channel, only post to it.";
}
if (Type == MessageTypes.Public)
{
Loc = data.AssetsFolder + "\\pub" + Channel + ".zzc";
}
else if (Type == MessageTypes.Private)
{
Loc = data.AssetsFolder + "\\" + Channel + ".zzpc";
}
else if (Type == MessageTypes.Game)
{
Loc = data.AssetsFolder;
}
else
{
Loc = data.AssetsFolder;
}
while (true)
{
try
{
String MessageList = "";
StreamReader MessageReader = new StreamReader(Loc);
string EncMessages = MessageReader.ReadToEnd();
MessageReader.Dispose();
List<string> EncMsgList = EncMessages.Split(';').ToList();
for (int i = 1; i < EncMsgList.Count; i++)
{
MessageList += data.Encodings.Decrypt(EncMsgList[i], Palettes.Message) + "\n";
}
return MessageList;
}
catch
{
// Do nothing
}
}
}
You say that it "freezes."
In your Read method you have a while(true) loop with an embedded try...catch block, but the catch never returns you from that method. If you keep throwing the same exception, you'll continue to loop over and over which could be where you are freezing.
At least to prove that is the case, put a return in you catch or some diagnostic code to indicate if that is the case.

Categories