Unity-角色编辑器和技能编辑器

发布于:2024-12-18 ⋅ 阅读:(39) ⋅ 点赞:(0)

一.我们要写编辑器,首先要知道编辑器是什么?

‌Unity编辑器是游戏开发的基础环境,提供了强大的工具,使开发者能够创建复杂的游戏世界和动态的游戏元素。Unity编辑器通过自定义编辑器扩展,提高了开发效率和创造力。自定义编辑器可以让开发者根据游戏需求简化工作流程,自动执行重复性任务,节省时间,并提高生产力。Unity编辑器的用户界面直观易用,开发者可以轻松地进行场景构建、资源管理、动画制作、光照设置等多种操作。

二.角色编辑器与技能编辑器

1.首先,要想写编辑器,先要在Assets旗下创建一个专门的文件夹,并且命名为Editor,在这个文件夹中创建一个RoleEditor的脚本,并且导入using UnityEditor;的命名空间,将脚本继承的MonoBehaviour换成EditorWindow,其次,我们要想在Unity界面显示出编辑器(Editor),要写[MenuItem("Editor/编辑器名称")]写这句话的效果图如下:

主菜单显示Editor

2.要想显示出编辑器,有一处是特别要注意的,就是要写GetWindow<RoleEditor>("RoleEditor").Show();的这句话的方法一定要用静态,否则无法显示编辑器。写法如下图:

静态方法

 3.编辑器要想选择图片,一定要注意我们的Sprite精灵图是.jpg格式还是.png格式等,因为我这里写的加载图片的路径,Replace用来掐头去尾,不清楚的可以把所有格式全部写出来,或者点击精灵图也可以查看精灵图的格式:

4.最后代码总结:

   (1)数据基类

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

public class DataBase
{
    public int id;
    public string name = "";
    public string iconPath = "";
}

public class RoleData : DataBase
{
    public int hp;
    public int atk;
    public int speed;
    public string rolePath = "";
    public List<int> skillid = new List<int>();
}

public class SkillData : DataBase
{
    public string skillPath = "";
    public float dis;
    public float range;
    public int num = 1;
    public List<int> buffid = new List<int>();
}

public class BuffData : DataBase
{
    public string buffPath = "";
    public string animPath = "";
    public int num;
    public float value;
}

(2)单例

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

public class Singleton<T> where T : class, new()
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if(instance == null)
            {
                instance = new T();
            }
            return instance;
        }
    }
}

  (3)管理类

using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class ConfigManager : Singleton<ConfigManager>
{
    public const string rolePath = "Json/RolePath";
    public const string skillPath = "Json/SkillPath";
    public const string buffPath = "Json/BuffPath";
    static Dictionary<string, object> dic = new Dictionary<string, object>();

    public Dictionary<int, T> GetDic<T>(string path)
    {
        if(dic.ContainsKey(path))
        {
            return dic[path] as Dictionary<int, T>;
        }
        if(File.Exists(Application.dataPath + "/Resources/" + path + ".json"))
        {
            string json = Resources.Load<TextAsset>(path).text;
            Dictionary<int,T> tdic = JsonConvert.DeserializeObject<Dictionary<int,T>>(json);
            return tdic;
        }
        return new Dictionary<int, T>();
    }

    public T GetData<T>(string path, int id)
    {
        Dictionary<int, T> tdic = GetDic<T>(path);
        return tdic[id];
    }

    public void Save(string path, object obj)
    {
        string json = JsonConvert.SerializeObject(obj);
        File.WriteAllText(Application.dataPath + "/Resources/" + path + ".json", json);
    }

    public List<string> GetNames<T>(string path, params string[] str) where T : DataBase
    {
        List<string> list = new List<string>();
        foreach (var item in GetDic<T>(path).Values)
        {
            list.Add(item.name);
        }
        foreach (var item in str)
        {
            list.Add(item);
        }
        return list;
    }
}

(4) 角色编辑器

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

public class RoleEditor : EditorWindow
{
    static Dictionary<int, RoleData> dic;
    static List<string> nameArr;
    static List<string> skillArr;
    [MenuItem("Editor/RoleEditor")]
    public static void Init()
    {
        GetWindow<RoleEditor>("RoleEditor").Show();
        dic = ConfigManager.Instance.GetDic<RoleData>(ConfigManager.rolePath);
        nameArr = ConfigManager.Instance.GetNames<RoleData>(ConfigManager.rolePath, "创建新角色");
        skillArr = ConfigManager.Instance.GetNames<SkillData>(ConfigManager.skillPath);
    }

