我想在Unity Editor中創(chuàng)建一個(gè)易于使用的按鈕,用于創(chuàng)建角色和項(xiàng)目.
我會(huì)在這里拋出一些額外的信息來幫助解釋我的問題.
我的游戲結(jié)構(gòu)如下;
游戲控制器>>字符腳本>> (PlayerName)腳本
字符對(duì)象具有字符腳本和以其命名的腳本.
我希望能夠在Unity編輯器中單擊“創(chuàng)建新角色”,它會(huì)執(zhí)行以下操作:
1)提示使用名稱.
2)從用戶輸入的內(nèi)容中創(chuàng)建名為Name的空游戲?qū)ο?
3)創(chuàng)建一個(gè)名為相同的新C#腳本,并將其添加到對(duì)象中.
– 我希望生成的腳本中包含一些預(yù)先確定的“字符模板”代碼.
4)將新腳本附加到新的空游戲?qū)ο?并附加“角色腳本”.
提前致謝.
最后一個(gè)子問題.
通過角色腳本上的公共單一行為從GameController訪問PlayerNamedScript會(huì)更好嗎?
或者,CharacterScript可以動(dòng)態(tài)擴(kuò)展PlayerNamedScript兄弟姐妹.
我希望這很清楚.再次感謝.
解決方法:
試試吧
將CharacterCreatorEditor.cs放在項(xiàng)目中某處名為Editor的文件夾中.
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's 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's 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's 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's 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's 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 () { }}
代碼說明
首先,編輯器腳本獲取所有輸入變量(應(yīng)該相當(dāng)明顯它們是什么)
單擊完成按鈕后,會(huì)發(fā)生以下情況
>實(shí)例化一個(gè)新的GameObject
>實(shí)例化的GameObject的名稱與編輯器中的字符名稱相同(例如John Doe)
>附加了CharacterScript(您的通用腳本)
>讀取模板文本文件(“CharacterTemplate.txt”),并將所有數(shù)據(jù)替換為您在編輯器窗口中輸入的數(shù)據(jù)
>然后將其寫入新的腳本文件
>我們刷新資產(chǎn)數(shù)據(jù)庫,并等待新編譯的腳本編譯(例如JohnDoe.cs)
>最后將腳本附加到步驟1中實(shí)例化的GameObject
對(duì)于第二個(gè)問題,您需要做的是讓所有PlayerNamedClass擴(kuò)展相同的基類.這樣,您可以鍵入將在CharacterScript中公開的變量
因此,例如,如果您調(diào)用基類“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>();}
希望這能回答你的問題.如果您遇到問題,請(qǐng)發(fā)表評(píng)論
來源:https://www.icode9.com/content-1-263151.html聯(lián)系客服