Unity 4.6 Editor, Create Script with Predefined Data

I am trying to make an easy-to-use button in the Unity editor to create a character and element.

I will post some additional information here to help explain my problem. My game is structured like this: Game controller → Script symbol → (player name) Script The symbol object has both the Script symbol and the Script named after it on it.

I want to be able to click "Create a new character" in the Unity editor and do the following: 1) Request a name to use. 2) Create an empty game object named Name from any user-entered. 3) Create a new C # Script with the same name and add it to the object. -I want the generated Script to have some predefined character pattern code in it. 4) Attach the new Script to the new empty game object and attach "Character Script" to it.

Thanks in advance.

Last question. Would it be better to access PlayerNamedScript from GameController using a public all-in-one candybar on the Script symbol?

Or maybe CharacterScript can dynamically extend PlayerNamedScript, sibling.

I hope this is clear. Thanks again.

+4
2

CharacterCreatorEditor.cs - .

CharacterCreatorEditor.cs

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;

public class CharacterCreatorEditor : EditorWindow {

    #region Character Fields
    //Add as many character specific fields / variables you want here.
    //Remember to update the same thing in the "CharacterTemplate.txt"!
    public string characterName = "John Doe";

    public float characterHealth = 10;

    public int characterCost = 1000;

    public bool isBadGuy = false;
    #endregion


    private bool needToAttach = false;      //A boolean that checks whether a newly created script has to be attached
    private float waitForCompile = 1;       //Counter for compile
    GameObject tempCharacter;               //A temporary GameObject that we assign the new chracter to.


    //A Menu Item when clicked will bring up the Editor Window
    [MenuItem ("AxS/Create New Character")]
    public static void CreateNewChar () {
         EditorWindow.GetWindow(typeof(CharacterCreatorEditor));
    }


    void OnGUI () {

        GUILayout.Label("Here a sample Editor Window. Put in more variables as you need below.");
        GUILayout.Space(10);

        //Note on adding more fields
        //The code below is broken into groups, one group per variable
        //While it relatively long, it keeps the Editor Window clean
        //Most of the code should be fairly obvious

        GUILayout.BeginHorizontal();
        GUILayout.Label("Character Name", new GUILayoutOption[0]);
        characterName = EditorGUILayout.TextField(characterName, new GUILayoutOption[0]);
        GUILayout.EndHorizontal();
        GUILayout.Space(10);

        GUILayout.BeginHorizontal();
        GUILayout.Label("Character Health", new GUILayoutOption[0]);
        characterHealth = EditorGUILayout.FloatField(characterHealth, new GUILayoutOption[0]);
        GUILayout.EndHorizontal();
        GUILayout.Space(10);

        GUILayout.BeginHorizontal();
        GUILayout.Label("Character Cost", new GUILayoutOption[0]);
        characterCost = EditorGUILayout.IntField(characterCost, new GUILayoutOption[0]);
        GUILayout.EndHorizontal();
        GUILayout.Space(10);

        GUILayout.BeginHorizontal();
        GUILayout.Label(string.Format("Is {0} a Bad Guy?", new object[] { characterName }), new GUILayoutOption[0]);
        isBadGuy = EditorGUILayout.Toggle(isBadGuy, new GUILayoutOption[0]);
        GUILayout.EndHorizontal();
        GUILayout.Space(10);

        GUI.color = Color.green;

        //If we click on the "Done!" button, let create a new character
        if(GUILayout.Button("Done!", new GUILayoutOption[0]))
            CreateANewCharacter();

    }

    void Update () {
        //We created a new script below (See the last few lines of CreateANewCharacter() )
        if(needToAttach) {

            //Some counter we just keep reducing, so we can give the
            //EditorApplication.isCompiling to kick in
            waitForCompile -= 0.01f;

            //So a few frames later, we can assume that the Editor has enough
            //time to "catch up" and EditorApplication.isCompiling will now be true
            //so, we wait for the newly created script to compile
            if(waitForCompile <= 0) {

                 //The newly created script is done compiling
                if(!EditorApplication.isCompiling) {

                    //Lets add the script
                    //Here we add the script using the name as a string rather than
                    //it type in Angled braces (As done below)
                    tempCharacter.AddComponent(characterName.Replace(" ", ""));

                    //Reset the control variables for attaching these scripts.
                    needToAttach = false;
                    waitForCompile = 1;
                }
            }
         }
    }

