Esempio n. 1
0
        public static List <string> FetchAutocompleteOptions(string command, string[] tokens)
        {
            // can only autocomplete if there is a single token or no token
            if (tokens.Length > 1)
            {
                return(null);
            }

            // fetch the autocomplete options
            return(CommandHelpers.GetGameObjectAutocompleteOptions(tokens.Length > 0 ? tokens[0] : "", command));
        }
Esempio n. 2
0
        public static string Execute(string[] tokens)
        {
            // incorrect number of tokens found
            if (tokens.Length < 3)
            {
                return("[Error] You must provide a valid path to the game object to modify.");
            }

            // attempt to find the object
            GameObject foundObject = CommandHelpers.GetGameObject(tokens[1]);

            // object not found?
            if (foundObject == null)
            {
                return("[Error] Could not find the specified game object. Check the path. Paths must be case sensitive.");
            }

            // is the location being set as local or world?
            bool isLocal = false;

            if (tokens[0].ToLower() == "local")
            {
                isLocal = true;
            }
            else if (tokens[0].ToLower() == "world")
            {
                isLocal = false;
            }
            else
            {
                return("[Error] No indication was provided for if the coordinates are in local or world space.");
            }

            // check if the coordinates are correct
            Vector3 coordinates = Vector3.zero;

            if (!CommandHelpers.Vector3FromTokens(tokens, 2, ref coordinates))
            {
                return("[Error] The incorrect number of coordinates were given. Coordinates should be x,y,z");
            }

            // update the location
            if (isLocal)
            {
                foundObject.transform.localEulerAngles = coordinates;
            }
            else
            {
                foundObject.transform.eulerAngles = coordinates;
            }

            return(foundObject.name + " is now rotated to " + foundObject.transform.eulerAngles + " (world) " + foundObject.transform.localEulerAngles + " (local)");
        }
Esempio n. 3
0
        public static List <string> FetchAutocompleteOptions(string command, string[] tokens)
        {
            // don't autocomplete once we are entering the variable
            if (tokens.Length >= 2)
            {
                return(null);
            }

            // at the variable autocomplete stage (ie. need reflection)
            if (tokens.Length > 0 && tokens[0].Count(character => character == '.') > 1)
            {
                return(CommandHelpers.GetAutocompleteOptions(tokens[0], command, CommandHelpers.AutocompleteCandidates.Variables));
            }

            // fetch the game object autocomplete options
            string        path = tokens.Length > 0 ? tokens[0] : "";
            List <string> autocompleteOptions = CommandHelpers.GetComponentAutocompleteOptions(path, command);

            if (autocompleteOptions == null)
            {
                autocompleteOptions = new List <string>();
            }

            // user has entered exact path to a component - switch to variable autocomplete stage
            if ((tokens.Length > 0) && (autocompleteOptions.Count <= 1) && (CommandHelpers.GetComponent(tokens[0]) != null))
            {
                return(CommandHelpers.GetAutocompleteOptions(tokens[0], command, CommandHelpers.AutocompleteCandidates.Variables));
            }

            // append the type based autocomplete options
            autocompleteOptions.AddRange(ConsoleDaemon.Instance.AvailableTypes.Keys
                                         .Where(typeName => typeName.StartsWith(path))
                                         .Select(typeName => command + " " + typeName).ToList());

            // if we have no autocomplete options at this stage then we are working with a class
            if (tokens.Length > 0 && (autocompleteOptions == null || autocompleteOptions.Count <= 1))
            {
                string[] pathElements = tokens[0].Split('.');

                // check if the class is in the cached types
                if (ConsoleDaemon.Instance.AvailableTypes.ContainsKey(pathElements[0]))
                {
                    return(CommandHelpers.GetAutocompleteOptions(tokens[0], command, CommandHelpers.AutocompleteCandidates.Variables));
                }
            }

            return(autocompleteOptions);
        }
