0
\$\begingroup\$

In many times, prefabs that share the same script may require the same GameObject in the script. For example, in my game I want to make a series of card prefabs. Each card has their own image when shown, but has the same back image when hidden. My script for card is:

public class DraggingCard : DragAndDropItem
{
    public Sprite secretSprite; //This is the same for every card
    Sprite oringinalSprite; //This is individual for every card
    Image image;

    public void Awake()
    {
        image = GetComponent<Image>();
        oringinalSprite = image.sprite;
    }

    public void Activate()
    {
        image.sprite = oringinalSprite;
    }

    public void Hide()
    {
        image.sprite = secretSprite;
    }
}

But if I write this, I'll have to assign the secretSprite in the inspector for every DraggingCard prefab. I tried to set secretPrefab to be static or const but neither worked.

I believe there must be a clever way to avoid the repeat work. Could anyone tell me that? Thank you!

\$\endgroup\$
  • \$\begingroup\$ Can you confirm if your objects containing DraggingCard are all instances of the same prefab, or if there are multiple base prefabs? \$\endgroup\$ – Gnemlock Jan 21 '17 at 21:53
  • \$\begingroup\$ @Gnemlock There are multiple prefabs. Each of the prefab has an Image whose sprite is originalSprite, and is attached with a DraggingCard script. \$\endgroup\$ – DarkZero Jan 22 '17 at 2:50
1
\$\begingroup\$

The easiest and cheapest method is to do it all in one go.

Select all of your prefabs in your project window (you can use search to get them all in one view, even if they're in different folders), and then assign the field once. The newly assigned value will be applied to every prefab in your selection.

Most scripts you write in Unity will support this type of multi-editing out of the box. If using a custom editor you might need to do a little work to enable this.


Some alternatives you can use if you need something more elaborate:

A) In your Start script, load the texture you want with Resources.Load - you pass a path to the texture from a folder called Resources, which can be a static string. Just note that anything in a Resource folder will always be included in your build, even if you stop using it, and Unity won't be able to see this reference to pre-load the assets you need, so loading a lot of assets this way can introduce a performance hit.

B) Introduce an object with a "Manager" script into your scene, where the manager's job is to keep track of common references other scripts need. In Start, your other scripts can find the manager with built-in Find methods or a static GetInstance method, and ask it for their references. That way you only need to assign the references once to the manager object's prefab.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you! I'm now temporarily fixing it with Resources.Load, but it makes annoyed that I have to explicitly put sprites that I want every prefab to share in the folder... \$\endgroup\$ – DarkZero Jan 22 '17 at 3:07
  • 1
    \$\begingroup\$ Did you try just doing it with multi-select? It's a more scalable solution unless you find some obstacle to doing it that way. \$\endgroup\$ – DMGregory Jan 22 '17 at 3:09
  • \$\begingroup\$ It worked like a charm! Thank you! I don't have enough rep to vote you up though.... \$\endgroup\$ – DarkZero Jan 22 '17 at 3:12
  • \$\begingroup\$ No worries, I've got all the rep I need. Good luck! \$\endgroup\$ – DMGregory Jan 22 '17 at 3:13
-1
\$\begingroup\$

Assign the script and the secretSprite to your DraggingCard object before you make it a prefab. Then every DraggingCard instance that you place in your scene will already have the secretSprite assigned to it.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Because you've already made your prefab, just select one of the DraggingCard instances in your scene that you've already assigned the sercretSprite to, and click the 'Apply' button in the inspector- that will update the prefab object itself and apply the changes to any existing instances of the prefab that you have in your scene. \$\endgroup\$ – David Greaves Jan 21 '17 at 9:10
  • 1
    \$\begingroup\$ I think this question is about having more than one prefab. (For example, if I have a deck of cards with a prefab for AceOfClubs and TwoOfClubs and...) - so the scene instances aren't all sharing a single root prefab. \$\endgroup\$ – DMGregory Jan 21 '17 at 13:04
  • \$\begingroup\$ In that example though, all of the cards are essentially the same object, they just need a different sprite assigned for their face (something you would probably assign at run time using the output of your shuffling/card selection algorithm). The back of the card, or in this case the 'secretSprite' is presumably one sprite shared by each individual card. \$\endgroup\$ – David Greaves Jan 21 '17 at 13:54
  • \$\begingroup\$ reversing my vote. DraggingCard being a script, there is no guarantee that all cards will be the same object. \$\endgroup\$ – Gnemlock Jan 21 '17 at 21:51
  • 1
    \$\begingroup\$ Maybe someone would think it is better to make only one Card prefab, and assign each of the Card objects their own sprite and values when spawned, but I don't think this is better than making a prefab for each card, because it is just a difference on either you do more dirty work in the code or in the inspector...from the view of a Unity beginner. \$\endgroup\$ – DarkZero Jan 23 '17 at 3:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.