0
\$\begingroup\$

Why do my image sprites only change after closing the run, instead of when I start the game?

What I mean by this is that, upon starting the run, it does nothing. But once I hit the play button to end the run, it suddenly changes the images of shirtSpace and pantsSpace in both the game window and editor?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ClothesScript : MonoBehaviour
{
    // Variables
    Image shirtRenderer;
    Image pantsRenderer;
    Sprite[] shirtArray;
    Sprite[] pantsArray;
    public GameObject shirtSpace;
    public GameObject pantsSpace;
    int currentShirtIndex = 0;
    int currentPantsIndex = 0;

    // Start is called before the first frame update
    void Start()
    {
        shirtRenderer = shirtSpace.GetComponent<Image>();
        pantsRenderer = pantsSpace.GetComponent<Image>();
        shirtArray = new Sprite[4];
        pantsArray = new Sprite[4];
        LoadArrays();
        UpdateShirt();
        UpdatePants();
    }

    // Update is called once per frame
    void Update()
    {

    }

    // LoadArrays is called by Start to fill the arrays
    void LoadArrays()
    {
        shirtArray[0] = Resources.Load<Sprite>("Shirt0");
        shirtArray[1] = Resources.Load<Sprite>("Shirt1");
        shirtArray[2] = Resources.Load<Sprite>("Shirt2");
        shirtArray[3] = Resources.Load<Sprite>("Shirt3");
        pantsArray[0] = Resources.Load<Sprite>("Pants0");
        pantsArray[1] = Resources.Load<Sprite>("Pants1");
        pantsArray[2] = Resources.Load<Sprite>("Pants2");
        pantsArray[3] = Resources.Load<Sprite>("Pants3");
    }

    // UpdateShirt is called by Start and whenever the currentShirtIndex is changed
    void UpdateShirt()
    {
        shirtRenderer.sprite = shirtArray[2];
        Debug.Log("Cleared Shirt");
    }

    // UpdatePants is called by Start and whenever the currentPantsIndex is changed
    void UpdatePants()
    {
        pantsRenderer.sprite = pantsArray[currentPantsIndex];
        Debug.Log("Cleared Pants");
    }

    // ShirtDecrease is called when ShirtLeftButton is clicked
    public void ShirtDecrease()
    {
        if(currentShirtIndex <= 1)
        {
            currentShirtIndex = 3;
        }
        else
        {
            currentShirtIndex--;
        }
    }

    // ShirtIncrease is called when ShirtRightButton is clicked
    public void ShirtIncrease()
    {
        if(currentShirtIndex == 3)
        {
            currentShirtIndex = 1;
            UpdateShirt();
        }
        else
        {
            currentShirtIndex++;
        }

        UpdateShirt();
    }

    // PantsDecrease is called when PantsLeftButton is clicked
    public void PantsDecrease()
    {
        if(currentPantsIndex <= 1)
        {
            currentPantsIndex = 3;
        }
        else
        {
            currentPantsIndex--;
        }
    }

    // PantsChange is called when PantsRightButton is clicked
    public void PantsIncrease()
    {
        if(currentPantsIndex == 3)
        {
            currentPantsIndex = 1;
        }
        else
        {
            currentPantsIndex++;
        }
    }
}
\$\endgroup\$
5
  • \$\begingroup\$ What I mean by this is that, upon starting the run, it does nothing. But once I hit the play button to end the run, it suddenly changes the images of shirtSpace and pantsSpace in both the game window and editor? \$\endgroup\$
    – gtc26
    May 23 at 16:48
  • \$\begingroup\$ shirtRenderer.sprite = shirtArray[2]; in UpdateShirt() seems wrong \$\endgroup\$
    – Zibelas
    May 23 at 17:04
  • \$\begingroup\$ @gtc26 If you have something to add to help readers better understand your question, please edit the question to include that information directly in your question. \$\endgroup\$
    – Pikalek
    May 24 at 2:44
  • \$\begingroup\$ There is a lot of things wrong with your increase/ decrease functions as well. *Decrease() and *Increase never loads the image at location 0. *Pants() never calls the UpdatePants() \$\endgroup\$
    – Zibelas
    May 24 at 7:41
  • \$\begingroup\$ @Zibelas thank you. Haha I added that for testing but forgot to remove it \$\endgroup\$
    – gtc26
    May 24 at 11:34