Esempio n. 4
0
        public static List <string> FetchAutocompleteOptions(string command, string[] tokens)
        {
            // no tokens so just return these options
            if (tokens.Length == 0)
            {
                return(new List <string>(new string[] { command + " enabled", command + " disabled", command + " true", command + " false" }));
            }

            // if we have one token then it may be a partial one
            if (tokens.Length == 1 &&
                tokens[0].ToLower() != "enabled" && tokens[0].ToLower() != "disabled" &&
                tokens[0].ToLower() != "true" && tokens[0].ToLower() != "false")
            {
                List <string> options = new List <string>();

                if ("enabled".StartsWith(tokens[0].ToLower()))
                {
                    options.Add(command + " enabled");
                }
                if ("disabled".StartsWith(tokens[0].ToLower()))
                {
                    options.Add(command + " disabled");
                }
                if ("true".StartsWith(tokens[0].ToLower()))
                {
                    options.Add(command + " true");
                }
                if ("false".StartsWith(tokens[0].ToLower()))
                {
                    options.Add(command + " false");
                }

                return(options);
            }

            // invalid number of tokens so no autocompletion
            if (tokens.Length > 2)
            {
                return(null);
            }

            // fetch the autocomplete options
            return(CommandHelpers.GetComponentAutocompleteOptions(tokens.Length > 1 ? tokens[1] : "", command + " " + tokens[0]));
        }
Esempio n. 5
0
        public static string Execute(string[] tokens)
        {
            if (tokens.Length < 1)
            {
                return("[Error] You must provide a path to the component to remove.");
            }

            // attempt to find the component
            Component foundComponent = CommandHelpers.GetComponent(tokens[0]);

            if (foundComponent == null)
            {
                return("[Error] Could not find the specified component. Check that the path is correct.");
            }

            GameObject.Destroy(foundComponent);

            return("Component destroyed");
        }
Esempio n. 6
0
        public static string Execute(string[] tokens)
        {
            // incorrect number of tokens found
            if (tokens.Length != 1)
            {
                return("[Error] You must provide a valid path to the game object to query.");
            }

            // attempt to find the object
            GameObject foundObject = CommandHelpers.GetGameObject(tokens[0]);

            // object not found?
            if (foundObject == null)
            {
                return("[Error] Could not find the specified game object. Check the path. Paths must be case sensitive.");
            }

            return(foundObject.name + " has a scale of " + foundObject.transform.localScale + " (local) ");
        }
Esempio n. 7
0
        public static string Execute(string[] tokens)
        {
            if (tokens.Length == 0)
            {
                return("[Error] You must provide the name of at least one scene to load.");
            }

            // get the names of the scenes in the build
            List <string> sceneNamesInBuild = CommandHelpers.GetSceneNamesInBuild();

            // force additive if there are multiple scenes
            bool isAdditive = tokens.Length > 1 ? true : false;

            // check that all of the provided scene names are valid
            foreach (string sceneName in tokens)
            {
                string workingSceneName = sceneName.ToLower();

                if (workingSceneName == "additive")
                {
                    isAdditive = true;
                }
                else if (sceneNamesInBuild.IndexOf(workingSceneName) < 0)
                {
                    return("[Error] Unable to load scene \'" + sceneName + "\' as it is not in the build settings.");
                }
            }

            // load the requested scenes
            foreach (string sceneName in tokens)
            {
                // skip if trying to do additive loading
                if (sceneName.ToLower() == "additive")
                {
                    continue;
                }

                SceneManager.LoadScene(sceneName, isAdditive ? LoadSceneMode.Additive : LoadSceneMode.Single);
            }

            return("Loaded the requested scenes.");
        }
Esempio n. 8
0
        public static string Execute(string[] tokens)
        {
            // incorrect number of tokens found
            if (tokens.Length != 1)
            {
                return("[Error] You must provide a valid path to the game object to query.");
            }

            // attempt to find the object
            GameObject foundObject = CommandHelpers.GetGameObject(tokens[0]);

            // object not found?
            if (foundObject == null)
            {
                return("[Error] Could not find the specified game object. Check the path. Paths must be case sensitive.");
            }

            Dictionary <string, Component> componentMapping = CommandHelpers.GetComponentMapping(foundObject);
            List <string> componentNames = componentMapping.Keys.ToList();

            // find the longest component name
            int longestComponentName = 0;

            foreach (string componentName in componentNames)
            {
                longestComponentName = Mathf.Max(componentName.Length, longestComponentName);
            }

            // build the list of components
            string result = "Found the following components: ";

            foreach (string componentName in componentNames)
            {
                Component component = componentMapping[componentName];
                string    status    = component is Behaviour ? ((component as Behaviour).enabled ? "Enabled" : "Disabled") : "Always Enabled";

                result += System.Environment.NewLine + "    " + componentName.PadRight(longestComponentName) + "    : " + status;
            }

            return(result);
        }
