Forum rules - please read before posting.

New Menu Link element

edited February 2018 in Engine development
Would it be possible in a future version of AC to have a new "Link" menu element that would allow players to click on it to open a provided link in a web browser? It could also be a Label element with a label type of link.

The element would have a text label (displayed in the menu, as for label element) and a url property (address to open in the browser). It would call Application.OpenURL ("URL");

Comments

  • I feel that would be too limiting, as it's essentially a button with only one purpose.

    The current Button element can be set to run an ActionList (in which a custom Action can open the link), or run a custom script (using the OnMenuElementClick event).  Both of these would allow for the OpenURL method call to be made.

    Making a new custom Action for this is very simple.  Follow the tutorial (and see the "ActionTemplate" file), then place the method call inside your Action's Run() method, followed by "return 0f;".
  • Using a button with a custom action is probably the best way. I will write the custom action script.
  • edited February 2018
    Hi Chris,

    I've created a new custom Action which can open a URL in a new browser window. It can either use an entered URL or use one contained in a string variable.

    I wanted to share the code with the community on the Wiki, but it requires creating a new account (stupid, as it allows you to login using Facebook) and the editor doesn't seem to load properly on my PC. Anyway, if you or any other AC user wants the code, I can send it on.
  • By all means!
  • Hi Chris and @wmsgva , I'm going to be uploading my game to Android either Friday or Monday and I'm finishing up the last few items. The cheater, video link in my hints section is one of the last steps. I don't understand what you're saying to do to add a link Chris, so I'm also asking for a pull-down to add an outside link. This would be the first time I've had to add code so I'm pretty lost. Any help @wmsgva would be greatly appreciated. Thanks!
  • Sorry, been busy on other things for a few days.

    The code is hereafter. To use it, you need to copy the code into a file (I used LinkFollow.cs), copy the file into the directory you use for custom actions (as defined under "Custom action scripts" on AC's Action menu tab).

    After doing this, you should have a new custom action which you can use in ActionLists: in the action box, select Custom : Link. This allows you to specify a URL to jump to or to use one contained in a global variable.

    To use this from a menu button for example, in the button's "ActionList to run" field, specify an ActionList which contains this new custom action.

    /*
     *
     *  Adventure Creator
     *  by Chris Burton, 2013-2016
     *
     *  "LinkFollow.cs"
     *  by Warren Smith, 2018
     *
     *  This action opens a given URL in an external browser.
     *
     */

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

    #if UNITY_EDITOR
    using UnityEditor;

    namespace AC
    {

      [System.Serializable]
      public class LinkFollow : Action
      {
    public enum SetLinkMethod { EnteredHere=0, CopiedFromGlobalVariable=1 };

    public SetLinkMethod setVarMethodString = SetLinkMethod.EnteredHere;
        public string urlToFollow;

    public int parameterID = -1;
    public int setParameterID = -1;
    public int variableID = -1;

    #if UNITY_EDITOR
    private VariableType VarType = VariableType.String;

        public LinkFollow ()
        {
          this.isDisplayed = true;
          category = ActionCategory.Custom;
          title = "Link";
          description = "Opens a given URL in a browser.";
        }


        override public void AssignValues (List<ActionParameter> parameters)
        {
      variableID = AssignVariableID (parameters, parameterID, variableID);
      urlToFollow = AssignString (parameters, setParameterID, urlToFollow);
        }


        override public float Run ()
        {
          if (!isRunning)
          {
            isRunning = true;

    if (setVarMethodString == SetLinkMethod.CopiedFromGlobalVariable)
    {
    GVar sVar;
    sVar = GlobalVariables.GetVariable (variableID);
    urlToFollow = sVar.textVal;
    }

    if (urlToFollow != "")
    {
    Application.OpenURL (urlToFollow);
    }

    return 0f;
          }
          else
          {
            isRunning = false;
            return 0f;
          }
        }


        #if UNITY_EDITOR

        override public void ShowGUI (List<ActionParameter> parameters)
        {
          parameterID = Action.ChooseParameterGUI ("URL to open:", parameters, parameterID, ParameterType.String);

          if (parameterID < 0)
          {
    setVarMethodString = (SetLinkMethod)EditorGUILayout.EnumPopup ("Source type:", setVarMethodString);
    if (setVarMethodString == SetLinkMethod.CopiedFromGlobalVariable)
    {
    if (AdvGame.GetReferences ().variablesManager)
    {
    variableID = ShowVarGUI (AdvGame.GetReferences ().variablesManager.vars, parameters, ParameterType.GlobalVariable, variableID, parameterID);

    // Check types match?
    if (parameterID == -1 && VarType != VariableType.String)
    {
    EditorGUILayout.HelpBox ("The chosen Variables do not share the same Type - a conversion will be attemped", MessageType.Info);
    }
    }
    } else
    {
    urlToFollow = EditorGUILayout.TextField ("http://", urlToFollow);
    if (urlToFollow == "") {
    EditorGUILayout.HelpBox ("Empty URL provided.", MessageType.Info);
    }
    }
          }
          AfterRunningOption ();
        }

    private int ShowVarGUI (List<GVar> vars, List<ActionParameter> parameters, ParameterType parameterType, int variableID, int parameterID)
    {
    // Create a string List of the field's names (for the PopUp box)
    List<string> labelList = new List<string>();

    int i = 0;
    int variableNumber = -1;

    if (vars.Count > 0)
    {
    foreach (GVar _var in vars)
    {
    labelList.Add (_var.label);

    // If a GlobalVar variable has been removed, make sure selected variable is still valid
    if (_var.id == variableID)
    {
    variableNumber = i;
    }
    i ++;
    }

    if (variableNumber == -1 && (parameters == null || parameters.Count == 0 || parameterID == -1))
    {
    // Wasn't found (variable was deleted?), so revert to zero
    ACDebug.LogWarning ("Previously chosen variable no longer exists!");
    variableNumber = 0;
    variableID = 0;
    }

    string label = "Source variable:";

    parameterID = Action.ChooseParameterGUI (label, parameters, parameterID, parameterType);
    if (parameterID >= 0)
    {
    //variableNumber = 0;
    variableNumber = Mathf.Min (variableNumber, vars.Count-1);
    variableID = -1;
    }
    else
    {
    variableNumber = EditorGUILayout.Popup (label, variableNumber, labelList.ToArray());
    variableID = vars [variableNumber].id;
    }
    }
    else
    {
    EditorGUILayout.HelpBox ("No variables exist!", MessageType.Info);
    variableID = -1;
    variableNumber = -1;
    }
    if (variableNumber >= 0)
    {
    VarType = vars[variableNumber].type;
    }

    return variableID;
    }


        public override string SetLabel ()
        {

    string labelAdd;

    if (setVarMethodString == SetLinkMethod.EnteredHere) {
    labelAdd = " (" + urlToFollow + ")";
    } else {
    labelAdd = " (from variable)";
    }
          return labelAdd;
        }

        #endif

      }

    }
  • I get the following error code when trying to use this. Any suggestions what to change to fix?

    Instance of LinkFollow couldn't be created. The the script class needs to derive from ScriptableObject.
    UnityEngine.ScriptableObject:CreateInstance(String)
    AC.AdventureCreator:RefreshActions() (at Assets/AdventureCreator/Scripts/Managers/Editor/AdventureCreator.cs:511)
    AC.ActionListEditorWindow:OnEnable() (at Assets/AdventureCreator/Scripts/ActionList/Editor/ActionListEditorWindow.cs:110)
    UnityEditor.EditorWindow:GetWindow(Type)
    AC.ActionListEditorWindow:CreateWindow() (at Assets/AdventureCreator/Scripts/ActionList/Editor/ActionListEditorWindow.cs:53)
    AC.ActionListEditorWindow:Init(ActionList) (at Assets/AdventureCreator/Scripts/ActionList/Editor/ActionListEditorWindow.cs:77)
    AC.HierarchyIcons:HierarchyItemCB(Int32, Rect) (at Assets/AdventureCreator/Scripts/ActionList/Editor/HierarchyIcons.cs:71)
    UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

  • edited December 2018

    Have you installed it in the correct way, as outlined in this tutorial? Is it listed in the Actions Manager?

    Sometimes restarting Unity can resolve this.

  • edited December 2018

    Installed as instructed, but wasn't working until rebooting machine and not just reloading Unity. One of those weird PC moments. Thanks, now works excellent! :smiley:

  • edited January 28

    Am I right to assume that this script needs to be updated to work under 1.72.4?

    And what would have to be changed to make it accept all kinds of variables instead of only Global Vars (plus parameters), too?

  • Am I right to assume that this script needs to be updated to work under 1.72.4?

    The only issue I can see is the need to change:

    urlToFollow = sVar.textVal;
    

    with:

    urlToFollow = sVar.TextValue;
    

    what would have to be changed to make it accept all kinds of variables instead of only Global Vars (plus parameters), too?

    You can define and expose a VariableLocation enum variable to let the user choose between Global and Local, and then call LocalVariables.GetVariable depending.

    Parameters are an extra complication, but a series of tutorials on writing custom Actions (that concludes with the introduction of parameters) can be found here.

  • Yes, right. And parameters are already included, too.

    I just would have liked to let the script access Component Variables, but I couldn't get it to work.

  • Unfortunately I cannot get this to work with the option "Copied from Global Variable".

    The problem is that "Copied from Global Variable" doesn't copy … I suspect it doesn't do anything in fact.

    • If I do a first run with "Copied from Global Variable" nothing happens.
    • If I then switch to "Entered here" and enter a specific address, it works perfectly.
    • As soon as I switch back to "Copied from Global Variable", it will still open the address I entered before, regardless of what should get copied from the global var selected.

    It's a pity because this custom action would be a great addition!

  • Works for me. Here's a more cleanly-formatted script:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class LinkFollow : Action
        {
    
            public enum SetLinkMethod { EnteredHere=0, CopiedFromGlobalVariable=1 };
    
            public SetLinkMethod setVarMethodString = SetLinkMethod.EnteredHere;
            public string urlToFollow;
    
            public int parameterID = -1;
            public int setParameterID = -1;
            public int variableID = -1;
    
            #if UNITY_EDITOR
            private VariableType VarType = VariableType.String;
            #endif
    
            public LinkFollow ()
            {
                this.isDisplayed = true;
                category = ActionCategory.Custom;
                title = "Link";
                description = "Opens a given URL in a browser.";
            }
    
    
            override public void AssignValues (List<ActionParameter> parameters)
            {
                variableID = AssignVariableID (parameters, parameterID, variableID);
                urlToFollow = AssignString (parameters, setParameterID, urlToFollow);
            }
    
    
            override public float Run ()
            {
                if (setVarMethodString == SetLinkMethod.CopiedFromGlobalVariable)
                {
                    GVar sVar;
                    sVar = GlobalVariables.GetVariable (variableID);
                    urlToFollow = sVar.TextValue;
                }
    
                if (!string.IsNullOrEmpty (urlToFollow))
                {
                    Debug.Log ("Open " + urlToFollow);
                    //Application.OpenURL (urlToFollow);
                }
                return 0f;
            }
    
    
            #if UNITY_EDITOR
    
            override public void ShowGUI (List<ActionParameter> parameters)
            {
                parameterID = Action.ChooseParameterGUI ("URL to open:", parameters, parameterID, ParameterType.String);
    
                if (parameterID < 0)
                {
                    setVarMethodString = (SetLinkMethod)EditorGUILayout.EnumPopup ("Source type:", setVarMethodString);
                    if (setVarMethodString == SetLinkMethod.CopiedFromGlobalVariable)
                    {
                        if (AdvGame.GetReferences ().variablesManager)
                        {
                            variableID = ShowVarGUI (AdvGame.GetReferences ().variablesManager.vars, parameters, ParameterType.GlobalVariable, variableID, parameterID);
    
                            // Check types match?
                            if (parameterID == -1 && VarType != VariableType.String)
                            {
                                EditorGUILayout.HelpBox ("The chosen Variables do not share the same Type - a conversion will be attemped", MessageType.Info);
                            }
                        }
                    }
                    else
                    {
                        urlToFollow = EditorGUILayout.TextField ("http://", urlToFollow);
    
                        if (string.IsNullOrEmpty (urlToFollow))
                        {
                            EditorGUILayout.HelpBox ("Empty URL provided.", MessageType.Info);
                        }
                    }
                }
                AfterRunningOption ();
            }
    
            private int ShowVarGUI (List<GVar> vars, List<ActionParameter> parameters, ParameterType parameterType, int variableID, int parameterID)
            {
                // Create a string List of the field's names (for the PopUp box)
                List<string> labelList = new List<string>();
    
                int i = 0;
                int variableNumber = -1;
    
                if (vars.Count > 0)
                {
                    foreach (GVar _var in vars)
                    {
                        labelList.Add (_var.label);
    
                        if (_var.id == variableID)
                        {
                            variableNumber = i;
                        }
                        i ++;
                    }
    
                    if (variableNumber == -1 && (parameters == null || parameters.Count == 0 || parameterID == -1))
                    {
                        // Wasn't found (variable was deleted?), so revert to zero
                        ACDebug.LogWarning ("Previously chosen variable no longer exists!");
                        variableNumber = 0;
                        variableID = 0;
                    }
    
                    string label = "Source variable:";
    
                    parameterID = Action.ChooseParameterGUI (label, parameters, parameterID, parameterType);
                    if (parameterID >= 0)
                    {
                        variableNumber = Mathf.Min (variableNumber, vars.Count-1);
                        variableID = -1;
                    }
                    else
                    {
                        variableNumber = EditorGUILayout.Popup (label, variableNumber, labelList.ToArray());
                        variableID = vars [variableNumber].id;
                    }
                }
                else
                {
                    EditorGUILayout.HelpBox ("No variables exist!", MessageType.Info);
                    variableID = -1;
                    variableNumber = -1;
                }
                if (variableNumber >= 0)
                {
                    VarType = vars[variableNumber].type;
                }
    
                return variableID;
            }
    
            #endif
    
        }
    
    }
    
  • So, I've followed the instructions listed here and on that tutorial. I've created the new custom action and its showing up in the editor, I can type out a link, but for some reason no page is being opened up. Any ideas what I'm doing wrong?

  • The above script actually has the link-opening commented out. Replace:

    //Application.OpenURL (urlToFollow);
    

    with:

    Application.OpenURL (urlToFollow);
    
  • edited July 3

    Ok, I've done that now, but now I'm getting this error:

    https://ibb.co/7yzsKP0

  • That's not coming from AC - and not Unity by the looks of it.

    The AC side of things is just providing a means to call the above line - you'll need to consult Unity's documentation on it for guidance:

    https://docs.unity3d.com/ScriptReference/Application.OpenURL.html

  • Ok, thanks.

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.