Search Unity

Using string concatenation with the Unity Editor ?

Discussion in 'Scripting' started by Althos, Feb 14, 2020.

  1. Althos

    Althos

    Joined:
    Sep 23, 2019
    Posts:
    17
    Hi, I'm currently trying to make a card game, and my cards are currently saved as Scriptable objects, however, I'm having an issue when it comes to displaying the card effects :
    As the value of a card's effect can sometime get modified during playthrough, I need the text effect to be udpated too, which can easily be done with some string concatenation, however, I don't think these can be created directed with Unity's Editor.
    This is annoying since all my cards share the same structure, making personalized dynamic effect texts would require to either create a new custom instance for each card, or to implement another scriptable object which would only contain the text.

    Does anyone know if there is a way to fix my problem ? Thanks a lot for your help!
     
  2. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    313
    Think of ScriptableObject as data containers. Yes, they are capable of more, but eventually you will run into such issues as yours. How to solve this? Separate instances from data.

    Every card could be represented as a ScriptableObject instance. However, when your player uses cards, he doesn't use these instances, these data containers, but wrappers which only reference these ScriptableObjects. Very simple, it could look like this:

    Code (CSharp):
    1. public class GameCard : ScriptableObject { /*...*/ }
    Code (CSharp):
    1. public class CardWrapper : MonoBehaviour {
    2.     public GameCard card;
    3.     /* ....*/
    4. }
    If doesn't look very appealing to you, let's think about it some more. Do you happen to play Hearthstone? It is a card game in which one of the things that you can do is play monsters. Monsters can have unique properties, such as Lifesteal, Poison and Double Attack. In the example code above, your ScriptableObject would know that your monster has such an unique property, but what if another card alters said properties, maybe adding new ones or removing others? This is why the wrapper is handy. The wrapper is the actual instance, the monster on the field, based on the card, on the data "in the back". This could be simply a list of properties, with the properties themselves being ScriptableObjects as well, for instance.

    Getting back to your specific problem. Let's say your card has some unique text, but you need to add more? The wrapper could reference the text from the ScriptableObject and the combine it with whatever text is required through runtime effects from properties and such, using said string concatenation, displaying it into some UI.
     
  3. Althos

    Althos

    Joined:
    Sep 23, 2019
    Posts:
    17
    Hi, thanks for your answer. What I'm trying to do, rather than dynamically add or remove text, is to have text that contain value which can be dynamically edited.
    If I have an effect string that reads "Deals 4 damage", and have another property that increases the amount of damage done by said card, the text can't be edited to reflect that. The way to do around that would be to use string concatenation, which (as far as I know), can only be done through scripting, which in turns also means that I have to create a separate unique ScriptableObject instance for each card, which is definitely possible, but also unneeded if it is indeed possible to do string concatenation from the editor itself.
     
  4. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    313
    You can use String.Format to easily build your text together. A very short example could be
    $"Deals {myDamageValue} damage"
    . How this works in your environment highly depends on your UI solution. If there are things that can change in your tooltip, it might be worth to update the corresponding UI element and rebuild it at runtime.