Esempio n. 9
0
        public static List <string> FetchAutocompleteOptions(string command, string[] tokens)
        {
            // can only autocomplete if there are no, 1 or 2 tokens
            if (tokens.Length > 2)
            {
                return(null);
            }

            // none or one token?
            if (tokens.Length <= 1)
            {
                List <string> autocompleteOptions = CommandHelpers.GetGameObjectAutocompleteOptions(tokens.Length > 0 ? tokens[0] : "", command);

                if (autocompleteOptions != null)
                {
                    return(autocompleteOptions);
                }
            }

            // this shouldn't happen! but just in case
            if (tokens.Length == 0)
            {
                Debug.LogError("Failed to find autocomplete options and have no tokens. This shouldn't be possible.");
                return(null);
            }

            // setup the base path for the autocomplete options
            string basePath = tokens[0];

            if (basePath.Contains(" "))
            {
                basePath = command + " \"" + tokens[0] + "\"";
            }
            else
            {
                basePath = command + " " + tokens[0];
            }

            // fetch the autocomplete options
            return(CommandHelpers.GetGameObjectAutocompleteOptions(tokens.Length > 1 ? tokens[1] : "", basePath));
        }
Esempio n. 10
0
        public static string Execute(string[] tokens)
        {
            // incorrect number of tokens found
            if (tokens.Length != 1)
            {
                return("[Error] You must provide a valid path to the game object to destroy.");
            }

            // attempt to find the object
            GameObject foundObject = CommandHelpers.GetGameObject(tokens[0]);

            // object not found?
            if (foundObject == null)
            {
                return("[Error] Could not find the specified game object. Check the path. Paths must be case sensitive.");
            }

            GameObject.Destroy(foundObject);

            return("Object destroyed.");
        }
Esempio n. 11
0
        public static string Execute(string[] tokens)
        {
            // incorrect number of tokens found
            if (tokens.Length != 2)
            {
                return("[Error] Incorrect number of parameters. You must provide the true/false/enabled/disabled flag and a valid path to the component to modify.");
            }

            // invalid flag provided
            string enabledFlag = tokens[0].ToLower();

            if (enabledFlag.ToLower() != "enabled" && enabledFlag.ToLower() != "disabled" &&
                enabledFlag.ToLower() != "true" && enabledFlag.ToLower() != "false")
            {
                return("[Error] Unknown flag. You must provide the true/false/enabled/disabled flag and a valid path to the component to modify.");
            }

            // attempt to find the component
            Component foundComponent = CommandHelpers.GetComponent(tokens[1]);

            // component not found?
            if (foundComponent == null)
            {
                return("[Error] Could not find the specified component. Check the path. Paths must be case sensitive.");
            }

            // component cannot be enabled/disabled
            if (!(foundComponent is Behaviour))
            {
                return("[Error] The component does not support being enabled or disabled.");
            }

            // Update the component
            (foundComponent as Behaviour).enabled = (enabledFlag == "enabled") || (enabledFlag == "true");

            return("Component is now " + enabledFlag);
        }
Esempio n. 12
0
        public static string Execute(string[] tokens)
        {
            // incorrect number of tokens found
            if (tokens.Length == 0)
            {
                return("[Error] You must provide a valid path to the game object to update and optionally a path to the new parent.");
            }

            // attempt to find the object
            GameObject foundObject = CommandHelpers.GetGameObject(tokens[0]);

            // object not found?
            if (foundObject == null)
            {
                return("[Error] Could not find the game object to change. Check the path. Paths must be case sensitive.");
            }

            // attempt to find the new parent object
            GameObject foundParentObject = tokens.Length > 1 ? CommandHelpers.GetGameObject(tokens[1]) : null;

            // object not found?
            if (tokens.Length > 1 && foundParentObject == null)
            {
                return("[Error] Could not find the new parent game object. Check the path. Paths must be case sensitive.");
            }

            // did the user give the same path?
            if (foundObject == foundParentObject)
            {
                return("[Error] The object and the new parent cannot be the same. Please provide two different game objects.");
            }

            // reparent the object
            foundObject.transform.SetParent(foundParentObject != null ? foundParentObject.transform : null);

            return("Parent updated");
        }
Esempio n. 13
0
        public static string GetValue(string path)
        {
            // split based on the . as this might indicate a component or variable split
            string[] pathElements = path.Split('.');

            System.Type foundType      = null;
            Component   foundComponent = null;

            System.Object foundObject = null;

            // attempt to find the type
            if (ConsoleDaemon.Instance.AvailableTypes.ContainsKey(pathElements[0]))
            {
                foundType = ConsoleDaemon.Instance.AvailableTypes[pathElements[0]];
            }

            // if there are multiple path elements then we may have a component
            if (pathElements.Length >= 2)
            {
                // attempt to find the component, if found then retrieve the type
                foundComponent = CommandHelpers.GetComponent(pathElements[0] + "." + pathElements[1]);
                if (foundComponent != null)
                {
                    foundType   = foundComponent.GetType();
                    foundObject = foundComponent;
                }
            }

            // no matching type should only happen if invalid information has been entered
            if (foundType == null)
            {
                return("[Error] Failed to find a matching component or type. Check the entered path.");
            }

            // track the index into the path for the earliest spot a variable may be
            int variableStart = foundComponent != null ? 2 : 1;

            // cache the binding flags (can only search for instance if we have a component)
            BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

            if (foundComponent != null)
            {
                flags |= BindingFlags.Instance;
            }

            // traverse the hierarchy of the path to find the last node
            bool lastElementIsPartial = false;

            for (int pathIndex = variableStart; pathIndex < pathElements.Length; ++pathIndex)
            {
                FieldInfo field = foundType.GetField(pathElements[pathIndex], flags);
                lastElementIsPartial = true;

                if (field != null)
                {
                    // even if the parent was static after we are one field in we are dealing with an actual variable so add instance
                    flags |= BindingFlags.Instance;

                    foundType            = field.FieldType;
                    lastElementIsPartial = false;

                    foundObject = field.GetValue(foundObject);
                }
                else
                {
                    PropertyInfo property = foundType.GetProperty(pathElements[pathIndex], flags);

                    if (property != null)
                    {
                        // even if the parent was static after we are one field in we are dealing with an actual variable so add instance
                        flags |= BindingFlags.Instance;

                        foundType            = property.PropertyType;
                        lastElementIsPartial = false;

                        foundObject = property.GetValue(foundObject, null);
                    }
                }

                // no found object
                if (foundObject == null)
                {
                    return("[Error] Failed to access the object. It may have been destroyed.");
                }
            }

            // if the last element is partial then an error has occurred
            if (lastElementIsPartial)
            {
                return("[Error] An incomplete path to a variable was supplied. Check the path. Paths are case sensitive.");
            }

            return("The value is: " + foundObject.ToString());
        }
Esempio n. 14
0
        public static System.Object ConstructObjectFromString(System.Type type, string value)
        {
            // If the type is a string then our process is simple
            if (type == typeof(string))
            {
                return(value);
            }
            // if the type is a vector 2, 3 or 4 then handle it
            if (type == typeof(Vector2))
            {
                // convert the string to a vector 2
                Vector2 vectorValue = Vector2.zero;
                if (CommandHelpers.Vector2FromTokens(new string[] { value }, 0, ref vectorValue))
                {
                    return(vectorValue);
                }

                return(null);
            }
            if (type == typeof(Vector3))
            {
                // convert the string to a vector 3
                Vector3 vectorValue = Vector3.zero;
                if (CommandHelpers.Vector3FromTokens(new string[] { value }, 0, ref vectorValue))
                {
                    return(vectorValue);
                }

                return(null);
            }
            if (type == typeof(Vector4))
            {
                // convert the string to a vector 4
                Vector4 vectorValue = Vector4.zero;
                if (CommandHelpers.Vector4FromTokens(new string[] { value }, 0, ref vectorValue))
                {
                    return(vectorValue);
                }

                return(null);
            }
            if (type == typeof(Quaternion))
            {
                // convert the string to a quaternion
                Vector4 vectorValue = Vector4.zero;
                if (CommandHelpers.Vector4FromTokens(new string[] { value }, 0, ref vectorValue))
                {
                    return(new Quaternion(vectorValue.x, vectorValue.y, vectorValue.z, vectorValue.w));
                }

                return(null);
            }
            if (type == typeof(Color))
            {
                // is the value being provided as a web style string?
                if (value.Contains('#'))
                {
                    Color colour = Color.magenta;
                    if (ColorUtility.TryParseHtmlString(value, out colour))
                    {
                        return(colour);
                    }
                }                 // otherwise assume it is a RGBA set
                else
                {
                    // convert the string to a color
                    Vector4 vectorValue = Vector4.zero;
                    if (CommandHelpers.Vector4FromTokens(new string[] { value }, 0, ref vectorValue))
                    {
                        return(new Color(vectorValue.x, vectorValue.y, vectorValue.z, vectorValue.w));
                    }
                }

                return(null);
            }

            // does the type have a parse method that takes a string?
            MethodInfo parseMethod = type.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null,
                                                    CallingConventions.Any, new System.Type[] { typeof(string) }, null);

            if (parseMethod != null)
            {
                try
                {
                    return(parseMethod.Invoke(null, new object[] { value }));
                }
                catch (System.Exception ex)
                {
                    Debug.LogError("Failed to parse type: " + ex.Message);
                    return(null);
                }
            }

            // does the type have a constructor that takes a string?
            ConstructorInfo constructor = type.GetConstructor(new System.Type[] { typeof(string) });

            if (constructor != null)
            {
                try
                {
                    return(constructor.Invoke(new object[] { value }));
                }
                catch (System.Exception ex)
                {
                    Debug.LogError("Failed to construct type: " + ex.Message);
                    return(null);
                }
            }

            return(null);
        }
