1
votes

On my scene view in unity, I have three gameobjects set up, each with a respective sprite renderer and sprites. Two of the three are smaller in dimensions than the third one.

The images displayed by both smaller sprites are different. What I'd like to do is to be able to change the sprite of the third one by clicking on the other two. Clicking on one of the smaller sprites will make the third larger sprite match the small sprite that was previously clicked.

Here are the relevant scripts assigned to the two smaller sprites.

1st one that handles which sprite is displayed on the small sprite:

public class CardModel : MonoBehaviour
{
    SpriteRenderer spriteRenderer;  // renders sprite

    public int cardIndex;       // indicates what the card is
    public bool show;           // shows or hides card

    public Sprite[] cardFronts; // collection of cards' front sides
    public Sprite cardBack;     // backside of all cards

    // if card is turned up, show front of card, show back otherwise
    public void DisplaySprite()
    {
        if (show)
            spriteRenderer.sprite = cardFronts[cardIndex];
        else
            spriteRenderer.sprite = cardBack;
    }

    void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();    // retrieve our sprite renderer
        DisplaySprite();                                         // show card's sprite
    }
}

And 2nd one that makes the smaller sprites clickable:

public class ClickCard : MonoBehaviour
{
    CardModel model; // used to retrieve card index and bool to assign to larger sprite

    public GameObject largeSprite; // third large sprite

    void OnMouseDown()
    {
        CardModel cModel = GetComponent<CardModel>(); // retrieve card model from smaller sprite
        LargeCardModel largeCardModel = largeSprite.GetComponent<LargeCardModel>(); // retrieve card model for larger sprite

        largeCardModel.matchSprite(cModel.show, cModel.cardIndex); // match large sprite with small sprite clicked
    }
}

And finally, the script attached to the third large sprite:

public class LargeCardModel : MonoBehaviour
{
    public int largeIndex; // determines which sprite to show

    public Sprite[] largeCardFaces; // collection of large sprites
    public Sprite largeCardBack; // large card back

    SpriteRenderer largeRenderer; // renders the image upon the large sprite

    void Awake()
    {
        largeRenderer = GetComponent<SpriteRenderer>(); // retrieve renderer
    }

    // method to allow sprite to be changed
    public void matchSprite(bool showFace, int cIndex)
    {
        if (largeRenderer == null)
            largeRenderer = GetComponent<SpriteRenderer>(); // for some reason, I need to include this line or else I get an exception

        if (showFace)
            largeRenderer.sprite = largeCardFaces[cIndex];
        else
            largeRenderer.sprite = largeCardBack;
    }
}

For whatever reason, I can't get the image to the larger sprite to change during runtime however when I stop running the program, the large sprite changes to that of the last smaller sprite I clicked on.

1
If I understand this correctly, you basically have 3 sprites, lets say 1, 2, 3. What you are saying is, if number 1 or 2 is clicked, number 3 should change to an enlarged version of the one you just clicked? Is this what you mean? - Tom
Yes. There are two sets of images. Both sets are the same save for differences in sizes. - user1800967
I think the code you've got for what you are trying to do is a bit of an overkill, have you tried instantiating instead of trying to manually change the 3rd sprite properties? that would be simpler and easier to implement? I could answer an idea if you havent tried it :) - Tom
Is it more taxing to change the sprite than to just repeatedly instantiate? For what I'm planning, the image of the large sprite will be changing numerous times. - user1800967
You have a point. If you have numerous things changing, instantiating may be more taxing. Ill have a think and get back to you :) - Tom

1 Answers

0
votes

Okay, bare with as I have not tested this in Unity yet.

I think you're over complicating what you are trying to do. What you want is basically when sprite 1 or 2 is clicked, sprite 3 becomes what you have just clicked.

Here's an idea to try out:

Small Card GameObject:

public int cardIndex;       // indicates what the card is
public bool show;           // shows or hides card

public Sprite[] cardFronts; // collection of cards' front sides
public Sprite cardBack;     // backside of all cards

GameObject largeSprite;     //the large sprite that we will be changing!

void Start()
{
    largeSprite = GameObject.Find("Name of the large sprite"); //find our large sprite!
}


// if card is turned up, show front of card, show back otherwise
public void DisplaySprite()
{
    if (show)
        gameObject.sprite = cardFronts[cardIndex]; //or it could be gameObject.renderer.sprite, I havent tested!
    else
        gameObject.sprite = cardBack;
}

void Awake()
{
    DisplaySprite(); // show card's sprite
}

void OnMouseDown()
{
    largeSprite.sprite = gameObject.sprite; //make the large one have the same as the small one!
}

Explanation:

Assuming this works, I've completely removed the script from the large GameObject and merged the 2 scripts together in the small one.

In Start() we find the large card gameObject using GameObject.Find() that way Unity will find your object with the name you've supplied and will go from there.

In OnMouseDown() we basically say:

  • if you clicked on me

  • make the large card the same as me! I havent tested it so that line might be a bit off, but the idea is there.

All in all, this is now one script that is attached to your small card object. Like I said I havent tested it, but I think the idea is there.

Hope this helps! :)