    public static int id;
    Sprite sprite;
    GameObject model;
    int skillid;
    private void OnGUI()
    {
        id = EditorGUILayout.Popup("选择", id, nameArr.ToArray());
        if(!dic.ContainsKey(id))
        {
            dic.Add(id, new RoleData());
            dic[id].id = id;
        }
        dic[id].name = EditorGUILayout.TextField("名称:", dic[id].name);
        if (dic[id].iconPath.Length > 0)
        {
            sprite = Resources.Load<Sprite>(dic[id].iconPath);  
        }
        sprite = (Sprite)EditorGUILayout.ObjectField(sprite, typeof(Sprite), false, GUILayout.Width(100), GUILayout.Height(100));
        if(sprite != null)
        {
            string path = AssetDatabase.GetAssetPath(sprite);
            path = path.Replace("Assets/Resources/", "");
            path = path.Replace(".jpg", "");
            path = path.Replace(".png", "");
            dic[id].iconPath = path;
        }

        if (dic[id].rolePath.Length > 0)
        {
            model = Resources.Load<GameObject>(dic[id].rolePath);
        }
        model = (GameObject)EditorGUILayout.ObjectField("人物模型:", model, typeof(GameObject), false);
        if (model != null)
        {
            string path = AssetDatabase.GetAssetPath(model);
            path = path.Replace("Assets/Resources/", "");
            path = path.Replace(".prefab", "");
            dic[id].rolePath = path;
        }
        dic[id].hp = EditorGUILayout.IntField("血量:", dic[id].hp);
        dic[id].atk = EditorGUILayout.IntField("攻击力:", dic[id].atk);
        dic[id].speed = EditorGUILayout.IntField("速度:", dic[id].speed);

        GUILayout.BeginHorizontal();
        skillid = EditorGUILayout.Popup(skillid, skillArr.ToArray());
        if(GUILayout.Button("添加技能"))
        {
            dic[id].skillid.Add(skillid);
        }
        GUILayout.EndHorizontal();
        if (dic[id].skillid.Count > 0)
        {
            foreach (var item in dic[id].skillid)
            {
                GUILayout.BeginHorizontal();
                SkillData skillData = ConfigManager.Instance.GetData<SkillData>(ConfigManager.skillPath, item);
                if(GUILayout.Button(skillData.name))
                {
                    SkillEditor.id = item;
                    SkillEditor.Init();
                }
                if(GUILayout.Button("删除技能"))
                {
                    dic[id].skillid.RemoveAt(item);
                    break;
                }
                GUILayout.EndHorizontal();
            }
        }
        if(GUILayout.Button("保存"))
        {
            ConfigManager.Instance.Save(ConfigManager.rolePath, dic);
            AssetDatabase.Refresh();
        }
    }
}

(5)技能编辑器

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

public class SkillEditor : EditorWindow
{
    static Dictionary<int, SkillData> dic;
    static List<string> nameArr;
    static List<string> buffArr;
    [MenuItem("Editor/SkillEditor")]
    public static void Init()
    {
        GetWindow<SkillEditor>("SkillEditor").Show();
        dic = ConfigManager.Instance.GetDic<SkillData>(ConfigManager.skillPath);
        nameArr = ConfigManager.Instance.GetNames<SkillData>(ConfigManager.skillPath, "创建新技能");
        buffArr = ConfigManager.Instance.GetNames<BuffData>(ConfigManager.buffPath);
    }

    public static int id;
    Sprite sprite;
    private void OnGUI()
    {
        id = EditorGUILayout.Popup("选择", id, nameArr.ToArray());
        if(!dic.ContainsKey(id))
        {
            dic.Add(id, new SkillData());
            dic[id].id = id;    
        }
        dic[id].name = EditorGUILayout.TextField("技能名称:", dic[id].name);

        if (dic[id].iconPath.Length > 0)
        {
            sprite = Resources.Load<Sprite>(dic[id].iconPath);
        }
        sprite = (Sprite)EditorGUILayout.ObjectField(sprite, typeof(Sprite), false, GUILayout.Width(100), GUILayout.Height(100));

        if (sprite != null)
        {
            string path = AssetDatabase.GetAssetPath(sprite);
            path = path.Replace("Assets/Resources/", "");
            path = path.Replace(".jpg", "");
            path = path.Replace(".png", "");
            dic[id].iconPath = path;
        }

        dic[id].dis = EditorGUILayout.FloatField("施法距离:", dic[id].dis);
        dic[id].range = EditorGUILayout.FloatField("施法范围:", dic[id].range);

        if(GUILayout.Button("保存技能"))
        {
            ConfigManager.Instance.Save(ConfigManager.skillPath, dic);
            AssetDatabase.Refresh();
        }
    }
}

 注意:在Assets/Resources旗下一定要创建一个叫Json的文件夹,因为我们保存(Save)的json是在这个文件夹旗下

三.效果

(1)角色编辑器

(2)技能编辑器


网站公告

今日签到

点亮在社区的每一天
去签到