Esempio n. 15
0
        public static List <string> GetAutocompleteOptions(string path, string command, AutocompleteCandidates candidateType)
        {
            // if we're at this point we know we have at least either a component or a class with static members

            // split based on the . as this might indicate a component or variable split
            string[] pathElements = path.Split('.');

            System.Type foundType      = null;
            Component   foundComponent = null;

            // attempt to find the type
            if (ConsoleDaemon.Instance.AvailableTypes.ContainsKey(pathElements[0]))
            {
                foundType = ConsoleDaemon.Instance.AvailableTypes[pathElements[0]];
            }

            // if there are multiple path elements then we may have a component
            if (pathElements.Length >= 2)
            {
                // attempt to find the component, if found then retrieve the type
                foundComponent = CommandHelpers.GetComponent(pathElements[0] + "." + pathElements[1]);
                if (foundComponent != null)
                {
                    foundType = foundComponent.GetType();
                }
            }

            // no matching type should only happen if invalid information has been entered
            if (foundType == null)
            {
                return(null);
            }

            // track the index into the path for the earliest spot a variable may be
            int variableStart = foundComponent != null ? 2 : 1;

            // cache the binding flags (can only search for instance if we have a component)
            BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

            if (foundComponent != null)
            {
                flags |= BindingFlags.Instance;
            }

            // traverse the hierarchy of the path to find the last node
            bool lastElementIsPartial = false;

            for (int pathIndex = variableStart; pathIndex < pathElements.Length; ++pathIndex)
            {
                FieldInfo field = foundType.GetField(pathElements[pathIndex], flags);
                lastElementIsPartial = true;

                if (field != null)
                {
                    // even if the parent was static after we are one field in we are dealing with an actual variable so add instance
                    flags |= BindingFlags.Instance;

                    foundType            = field.FieldType;
                    lastElementIsPartial = false;
                }
                else
                {
                    PropertyInfo property = foundType.GetProperty(pathElements[pathIndex], flags);

                    if (property != null)
                    {
                        // even if the parent was static after we are one field in we are dealing with an actual variable so add instance
                        flags |= BindingFlags.Instance;

                        foundType            = property.PropertyType;
                        lastElementIsPartial = false;
                    }
                }
            }

            // find all candidate fields
            string              partialName   = lastElementIsPartial ? pathElements[pathElements.Length - 1] : "";
            List <FieldInfo>    fieldInfos    = foundType.GetFields(flags).Where(field => field.Name.StartsWith(partialName)).ToList();
            List <PropertyInfo> propertyInfos = foundType.GetProperties(flags).Where(property => property.Name.StartsWith(partialName)).ToList();
            List <MethodInfo>   methodInfos   = null;

            // if we're doing a method search then also check methods
            if (candidateType == AutocompleteCandidates.Functions)
            {
                methodInfos = foundType.GetMethods(flags).Where(method => method.Name.StartsWith(partialName)).ToList();
            }

            // no valid items found
            if ((fieldInfos == null || fieldInfos.Count == 0) &&
                (propertyInfos == null || propertyInfos.Count == 0) &&
                (methodInfos == null || methodInfos.Count == 0))
            {
                return(null);
            }

            // assemble the base command
            string basePath  = "";
            int    lastIndex = lastElementIsPartial ? pathElements.Length - 1 : pathElements.Length;

            for (int index = 0; index < lastIndex; ++index)
            {
                basePath += pathElements[index] + ".";
            }

            // build the autocomplete options
            List <string> autocompleteOptions = new List <string>(fieldInfos.Count);
            bool          needsEscaping       = basePath.Contains(" ");

            foreach (FieldInfo fieldInfo in fieldInfos)
            {
                string option = (command + " ") + (needsEscaping ? ("\"" + basePath + fieldInfo.Name + "\"") : (basePath + fieldInfo.Name));
                autocompleteOptions.Add(option);
            }
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                string option = (command + " ") + (needsEscaping ? ("\"" + basePath + propertyInfo.Name + "\"") : (basePath + propertyInfo.Name));
                autocompleteOptions.Add(option);
            }
            if (candidateType == AutocompleteCandidates.Functions)
            {
                foreach (MethodInfo methodInfo in methodInfos)
                {
                    string option = (command + " ") + (needsEscaping ? ("\"" + basePath + methodInfo.Name + "\"") : (basePath + methodInfo.Name));

                    // for now only include those without parameters
                    if (methodInfo.GetParameters().Length > 0)
                    {
                        continue;
                    }

                    if (!autocompleteOptions.Contains(option))
                    {
                        autocompleteOptions.Add(option);
                    }
                }
            }

            return(autocompleteOptions);
        }