    private void CreateANewCharacter () {

        //Instantiate a new GameObject
        tempCharacter = new GameObject();

        //Name it the same as the Character Name 
        tempCharacter.name = characterName;

        //Add the ChracterScript component. Note the use of angle braces over quotes
        tempCharacter.AddComponent<CharacterScript>();

        //Loading the template text file which has some code already in it.
        //Note that the text file is stored in the path PROJECT_NAME/Assets/CharacterTemplate.txt
        TextAsset templateTextFile = AssetDatabase.LoadAssetAtPath("Assets/CharacterTemplate.txt", 
                                                               typeof(TextAsset)) as TextAsset;
        string contents = "";
        //If the text file is available, lets get the text in it
        //And start replacing the place holder data in it with the 
        //options we created in the editor window
        if(templateTextFile != null) {
            contents = templateTextFile.text;
            contents = contents.Replace("CHARACTERCLASS_NAME_HERE", characterName.Replace(" ", ""));
             contents = contents.Replace("CHARACTER_NAME_HERE", characterName);
            contents = contents.Replace("CHARACTER_HEALTH_HERE", characterHealth.ToString());
            contents = contents.Replace("CHARACTER_COST_HERE", characterCost.ToString());
            contents = contents.Replace("CHARACTER_BAD_GUY_HERE", isBadGuy.ToString().ToLower());
        }
        else {
            Debug.LogError("Can't find the CharacterTemplate.txt file! Is it at the path YOUR_PROJECT/Assets/CharacterTemplate.txt?");
        }

        //Let create a new Script named "CHARACTERNAME.cs"
        using(StreamWriter sw = new StreamWriter(string.Format(Application.dataPath + "/{0}.cs", 
                                                           new object[] { characterName.Replace(" ", "") }))) {
            sw.Write(contents);
        }
        //Refresh the Asset Database
        AssetDatabase.Refresh();

        //Now we need to attach the newly created script
        //We can use EditorApplication.isCompiling, but it doesn't seem to kick in
        //after a few frames after creating the script. So, I've created a roundabout way
        //to do so. Please see the Update function
        needToAttach = true;
    }

}



"YOUR_PROJECT/Assets/CharacterTemplate.txt" , !

CharacterTemplate.txt

using UnityEngine;
using System.Collections;


public class CHARACTERCLASS_NAME_HERE : MonoBehaviour {

    public string characterName = "CHARACTER_NAME_HERE";

    public float characterHealth = CHARACTER_HEALTH_HERE;

    public int characterCost = CHARACTER_COST_HERE;

    public bool isBadGuy = CHARACTER_BAD_GUY_HERE;


    public void SomeMethod () {

    }
}



-, script ( , ) "", :

  • GameObject
  • GameObject , (, John Doe)
  • ( script)
  • ( "CharacterTemplate.txt" ) , , .
  • script
  • script (, JohnDoe.cs)
  • , script GameObject, 1



, , PlayerNamedClass . , , CharacterScript

, , "NamedCharacterScripts"

JohnDoe.cs

public class JohnDoe : NamedCharacterScripts

JaneDoe.cs

public class JaneDoe : NamedCharacterScripts

CharacterScript.cs

public NamedCharacterScripts namedCharacterScript;

void Awake () {
    //This will assign JohnDoe.cs for the GameObject named "John Doe" &
    //JaneDoe.cs to the GameObject named "Jane Doe"
    namedCharacterScript = GetComponent<NamedCharacterScripts>();
}

, . ,

+4

My script , Venkat, .

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

[ExecuteInEditMode]
public class CharacterTools : MonoBehaviour
{
    [SerializeField, HideInInspector]
    private string className;

    private bool waitForCompile = false;

    private void Update()
    {
        if (string.IsNullOrEmpty(className))
            return;

        if (waitForCompile && EditorApplication.isCompiling)
            waitForCompile = false;

        if (!waitForCompile && !EditorApplication.isCompiling)
        {
            var gameObject = new GameObject(className);
            Debug.Log("Attempting to add " + className);
            var c = gameObject.AddComponent(className);

            className = null;
        }
    }

    [ContextMenu("Create character")]
    private void CreateCharacter()
    {
        string name = "Number" + Random.Range(0, 100).ToString();

        string nameTemplate = "{0}Character";
        string contentTemplate = @"using UnityEngine;

public class {0} : MonoBehaviour
{{
}}
";

        var className = string.Format(nameTemplate, name);
        var path = Application.dataPath + "/" + className + ".cs";

        var scriptFile = new StreamWriter(path);
        scriptFile.Write(string.Format(contentTemplate, className));
        scriptFile.Close();

        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport);
        AssetDatabase.Refresh();

        this.className = className;
        this.waitForCompile = true;
    }
}

:

  • script .
  • .
  • " ".
  • .
0

Source: https://habr.com/ru/post/1570176/


All Articles