1 Answer 1

0
\$\begingroup\$

It looks to me like you want something more like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ClothesScript : MonoBehaviour
{
    // Let's not repeat ourselves. 
    // Make a class for all the code used by both shirt & pants, so we type it once.
    [System.Serializable]
    public class SpriteSwapper {
        // Assign this in the inspector, like you do with shirtSpace already.
        [SerializeField] SpriteRenderer renderer;

        // Likewise, assign your sprites in the inspector.
        // Avoid using Resources.Load()
        [SerializeField] Sprite[] sprites;
 
        int currentIndex;

        public void SetSprite(int index) {
            // Wrap the index into the bounds of the array 
            // (-1 will go to the last item in the array, -2 the second last...)
            // I assume index >= -sprites.Length, but you can check/assert if needed.
            currentIndex = (index + sprites.Length) % sprites.Length;
            renderer.sprite = sprites[currentIndex];
        }

        // No need for separate Increase/Decrease methods.
        // Call CycleSprite(1) to step forward, CycleSprite(-1) to step backward.
        public void CycleSprite(int step) {
            // Because of the wrapping in SetSprite, this handles any step forward,
            // or a step as large as the full array length backward.
            SetSprite(currentIndex + step);
        }
    }

    // Now each clothing item is just an instance of that class.
    [SerializeField] SpriteSwapper shirt;
    [SerializeField] SpriteSwapper pants;

    // No searching to do - you can just initialize each swapper.
    void Start() {
        shirt.SetSprite(0);
        pants.SetSprite(0);
    }

    // If you want to maintain the same API, it's just one-liners now:
    public void ShirtIncrease() { shirt.CycleSprite( 1); }
    public void ShirtDecrease() { shirt.CycleSprite(-1); }
    public void PantsIncrease() { pants.CycleSprite( 1); }
    public void PantsDecrease() { pants.CycleSprite(-1); }
}

That's much less code, even with all my comments, and will scale better as you add more clothing items to swap. If you encounter a bug, you can fix it in one place and it will work the same for all clothing items, unlike your current code where it's easy to introduce an inconsistency between shirts and pants, as shown in your question:

void UpdateShirt()
{
    shirtRenderer.sprite = shirtArray[2]; // Always picks 2.
    Debug.Log("Cleared Shirt");
}

void UpdatePants()
{
    pantsRenderer.sprite = pantsArray[currentPantsIndex]; // Variable index.
    Debug.Log("Cleared Pants");
}
\$\endgroup\$
7
  • \$\begingroup\$ Thank you! Haha, I forgot to remove the shirtArray[2] from my testing \$\endgroup\$
    – gtc26
    May 24 at 11:35
  • \$\begingroup\$ Sorry if I was vague by the way, but I meant to make the shirt and pants sprites able to be mismatched (it will be an easy puzzle where the player has to match the two articles of clothing) \$\endgroup\$
    – gtc26
    May 24 at 11:51
  • \$\begingroup\$ If that solved your problem, you can click the checkmark in the upper left to mark it as accepted. If not, try editing your question to clarify the problem. \$\endgroup\$
    – DMGregory
    May 24 at 12:53
  • \$\begingroup\$ I've been working the past hour and accidentally made some changes, but I'm sure it'll work once I readjust to fit your code more \$\endgroup\$
    – gtc26
    May 24 at 12:55
  • \$\begingroup\$ I've been working on it a lot, but it either says "Can't divide by 0" or the inspector won't show the CycleSprite \$\endgroup\$
    – gtc26
    Jun 11 at 14:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .