Search Unity

Change a UI Image, Source Image when other UI button is clicked?

Discussion in 'Scripting' started by Unlimited_Energy, Jul 23, 2015.

  1. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    Hey everyone, Im having a little difficulty trying to figure out how I can change the source image of a UI Image when I click another UI button. So basically I click a UI button and it changes the source image of a UI Image, not a button image but change an actual UI image I have.

    Thanks for any help guys
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    pass a reference into the function that is called by the button's OnClick event, you can then access the image within the function to do whatever you want.

    Code (csharp):
    1.  
    2. using UnityEngine.UI;
    3.  
    4. public void MyButtonClickFunction(Image myImageToUpdate)
    5. {
    6. myImageToUpdate.sprite = .... // change image here (new ui uses sprites)
    7. }
    8.  
    you can then drag the image into the slot in the OnClick event's inspector
     
    Unlimited_Energy likes this.
  3. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    Code (CSharp):
    1. using UnityEngine.UI;
    2. using System.Collections;
    3.  
    4. public class OnClick : MonoBehaviour {
    5.  
    6.  
    7.  
    8.     public void Image.enabled(Image Slot1)
    9.     {
    10.         Slot1.sprite = car // change image here (new ui uses sprites)
    11.     }
    12.  

    I'm very new to coding and I'm having difficulty piecing together the code.
     
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    how to configure a button
    https://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button?playlist=17111


    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4.  
    5. public class ImageChanger : MonoBehaviour
    6. {
    7.     public Sprite spriteToChangeTo;
    8.  
    9.     public void ChangeImage(Image myImageToUpdate)
    10.     {
    11.         myImageToUpdate.sprite = spriteToChangeTo;
    12.     }
    13. }
    14.  
    add that script to the button, drag the sprite you want to change to into the spriteToChangeTo slot in the inspector for this script in the inspector. Setup the OnClick event for the button to call this function from this script (from the learn vid above). Drag the UI Image gameObject you want to update into the parameter slot for the function.

    Want a different button to change it to some other sprite? copy the exact same script onto that button and configure it as needed in the inspector. No further coding required.
     
    Unlimited_Energy likes this.
  5. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    Thank you LeftyRighty! Works Great. I just wanted to let you know tho I attached the script to the UI Image and not the button. That is how the Video showed me also to do it, just in case someone else is reading this thread.

    I Ran into a Snag tho. I have 6 UI Images, I have called these Slots1-6 I I also have 24 Buttons. Now I need the Source Image to change on the UI Image when one of the 24 buttons is clicked BUT I need the button to assign an Image to non used UI image slots. I need it to check to see if there is an image assigned to the UI image first and then if it is skip UI image(slot1) and check UI Image2(Slot2) ect, untill all 6 slots are filled with images. The script you wrote works perfect but I cannot figure out how to check the UI Image Source Image first to see if it has a image assigned to it already.

    This will allow someone to pick any 6 of the 24 buttons they want and have them be assigned to UI Images 1-6 and the button will just skip to the next UI Image to Fill its Source Image if it does not have one. I do however need it to check in order if there is no source image, otherwise it will just assign the image to all the remaining UI Images at the same time.

    I would need something like:

    If Slot1 threw Slot6 SourceImage=none then assign image to Slot1
    Else If Slot2 threw Slot6 source image = None then assign Image to Slot2
    Else If Slot3 threw Slot6 SourceImage= None then assign Image to Slot 3
    Else If Slot4 threw Slot6 SourceImage=none then assign image to Slot4
    Else If Slot5 threw Slot6 source image = None then assign Image to Slot5
    Else If Slot6 tSourceImage= None then assign Image to Slot 6
    Else If Do Nothing.
    ---------------------------------------------------------------------------------------------- maybe like
    If Slot1 threw Slot6 SourceImage=none then:
    1. public void ChangeImage(Image myImageToUpdate)
    2. {
    3. myImageToUpdate.sprite = spriteToChangeTo;
    4. }
    5. }
    Else If Slot2 threw Slot6 source image = None Then:

    • public void ChangeImage(Image myImageToUpdate)
    • {
    • myImageToUpdate.sprite = spriteToChangeTo;
    • }
    • }
    Else If Slot3 threw Slot6 SourceImage= None then

    • public void ChangeImage(Image myImageToUpdate)
    • {
    • myImageToUpdate.sprite = spriteToChangeTo;
    • }
    • }
    If Slot4 threw Slot6 SourceImage=none then

    • public void ChangeImage(Image myImageToUpdate)
    • {
    • myImageToUpdate.sprite = spriteToChangeTo;
    • }
    • }
    Else If Slot5 threw Slot6 source image = None then:

    • public void ChangeImage(Image myImageToUpdate)
    • {
    • myImageToUpdate.sprite = spriteToChangeTo;
    • }
    • }
    Else If Slot6 SourceImage= None then

    • public void ChangeImage(Image myImageToUpdate)
    • {
    • myImageToUpdate.sprite = spriteToChangeTo;
    • }
    • }
    Else If Do not change Image
     
    Last edited: Jul 25, 2015
  6. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    any one have any ideas?
    I'm failing horribly at this
     
  7. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Can't even read it, let alone offer you any advice based on it. In 100 words or less, explain the problem again ^_^

    It sounds to me, though, like you're trying to do something similar to a consumable item "assignment system" in an RPG- click a little icon, that icon gets assigned to the first blank slot in a 6-slot "quick-use items" bar at the bottom. Is this correct?
     
    Unlimited_Energy likes this.
  8. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    yes, for simplicity sake if I can figure out just the image swap portion as stated above I will be able to figure out the rest. I just cannot wrap my head around how to swap the items picture out from the slots and assigning it in slot order. i do not want people to be able to choose which slot it goes in tho. i need whatever button is clicked on, on screen 1 to assign that image to one of 6 slots on screen 2 but need that checking order and slot assignment logic.
     
  9. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    I think you're struggling with this because it's not something that the GUI is really meant to handle on its own- it's supposed to be reactionary really, responding to things that are happening elsewhere. If you had some sort of an inventory system attached to a manager in the scene or your main character or w/e, then you would have the "slots" located there instead, as an array of objects ("objects" being some sort of class you'd made, like "skills" or "items" or w/e, that hold the images that get displayed to the GUI as well as all of the other data associated with them).

    The logic could then be that you'd press a button or do something to bring up a GUI display of all possibilities for those slots on the screen for the player- this would be drawn from some "total list of objects" or w/e that you have stored elsewhere. By clicking on one of the items (functioning as a button, most likely), it would trigger the OnClick event, which would be pointing at a function in your inventory (again, in a manager or on your main character). The inventory function would check that array it's holding, see which is the first empty slot, if any are empty, and dump the item represented by your selection in there.

    Now you can go several ways for the display of the slots themselves on the screen, but for simplicity sake you could put a script on each of the GameObjects in the UI that represent the "slots" and have them check every fifth of a second or so if the item in that slot has changed in the inventory script since it last checked, and if it has, to update the picture being displayed there. If you did this on a manager parent of all of the slots instead of the slots individually, you could check for all of them simultaneously with one script.

    This is only one way of doing things, but I hope it gives you some ideas!
     
    Unlimited_Energy likes this.
  10. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    what is the Equivalent of ll for a string? ll is only for bools but I need to separate the slot names in a argument like
    if (gameObject.tag == "Slot1" ll "Slot2" ll "Slot3" ll "Slot4" ll "Slot5" ll "Slot6") but I cannot do that since you cannot use ll with string names.
     
  11. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    The "==" operator creates a bool out of a comparison, so you CAN use it with strings, but you have to do it with "==" for each one individually, like so:
    Code (csharp):
    1. if (gameObject.tag == "Slot1" || gameObject.tag == "Slot2" || gameObject.tag == "Slot3" || gameObject.tag == "Slot4" || gameObject.tag == "Slot5" || gameObject.tag == "Slot6")
    Alternatively, you could put all of those strings into a list and use list.Contains(gameObject.tag) to make a bool instead, or a hundred other ways.
     
    Unlimited_Energy likes this.
  12. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    cool thanks for the info. Im so new at scripting....im reading a book right now on Unity c# programming.

    im trying to refer to the None name when theres no source image. in the inspector you can choose "None for the source image and it will fill the source image name in with none. how would I refer to this since None is causing an unexpected symbol error when used in my code....
    gameObject.tag == "Slot1" || gameObject.tag == "Slot2" || gameObject.tag == "Slot3" || gameObject.tag == "Slot4" || gameObject.tag == "Slot5" || gameObject.tag == "Slot6" & myImageToUpdate.sprite ++ "None")
     
    Last edited: Jul 30, 2015
  13. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    How do I "connect" these two so they are logical? I need to say if the game objects tag is equal to "Slot1" AND ITS image spirite is equal to Null, then I do my function.

    I cannot figure out how to write that in c#. Im basically missing the c# code for AND THE or AND ITS to connect the two.(it took forever for me to figure out how to ask this lol)

    (gameObject.tag == "Slot1" myImageToUpdate.sprite = null)

    Im getting the followign error:
    parsing error unexpected symbol "myImageToUpdate"'

    ps Lysander~ Thank you for the array section on my other thread but for my beginner coding brain this seems to be easier for me to understand at the moment.
     
    Last edited: Aug 7, 2015
  14. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    You use the logical AND operator, which is &&. In this case it would be:
    Code (csharp):
    1. if(gameObject.tag == "Slot1" && myImageToUpdate.sprite == null) { }
    That checks both sides of the && and only returns true if both sides are true.

    This eventually leads to something sort of like those "factoring" problems you used to get in algebra class. When you're doing complex comparisons, you break it down into pieces, like say the tag is "Slot1" and the sprite is null- in the following statement && means "both sides must be true" and || means "either side must be true", so:
    Code (csharp):
    1. if(gameObject.tag == "Slot1" && (myImageToUpdate.sprite == null || myImageSpriteToUpdate == someSprite)) { }
    will turn into
    Code (csharp):
    1. if(TRUE && (FALSE || TRUE)) { }
    which will turn into
    Code (csharp):
    1. if(TRUE && TRUE) { }
    which will turn into
    Code (csharp):
    1. if(TRUE) { }
    You can come up with some fairly complicated logic in a pretty small span of space if you use it properly. The following is an example of "if the sprite is null AND the gameObject has a tag that's equal to any of the first three slots":
    Code (csharp):
    1. if(myImageToUpdate.sprite == null && (gameObject.tag == "Slot1" || gameObject.tag == "Slot2" || gameObject.tag == "Slot3")) { }
    It's worth noting that the if statement will short-circuit itself at the first FALSE value that it hits, meaning it won't bother checking the rest (a real FALSE value, not FALSE is an ongoing comparison like the slots above). So for instance, in the above example, if myImageToUpdate.sprite isn't null, it won't bother checking the tags. This behaviour is how we can say:
    Code (csharp):
    1. if(someGameObject != null && someGameObject.GetComponent<someComponent>() != null) { }
    which checks if the someGameObject is not null first and THEN checks if it has a component only in the case that it's not null. Normally if we check for a component and the object is null, it'll throw an error, but this way works because if it's null it won't even get to the component check.

    Sorry, I know this is an info-dump and a lot to take in. Hope it helps though.
     
    Last edited: Aug 7, 2015
    Unlimited_Energy likes this.
  15. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    Thank you so much for the really good write up. makes alot more sense now. The data dump was good lol. Its allowing me to mess around with this code to try and get it to work. Probly the most useful info ive read on if statements and && yet. I have created three scripts for three different buttons with slightly different code using all the info you just gave me to figure out which script will do what I want it to do and see how the other scripts affect each others button on click functions.

    So far Button1 changes the image of all 6 slots on button click. then if I click the 2nd button it changes nothing, same with third. If stop the game and click play again and click button 2 first it only changes slot 1, clicking button 1 next, changes all of the rest of the slots besides slot one which I understand why it does this and does not change the others this part of the code makes sense, clicking button 3 does nothing. im trying tons of different code arrangements in my if statements to figure out why if I start the game and click button 1 it changes all slots but clicking button 2 changes nothing if button 1 is clicked first upon game launch. Been working at it for the past 8 hours. If i cannot figure it out in another couple hours ill post my code. Im soo close to getting this to work perfect, i can feel it lol.
     
    Last edited: Aug 8, 2015
  16. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    I finally got it working! I had my else if statements separated for HOURS. like
    else
    {
    if{}
    else
    {
    if{}
    This TOTALLY screwed up my logic. I tried a hundred different ways to write this code before I realized how it was layed out. This just highlighted the importance of clean looking code for me.
     
  17. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    I actually had to go into the settings for VS and force it to newline for all braces, conditional statements, etc (at least, when any part of the block is spread to a second line). I think there's only two states that code should be allowed to exist in- completely spread out and exposed, or in a single compact line. Anything in the middle is just messy.

     
  18. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    I cannot figure out why this code is not working. I click button one and it switches the image for slot one. I click button 2 and it does nothing. Im not sure why the code below will not change slot 2s image when button 2 is clicked.

    Code (CSharp):
    1.         if(gameObject.tag == "Slot1" && myImageToUpdate.sprite == null)
    2.         {
    3.             myImageToUpdate.sprite = spriteToChangeTo;
    4.         }
    5.         else if(gameObject.tag == "Slot2" && (gameObject.tag == "Slot1" && myImageToUpdate.sprite != null))
    6.             {
    7.             myImageToUpdate.sprite = spriteToChangeTo;
    8.             }
    im not getting any errors, but im not sure why nothing is happening. to my knowledge since slot 1 has a source image after button one is clicked then button 2 should change slot 2 to spriteToChangeTo(source image) of button 2

    I think im about to just create 26 "slots"(UI Images) and assign each button to its own UI image and have all UI images or "slots" turned off from the beginning and then after player clicks first 6 buttons it will jump to screen 2 and display the 6 "slots".....:confused:
     
    Last edited: Aug 12, 2015
  19. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    The "else if" statement is simultaneously requiring that the tag be "Slot1" and "Slot2". If you want to make it so that it can be "Slot2 OR (Slot1 and a sprite image)", then you need to replace the first && (AND) in the statement with || (OR).
     
    Last edited: Aug 12, 2015
  20. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    OO good info. Im trying to say if the game object is slot 2 then check if slot 1 is already filled with a source image, The script basically checks each slot to see if there is a source image. so for slot three I would say. for slot 3, if the if slot 1 and slot 2 source image = null then apply source image to slot 3 ect. its basically checking the other slots so it dose not apply a "sword" in all the slots at once.

    All my weapons have there own script which are all the same, each weapon script is attached to the UI image.. on button press for "sword" it targets slots 1-6 and dose a image change function on all slots and im trying to get the code to say if slot one is empty then fill in just slot one and do nothing to the other slots, if slot 2 is empty and slot one is full then fill slot 2 with image, if slot 3 is empty and slot 1 and 2 source image is not null then fill slot 3 ect.
     
  21. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Okay, since you're really adamant about putting the logic in the GUI section instead of the character manager or w/e, I'll give you this. What you need to do is make a manager GameObject in your canvas- for organizational reasons, you can make this the parent of your "slot" objects. On a script attached to this manager, you'll make a public array or list of GameObjects or Images or whatever (for your "slots") and a function that will tell it to add an image to the first one in the sequence that's empty, like so:
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections.Generic;
    4.  
    5. public class SlotManager : MonoBehaviour
    6. {
    7.    public List<Image> slots = new List<Image>();
    8.  
    9.    public void AddToFirstAvailable(Sprite newSprite)
    10.    {
    11.       foreach(Image slot in slots)
    12.       {
    13.          if(slot.sprite == null)
    14.          {
    15.             slot.sprite = newSprite;
    16.             return; //or break; to get out of the For loop, if you have more to do
    17.          }
    18.       }
    19.    }
    20. }
    You can even make that function return a bool to tell you if there was an empty slot, just replace "return;" with "return true;" and then add "return false;" to the last line of the function, outside of the For loop. It'll only get to that point if it iterates through all of the Image objects and none of them were null. Anyways, just drag the slots into that list from the inspector in the order that you wish them to be checked, so "left to right" I'm guessing, and then you can call that function on the manager from anywhere, provided you get a reference to the manager first.
     
    Unlimited_Energy likes this.
  22. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    Dude, it works PERFECT! I cannot thank you enough. This was a huge learning experience for me.


     
  23. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    In this part of the code "(Image slot in slots)" could you use any Identifier name instead of slot? im just trying to understand how that works.
     
  24. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Yeah, it's functionally identical to having a for loop like:
    Code (csharp):
    1. for(int i = 0; i < slots.Count; i++)
    2. {
    3.    Image slot = slots[i];
    4.    //do whatever
    5. }
    except it's faster to write and doesn't expose the iterator. If you need the iterator (i, in this case), you should use a "for" loop instead, obviously.
     
    Unlimited_Energy likes this.
  25. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    public List<Image> slots =new List<Image>();

    I see you used a Class "Image" in the the brackets. what kind of things can go in those brackets? Classes only?
    so basically were saying right there were creating a Image List or, a List of Type "Image"?
     
  26. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    List is generic, meaning you can make a list of anything- classes, structs, enums, delegates, w/e.

    In terms of Unity, specifically, you should keep in mind that "Components" are just normal classes that happen to derive from Monobehaviour, so you can store them in arrays or lists just fine. If you make an array or a list and specify a Monobehaviour-derived class type (Transform, Renderer, Image, Text, etc...), then you can drag a GameObject onto one of the slots for that array/list in the inspector and it'll automatically grab the component of that type on the GameObject (if one exists) and assign it to that slot. So, with a public list of Image components, and setting a "size" of more than 0 in the inspector, you can drag over an object with an Image component on it onto that slot, and it'll assign that component to it.

    That was the kind of "shortcut" I was intending with this list- instead of just assigning all of the GameObjects themselves to it and forcing you to use GetComponent<Image>() on all of them, which is a waste since you don't need the rest of the GameObject- just those components.
     
    Unlimited_Energy likes this.
  27. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    Im trying to do the same thing with a Buttons Component Audio Source and change the Audio clip file on each button when the Weapon Button is clicked. So basically it will assign the the Image to the slot threw the gameManager object. and then since Each Image"slot" game object has 6 child Button objects under it, it will do the exact same thing. Click sword button and the slot image changes to sword and the 6 child buttons of each Image Slots Audio Clip is changed to one of the 6 sound effect files for each weapon I have.

    There are Visible Buttons on the Image that gets changed that trigger sounds when clicked so you can hear different variations of the weapons sounds.

    I was going to make an AudioManager Object and attach a script to it and place all 6 Buttons of each "slot1-6" which are children of GameManager Object which has the SlotManager script attached to it to manage the slots.


    I need to say:
    if game object tag == "Slot 1" && Source Image == "sword"
    Button 1 Audio.Clip = SwordSound1
    Button 2 Audio.Clip = SwordSound2
    Button 3 Audio.Clip = SwordSound3
    Button 4 Audio.Clip = SwordSound4
    Button 5 Audio.Clip = SwordSound5
    Button 6 Audio.Clip = SwordSound6

    if game object tag == "Slot 2" && Source Image == "sword"
    Button 7 Audio.Clip = SwordSound1
    Button 8 Audio.Clip = SwordSound2
    Button 9 Audio.Clip = SwordSound3
    Button 10 Audio.Clip = SwordSound4
    Button 11 Audio.Clip = SwordSound5
    Button 12 Audio.Clip = SwordSound6

    if game object tag == "Slot 3" && Source Image == "sword"
    Button 13 Audio.Clip = SwordSound1
    Button 14 Audio.Clip = SwordSound2
    Button 15 Audio.Clip = SwordSound3
    Button 16 Audio.Clip = SwordSound4
    Button 17 Audio.Clip = SwordSound5
    Button 18 Audio.Clip = SwordSound6

    if game object tag == "Slot 4" && Source Image == "sword"
    Button 19 Audio.Clip = SwordSound1
    Button 20 Audio.Clip = SwordSound2
    Button 21 Audio.Clip = SwordSound3
    Button 22 Audio.Clip = SwordSound4
    Button 23 Audio.Clip = SwordSound5
    Button 24 Audio.Clip = SwordSound6

    ect ect for all 6 slots and I will need to do this for all weapons. I know its alot of code to write but if I can get directed in the right direction for one block of code.... Im not sure how to use File names for source images. can I say "Source Image == "sword"? or how do I refer to a file name that a source image is using? do i just put its name in quotes?


    I have so far (nested If statements seemed like it would work)
    Code (CSharp):
    1.     public void
    2.     {
    3.         if (gameObject.tag == "Slot1" && Image.sprite == "Sword")
    4.         {
    5.             if (gameObject.name =="Button 1")
    6.             {
    7.                 AudioClip = "Sword1";
    8.             }
    9.             if (gameObject.name =="Button 2")
    10.             {
    11.                 AudioClip = "Sword2";
    12.             }
    13.             if (gameObject.name =="Button 3")
    14.             {
    15.                 AudioClip = "Sword3";
    16.             }
    17.             if (gameObject.name =="Button 4")
    18.             {
    19.                 AudioClip = "Sword4";
    20.             }
    21.             if (gameObject.name =="Button 5")
    22.             {
    23.                 AudioClip = "Sword5";
    24.             }
    25.             if (gameObject.name =="Button 6")
    26.             {
    27.                 AudioClip = "sword6";
    28.             }
    29.         }
    30.  
    31.     }
    32. }
    Im getting this error:
    error CS0131: The left-hand side of an assignment must be a variable, a property or an indexer
     
    Last edited: Aug 18, 2015
  28. nnadiwisdom1

    nnadiwisdom1

    Joined:
    Sep 2, 2016
    Posts:
    5
    i am try to make a tic tac toe game and i need the buttons to alternate between two images pls how do i do that am kind of a beginner in unity....
     
  29. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Not really related to the original thread, but whatever. First, the logic for your game should all happen in some sort of a game manager, the UI (the Xs and Os) should just be visual indicators of stuff going on in the logic.

    For instance, let's say I have a game manager with an enum defined for "symbols", which are just "X" and "O", and it keeps track of the player moves by filling 3 arrays with these enums as the game goes on.
    [ ] [ ] [ ], [ ] [ ] [ ], [ ] [ ] [ ]

    Now, on the screen are 9 buttons, one for each tic-tac-toe slot where an X and O can be placed. Clicking one should activate the button's "On Click" action, which should run a function on that game manager like "PlayMove(int spot)" and pass in a parameter that indicates which button was just pressed (probably just an integer value for 0-8 or something). If the move was valid (the space not taken yet), then the manager puts the current move in that spot in one of the arrays:
    [X] [ ] [ ], [ ] [ ] [ ], [ ] [ ] [ ]
    ... then checks to see if any of the sets of values will cause a player to win this turn. Either way, it now needs a way to send a command to the "image" portion of the game, maybe on the same GameObject where the button is, and tell it to either put an X or an O image there, right? I assume this is what you're talking about.

    There are a couple of very simple ways to solve this, but let's go with the one with the least amount of coding involved. First, make two public Sprite variables on the game manager script (you can make it an array if you like, but separate variables is fine), then drag in the X and O sprites (textures you're using for those symbols) into those spots in the inspector. Next, make a public array of Image variables, and in the inspector, drag in each of the 9 GameObjects that stand for the 9 spots on the board (where the buttons are and the sprites need to be placed) into that array. Make sure to drag them in the same order as the 0-8 numbers from the button parameter, to make this simpler. Once you're done with that, just add a line to the end of the PlayMove function (where you placed the new move into the array earlier) and change the "sprite" member for the proper Image in the array to the sprite for X or O, as appropriate- the array position should be the same as that number the button sent as a parameter (0-8).

    Anyways, that should give you some ideas about one way to do this- you can also disable the button that the OnClick was sent from, or just filter it in the PlayMove function so that sending the same position more than once just skips everything.

    Here's a quick game manager script I wrote just to show what this would be like: untested.
    Code (CSharp):
    1. public class GameManager : MonoBehaviour
    2. {
    3.     public Sprite xSprite;
    4.     public Sprite oSprite;
    5.     public Image[] positionImages = new Image[9];
    6.  
    7.     private enum Symbols{X, O};
    8.     private Symbols currentPlayer = Symbols.X;
    9.     private Symbols[,] gameBoard = new Symbols[3,3];
    10.  
    11.     void Start ()
    12.     {
    13.         // do null checks on xSprite, oSprite, and array size & null checks on positionImages
    14.     }
    15.  
    16.     public void PlayMove(int movePosition)
    17.     {
    18.         // check to make sure the position is legal
    19.         if(movePosition >= 0 && movePosition <= 8)
    20.         {
    21.             // convert the integer into a row and column position for the move
    22.             int row = Mathf.FloorToInt(movePosition / 3);
    23.             int column = movePosition % 3;
    24.  
    25.             // check to see if the spot is already taken- do nothing if it is
    26.             if(gameBoard[row, column] != null)
    27.             {
    28.                 // assign the player's symbol to the right spot on the board
    29.                 gameBoard[row, column] = currentPlayer;
    30.  
    31.                 // this is where we assign the sprite image, as appropriate
    32.                 if(currentPlayer == Symbols.X)
    33.                     positionImages[movePosition].sprite = xSprite;
    34.                 else
    35.                     positionImages[movePosition].sprite = oSprite;
    36.  
    37.                 // check for winner, then change the current player and wait for another click
    38.                 CheckForWinner();
    39.                 ChangePlayer();
    40.             }
    41.         }
    42.     }
    43.  
    44.     private void ChangePlayer()
    45.     {
    46.         // simple swap to the next player
    47.         if(currentPlayer == Symbols.X)
    48.             currentPlayer = Symbols.O;
    49.         else
    50.             currentPlayer = Symbols.X;
    51.     }
    52.  
    53.     private void CheckForWinner()
    54.     {
    55.         // check for the various winning combinations here
    56.     }
    57. }
     
    nnadiwisdom1 likes this.
  30. nnadiwisdom1

    nnadiwisdom1

    Joined:
    Sep 2, 2016
    Posts:
    5
    thanks will try this out
     
  31. nnadiwisdom1

    nnadiwisdom1

    Joined:
    Sep 2, 2016
    Posts:
    5
    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    public class boardGame : MonoBehaviour {
    public Texture[] players;
    public int[] matrix;
    public int PlayerPlaying = 0;
    public Text msg;
    public int movecount;
    // Use this for initialization
    void Start () {
    for (int i = 0; i < matrix.Length ;i++){
    matrix = -1;
    }
    }
    public int GetPlayerPlaying (){
    return PlayerPlaying;
    }
    public void PlayerPlayed (int position){
    matrix [position] = PlayerPlaying;
    //cheack if someone won
    int temp = GameOver ();
    if (temp != -1) {
    msg.text ="Player "+ temp+" won!";
    }
    //next player
    PlayerPlaying++;
    if (PlayerPlaying > 1){
    PlayerPlaying = 0;
    }
    }
    public Texture getPlayerTexture(){
    return players [PlayerPlaying];
    }
    public int GameOver(){
    movecount++;

    if (movecount == 9) {
    msg.text = "Its a draw";
    }
    //horisontal
    if (matrix [0] == matrix [1] && matrix [1] == matrix [2] && matrix [0] != -1) {
    return matrix[0];
    }
    if (matrix [3] == matrix [4] && matrix [4] == matrix [5] && matrix [3] != -1) {
    return matrix[3];
    }
    if (matrix [6] == matrix [7] && matrix [7] == matrix [8] && matrix [6] != -1) {
    return matrix[6];
    }
    //vertical
    if (matrix [0] == matrix [3] && matrix [3] == matrix [6] && matrix [0] != -1) {
    return matrix[0];
    }
    if (matrix [1] == matrix [4] && matrix [4] == matrix [7] && matrix [1] != -1) {
    return matrix[1];
    }
    if (matrix [2] == matrix [5] && matrix [5] == matrix [8] && matrix [2] != -1) {
    return matrix[2];
    }
    //diagonals
    if (matrix [0] == matrix [4] && matrix [4] == matrix [8] && matrix [0] != -1) {
    return matrix[0];
    }
    if (matrix [2] == matrix [4] && matrix [4] == matrix [6] && matrix [2] != -1) {
    return matrix[2];
    }
    return -1;
    }

    }
     

    Attached Files:

  32. mellovely

    mellovely

    Joined:
    Jan 31, 2017
    Posts:
    21
    I have a similar problem to the original question, but in my case I am trying to change the movieTexture on my canvas when I press a button. I have a few buttons and a few videos, Im trying to make it so that if I press button A then video A plays, button B video B plays and so on.

    I tried adapting the solution for the original question, but i am stuck as to how to refer to a movie texture :
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class VideoChanger : MonoBehaviour {
    7.  
    8.     public MovieTexture video;
    9.  
    10.  
    11.  
    12.     public void ChangeVideo (MovieTexture myVideoToUpdate)
    13.     {
    14.        
    15.  
    16.         GetComponent<Renderer>().material.mainTexture = video;
    17.  
    18. //here I don't have a clue  
    19.         myVideoToUpdate.Renderer = MovieTextureToChangeTo;
    20.  
    21.  
    22.     }