When developing using a framework, many scripts mounted by Prefab have a fixed format. Creating a cs file from Unity's basic template and then modifying it to the appropriate template will waste some time. Especially when there are a large number of different interfaces, modifying each one is a waste of time and may be missed or incorrectly modified. Write a script to create a specified template instead of the C# base template.
Note: The current script uses NGUI. When using UGUI, just replace the corresponding Component.
code
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public class MediatorScriptCreator
{
private const string MenuItemText1 = "Assets/Create/模板脚本/创建Mediator模板脚本";
private const string MenuItemText3 = "Assets/Create/模板脚本/添加Mediator模板脚本";
[MenuItem(MenuItemText1, false, 25)]
public static void CreateScript()
{
CreateScript(false);
}
[MenuItem(MenuItemText3, false, 25)]
public static void AddScript()
{
AddComp();
}
private static List<GameObject> _nodeList;
private static List<UISprite> _imgList;
private static List<UIButton> _btnList;
private static List<UILabel> _labelList;
private static List<UISlider> _sliderList;
private static void CreateScript(bool isPartial)
{
var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
var directoryPath = System.IO.Path.GetDirectoryName(assetPath);
var folderName = System.IO.Path.GetFileName(directoryPath);
var folderPath = $"Assets/Game/GameLogic/{
folderName}";
if (!Directory.Exists(folderPath))
{
if (directoryPath != null) Directory.CreateDirectory(folderPath);
}
var scriptPath = $"{
folderPath}/{
Selection.activeObject.name}Mediator.cs";
if (File.Exists(scriptPath))
{
Debug.LogError($"The script \"{
scriptPath}\" already exists.");
return;
}
var myPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
// 获取 Prefab 的所有子对象
GetNodeData(myPrefab);
var txt = $@"using UnityEngine;
namespace PD
{
{
public {
(isPartial ? "partial" : "")} class {
Selection.activeObject.name}Mediator : NGuiFormMasterLogic
{
{
public override string FacadeName
{
{
get {
{ return HomeFacade.Name; }}//TODO:修改FacadeName
}}
public new const string NAME = {
$"\"{
Selection.activeObject.name}Mediator\""};
public override void OnConstruct(object userData)
{
{
base.OnConstruct(userData);
MediatorName = NAME;
}}
";
var txtEnd = $@"
}}
}}";
for (var i = 0; i < _nodeList.Count; i++)
{
var name = _nodeList[i].name[2..];
name = name[..1].ToUpper() + name[1..];
var str = $@"
[SerializeField] private GameObject {
name};
";
txt += str;
}
for (var i = 0; i < _imgList.Count; i++)
{
var name = _imgList[i].name[2..];
name = name[..1].ToUpper() + name[1..];
var str = $@"
[SerializeField] private UISprite {
name};
";
txt += str;
}
for (var i = 0; i < _labelList.Count; i++)
{
var name = _labelList[i].name[2..];
name = name[..1].ToUpper() + name[1..];
var str = $@"
[SerializeField] private UILabel {
name};
";
txt += str;
}
for (var i = 0; i < _btnList.Count; i++)
{
var name = _btnList[i].name[2..];
name = name[..1].ToUpper() + name[1..];
var str = $@"
[SerializeField] private UIButton {
name};
";
txt += str;
}
for (var i = 0; i < _sliderList.Count; i++)
{
var name = _sliderList[i].name[2..];
name = name[..1].ToUpper() + name[1..];
var str = $@"
[SerializeField] private UISlider {
name};
";
txt += str;
}
for (var i = 0; i < _btnList.Count; i++)
{
var name = _btnList[i].name[2..];
name = name[..1].ToUpper() + name[1..];
var str = $@"
public void On{
name}Click()
{
{
}}
";
txt += str;
}
txt += txtEnd;
EditorPrefs.SetString("creatorPath", assetPath);
EditorPrefs.SetString("creatorName", myPrefab.name);
EditorPrefs.SetString("creatorScriptPath", scriptPath);
File.WriteAllText(scriptPath, txt);
AssetDatabase.Refresh();
}
public static void AddComp()
{
var scriptName = EditorPrefs.GetString("creatorName");
string[] guids = AssetDatabase.FindAssets(scriptName);
if (guids.Length > 0)
{
var assetPath = EditorPrefs.GetString("creatorPath");
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
MonoScript monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
System.Type type = monoScript.GetClass();
var prefab =
GameObject.Instantiate(
AssetDatabase
.LoadMainAssetAtPath(
assetPath)) as GameObject; // PrefabUtility.LoadPrefabContents(assetPath);//
var component = prefab.AddComponent(type);
// 获取所有字段
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var list = prefab.GetComponentsInChildren<Transform>(true).Where(a => a.name.StartsWith("m_")).ToList();
foreach (FieldInfo field in fields)
{
// 判断字段是否被序列化
var attributes = field.GetCustomAttributes(typeof(SerializeField), false);
if (attributes.Length > 0)
{
var temp = field.Name + "";
var name = temp[..1].ToLower() + temp[1..];
var go = list.FirstOrDefault(a => a.name == $"m_{
name}");
if (go != null)
{
list.Remove(go);
var btn = go.GetComponent<UIButton>();
var slider = go.GetComponent<UISlider>();
var img = go.GetComponent<UISprite>();
var txt = go.GetComponent<UILabel>();
if (btn != null)
{
var str = $"On{
field.Name}Click";
Debug.Log(str);
var delegateFunc1 = new EventDelegate(component as MonoBehaviour, str);
btn.onClick.Add(delegateFunc1);
field.SetValue(component, btn);
}
else if (slider != null)
{
field.SetValue(component, slider);
}
else if (img != null)
{
field.SetValue(component, img);
}
else if (txt != null)
{
field.SetValue(component, txt);
}
else
{
field.SetValue(component, go.gameObject);
}
}
}
}
// GetNodeData(prefab);
// PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, assetPath);
PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, assetPath, InteractionMode.AutomatedAction);
Object.DestroyImmediate(prefab);
AssetDatabase.Refresh();
}
else
{
Debug.LogError($"请先生成脚本");
}
}
[MenuItem(MenuItemText1, true)]
public static bool CreatorNormal()
{
if (!Selection.activeObject) return false;
var prefabAssetType = PrefabUtility.GetPrefabAssetType(Selection.activeObject);
return prefabAssetType != PrefabAssetType.NotAPrefab;
}
[MenuItem(MenuItemText3, true)]
public static bool AddScript1()
{
if (!Selection.activeObject) return false;
var prefabAssetType = PrefabUtility.GetPrefabAssetType(Selection.activeObject);
return prefabAssetType != PrefabAssetType.NotAPrefab;
}
private static void GetNodeData(GameObject prefab)
{
Transform[] nodes = prefab.GetComponentsInChildren<Transform>(true);
_nodeList = new List<GameObject>();
_imgList = new List<UISprite>();
_labelList = new List<UILabel>();
_btnList = new List<UIButton>();
_sliderList = new List<UISlider>();
// 遍历所有子对象
foreach (var node in nodes)
{
if (!node.gameObject.name.StartsWith("m_")) continue;
var btn = node.GetComponent<UIButton>();
var img = node.GetComponent<UISprite>();
var label = node.GetComponent<UILabel>();
var slider = node.GetComponent<UISlider>();
if (btn != null)
{
_btnList.Add(btn);
}
else if (slider != null)
{
_sliderList.Add(slider);
}
else if (img != null)
{
_imgList.Add(img);
}
else if (label != null)
{
_labelList.Add(label);
}
else
{
_nodeList.Add(node.gameObject);
}
}
}
}
Instructions
Knowledge points
1. Use the @ prefix for strings and do not need to use \n for newlines. When used with $, if there is { in the string, it needs to be
represented by { { two braces, the first one is escaped. When there is " in the string, you need to use backslash " to escape
2. Determine whether the object is Prefab, PrefabUtility.GetPrefabAssetType(Selection.activeObject) != PrefabAssetType.NotAPrefab
;
3. [MenuItem(MenuItemText2, true)]
The second parameter bool value indicates whether to display this extension method
4. Get all the Pulbic
or [SerializeField]
attributes of the specified script:type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)