Forum rules - please read before posting.

Customizing the hotspot label syntax for Spanish (or other languages)

Hi Chris and fellow creators!
I finally managed to buy a copy of AC on black friday and I've been binge learning it like a mad man.
I am a linguist and teacher and I am prototyping a very simple educational game in Spanish. I figured that for my purposes, the best option is a clicking menu with all verbs available on click, so that users can read the whole label as a sentence by clicking a hotspot and then hovering over the verbs. Which I managed to do with just a few clicks with AC.

Now, the thing is that there is a specific behaviour in Spanish, in which when your direct object is human (or human-like), it needs the "a" preposition before it.

Look at table - Mirar mesa
Look at Juan - Mirar a Juan

Of course I am simplifying this a lot. You can say "Mirar pasajero" (look at passenger) instead of "Mirar a pasajero". But you can pretty much apply the general rule.

I am mostly a beginner with C#, but I like to get my hands dirty and through trial and error I figured if I could add an isHuman bool in hotspots and then locate where the hotspot label is put together in the scripts, I could add a conditional statement checking for the isHuman property.
I think I pretty much managed to achieve this declaring the isHuman bool in hotspot.cs, then I modified the HotspotEditor so that I can tick the box in the inspector, and then I modified the PlayerMenus so that it checks isHuman before putting together the hotspot label, using the "a" preposition if needed. So far, so good.

Now (finally), my question is: am I doing this correctly by tweaking the AC scripts? I am aware that when I update AC, I would have to modify those three scripts again. As I mentioned I am pretty much a beginner when it comes to C# so perhaps there is a way to change this functionality without editing AC files.

Thanks in advance!

Comments

  • Welcome to the community, @HauntedPumpkin.

    Indeed, due to upgrading etc it's typically best to avoid editing core scripts unless necessary. In the case of marking a Hotspot as "isHuman", you could do this by instead giving the Hotspot GameObject a Tag name of "IsHuman". The label generation could then simply read the Hotspot's tag instead of the value of a property within the Hotspot script.

    Which part of PlayerMenus are you modifying?

    Another way of going about this would be to create a separate set of verbs in the Cursor Manager for human-like alternatives. In English, or non-Spanish languages, these would be the same as the original set, but in Spanish they could end with " a". At least, that's so far as I understand it from your description.

    It would then be a case of either updating human-like Hotspots manually to rely on these alternatives, or writing a simple script to go through all Hotspots in the scene and do this automatically. Again you could make use of tags here. Something like this should do it:

    void Awake ()
    {
        Hotspot[] allHotspots = FindObjectsOfType <Hotspot>();
        foreach (Hotspot hotspot in allHotspots)
        {
            if (hotspot.gameObject.tag == "IsHuman")
            {
                foreach (AC.Button useButton in hotspot.useButtons)
                {
                    // Convert icon ID 1 to 5
                    if (useButton.iconID == 1) useButton.iconID = 5;
                    // etc
                }
            }
        }
    }
    
  • edited December 2019

    Hi Chris! Thank you so much for your answer, it took me a while to experiment with this and reply. I think I got this, though it will surely require some tweaking, but I managed to do this only modifying the MenuInteraction.cs script and leaving the rest alone (that's the file I meant before, but I got confused when writing the message--I had a lot of scripts open that I "played with" in VS, sorry!).
    I ended up with an alternative solution, because I am using choose hotspot then interaction and opting to show all verbs, since I will be using this for education, and I'd like for the player / learner to experiment with the verbs, even in nonsensycal combinations, in order to provide more feedback. The thing is that if I have two different verbs for "mirar" and "mirar a", the interaction menu would render two buttons for "mirar" and "mirar a" (unless there is a way around that), right?
    So this what I came up with, I realized that in a way, AC already knows when a hotspot "isHuman", because they are effectively a character (AC.Char). So in InteractionMenu.cs I declared:

    private string preposition = null;

    And then I located where the verb+hotspot phrase is put together in line 567, and I edited in the following:

    if (parentMenu.TargetHotspot != null)
                        {
    
    
                            if (KickStarter.playerInteraction.GetActiveHotspot() != null
                              && KickStarter.playerInteraction.GetActiveHotspot().GetComponentInParent<AC.Char>()
                             && (iconID == 0 || iconID == 2)) //preposition only applies to transitive verbs
                            {
    
                                preposition = " a";
                            }
    
                            else
                            {
                                preposition = "";                            
                            }
    
    
                            return AdvGame.CombineLanguageString (
                                            KickStarter.cursorManager.GetLabelFromID (iconID, _language) + preposition,
                                            parentMenu.TargetHotspot.GetName (_language),
                                            _language
                                            );
                        }
    

    I only use the "a" preposition in two cases because I have only 3 verbs so far (2 that obey the rule), but I am planning on having 9 verbs, so that would have to be included in the conditional statement. But so far, so good! I am loving this toolkit and your commitment to provide such good quality documentation and support. Thank you!

  • The thing is that if I have two different verbs for "mirar" and "mirar a", the interaction menu would render two buttons for "mirar" and "mirar a" (unless there is a way around that), right?

    It's possible to limit what verbs are shown in an Interaction menu to only just those that the Hotspot uses. This can be done by checking Auto-hide Interaction icons based on Hotspot? in the Settings Manager.

    However, it's also possible to override the Hotspot string when hovering over any menu element by hooking into the OnRequestMenuElementHotspotLabel custom event. This event is called before the element's GetHotspotLabelOverride function, which is bypassed if the event returns a non-empty string. You could, therefore, try writing a custom event hook like this:

    using UnityEngine;
    using AC;
    
    public class MenuHotspotOverrideExample : MonoBehaviour
    {
    
        private void OnEnable ()
        {
            EventManager.OnRequestMenuElementHotspotLabel += My_Override;
        }
    
        private void OnDisable ()
        {
            EventManager.OnRequestMenuElementHotspotLabel -= My_Override;
        }
    
        private string My_Override (Menu menu, MenuElement element, int slot, int language)
        {
            MenuInteraction menuInteraction = element as MenuInteraction;
            if (menuInteraction != null)
            {
                int iconID = menuInteraction.iconID;
    
                if (menu.TargetInvItem != null)
                {
                    return AdvGame.CombineLanguageString (
                        KickStarter.cursorManager.GetLabelFromID (iconID, language),
                                    menu.TargetInvItem.GetLabel (language),
                                    language
                                    );
                }
    
                if (menu.TargetHotspot != null)
                {
                    string preposition = string.Empty;
                    if (menu.TargetHotspot.GetComponentInParent<AC.Char> () && (iconID == 0 || iconID == 2))
                    {
                        preposition = " a";
                    }
    
                    return AdvGame.CombineLanguageString
                    (
                        KickStarter.cursorManager.GetLabelFromID (iconID, language) + preposition,
                        menu.TargetHotspot.GetName (language),
                        language
                    );
                }
            }
            return string.Empty;
        }
    
    }
    
  • This worked!!! Thanks!!

    Re: auto hide interactions, I need all interactions to show even when there is no interaction. So hooking up to the event this way is the best option.

  • Fair enough. Actually you could just return string.Empty whenever the preposition check fails, since that would then cause the original menu text to show.

  • Perfect. Thanks again.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.