Esempio n. 16
0
        public static List <string> FetchAutocompleteOptions(string command, string[] tokens)
        {
            // get the names of the scenes in the build
            List <string> sceneNamesInBuild = CommandHelpers.GetSceneNamesInBuild();

            List <string> autocompleteOptions = new List <string>();
            string        baseCommand         = command;;

            // check if the user has already indicated additive
            bool needAdditiveInOptions = true;

            foreach (string token in tokens)
            {
                if (token.ToLower() == "additive")
                {
                    needAdditiveInOptions = false;
                    break;
                }
            }

            // handle additive keyword by sneakily adding it as a scene name unless the tokens already contain that keyword
            if (needAdditiveInOptions)
            {
                sceneNamesInBuild.Add("additive");
            }

            // if there are no tokens then nothing further to do. the current base command is fine
            if (tokens == null || tokens.Length == 0)
            {
            }             // check if the last token exactly matches a scene name
            else if (sceneNamesInBuild.Contains(tokens[tokens.Length - 1].ToLower()))
            {
                // construct the base command
                foreach (string sceneName in tokens)
                {
                    // remove the scene from the available options
                    sceneNamesInBuild.Remove(sceneName.ToLower());

                    baseCommand += " " + (sceneName.Contains(" ") ? "\"" + sceneName + "\"" : sceneName);
                }
            }             // otherwise the token contains a partial name
            else
            {
                // construct the base command (exclude the final token)
                for (int index = 0; index < tokens.Length - 1; ++index)
                {
                    // remove the scene from the available options
                    sceneNamesInBuild.Remove(tokens[index].ToLower());

                    baseCommand += " " + (tokens[index].Contains(" ") ? "\"" + tokens[index] + "\"" : tokens[index]);
                }

                // filter out any scene names that do not match the potential candidates
                string partialName = tokens[tokens.Length - 1].ToLower();
                if (partialName != "additive")
                {
                    for (int index = 0; index < sceneNamesInBuild.Count; ++index)
                    {
                        if (!sceneNamesInBuild[index].StartsWith(partialName))
                        {
                            sceneNamesInBuild.RemoveAt(index);
                            --index;
                        }
                    }
                }
                else
                {
                    baseCommand += " additive";
                }

                // if we ended up with no valid scene names then error out
                if (sceneNamesInBuild.Count == 0)
                {
                    return(null);
                }
            }

            // fill out the list of autocomplete options
            foreach (string sceneName in sceneNamesInBuild)
            {
                string workingSceneName = sceneName.Contains(" ") ? "\"" + sceneName + "\"" : sceneName;

                autocompleteOptions.Add(baseCommand + " " + workingSceneName);
            }

            return(autocompleteOptions);
        }