unity编辑器

需要存储,就需要需要序列化,需要序列化成一个字符串
需要使用的化得经过反序列化才能使用
编辑器就是给类加标签,json与之差不多
一个变量可以加多个特性

[Hideinspector]隐藏

[Serializablefild]显示

[range(1,5)]范围

[tooltop("xxx")] 提示,添加变量悬浮提示文字

[Header("xxx")] 加在前面的文字

[Space(50)] 与上一行留像素距离

[Muiltline(5)] 加行,多行

[Textarea(5,10)] 默认五行,再多十行,再多就滚动条

枚举是下拉菜单 多选直接上2的n次幂

[Contexmenu("xxx")] 给小齿轮加回调函数
void 方法名(){}

[Contexmenuitem("xx","xx")],提示+函数名字
void xx(){}

[Requirecomponent(typeof())] 绑定类

[Executeineditmode] 在编辑的时候执行一下

[Addcomponentmenu(xxx,排第几)]  添加到addcomponent里

异或位运算。
相同为零,不同为一。
A与B异或得到C,那么。B与C异或,可再次获得A。A与C异或,可再次获得B.
所以如果A是明文,B是密钥,C就是密文,使用异或实现的算法,可以将C密文利用B密钥,解出A即原始文字。

监视器脚本,外挂式编程

Editor目录下建立外挂式开发脚本,将编辑器脚本与外挂脚本关联

外挂脚本在Editor下,所以不会被打入游戏包 不继承mono,而是继承editor 引入编辑器的命名空间,检视器属于编辑器开发范畴,继承Editor类,使用编辑器相关的成员变量和生命周期函数

找关系,引入特性[Customeditor(typeof(类名))],将编辑器开发脚本,与需要编辑的组件建立外挂联系


玩家类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public enum PlayerProfression
{
    Warrior=0,
    Wizard=1
}
public enum PlayerLoveColor
{
    Green=1,
    Red=2,
    Pink=4,
}
//将player组件添加到addcompent上
//第一个参数:分类名/组件名
//第二个参数:列表中显示的顺序
[AddComponentMenu("自定义控制器/玩家控制器",1)]
//使生命周期函数,在编辑状态下可以执行,在游戏中也可以正常使用
//update()在场景中对象发生变化或项目组织发生变化时会在编辑器下执行
[ExecuteInEditMode]
//关于类型和类名
//BoxCollider是类名,适用于函数提供泛型方法
//typeof(BoxCollider):System.Type,c#的类型,适用于需要system.Type参数
//当前组件依赖于盒子碰撞器
//当前组件挂在对象上时,盒子碰撞体会一起被添加上去
//player没有被移除时,盒子碰撞体也不能被移除
[RequireComponent(typeof(BoxCollider))]
public class Player : MonoBehaviour
{
    public int ID;
    public string Name;
    public float Atk;
    public bool isMan;
    public Vector3 HeadDir;
    public Color Hair;
    public GameObject Weapon;
    public Texture Cloth;
    public PlayerProfression Pro;
    public PlayerLoveColor LoveColor;
    public List<string> Items;


    private void Update()
    {
       // Debug.Log("Update");
    }
}
外挂的玩家类编辑器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//步骤1:引入编辑器的命名空间,检视器属于编辑器开发范畴
using UnityEditor;
//步骤3:将编辑器开发脚本于需要编辑的组件脚本简历外挂关联关系
//外挂脚本因为储存在Editor目录下,所以不会被最终打入游戏包
//不继承Mono,而是继承Editor
[CustomEditor(typeof(Player))]
//步骤2:继承Editor类,使用编辑器相关的成员变量和生命周期函数
public class PlayerEditor : Editor
{
    public Player _Component;
    //步骤4:需要在当前的外挂脚本中,获得需要被扩展得Player组件对象
    //当关联组件所在对象被选中或组件被添加时,调用
    private void OnEnable()
    {
        //步骤5:获取Player组件对象
        _Component = target as Player;

    }
    //当关联组件所在对象被销毁或组件被移除时,调用
    private void OnDisable()
    {
        _Component = null;
    }
    //用于绘制检视面板的生命周期函数
    public override void OnInspectorGUI()
    {
        //标题显示
        EditorGUILayout.LabelField("人物相关属性");
        //整数
        _Component.ID = EditorGUILayout.IntField("玩家ID", _Component.ID);
        //文本
        _Component.Name = EditorGUILayout.TextField("玩家名称", _Component.Name);
        //浮点数
        _Component.Atk = EditorGUILayout.FloatField("玩家攻击力", _Component.Atk);
        //布尔
        _Component.isMan = EditorGUILayout.Toggle("是否为男性", _Component.isMan);
        //向量
        _Component.HeadDir = EditorGUILayout.Vector3Field("头部方向", _Component.HeadDir);
        //颜色
        _Component.Hair = EditorGUILayout.ColorField("头发颜色", _Component.Hair);

        //对象数据类型的绘制
        //参数1:标题            参数2:原始组件的值
        //参数3:成员变量的类型  参数4:是否可以将场景中的对象拖给这个变量
        _Component.Weapon = EditorGUILayout.ObjectField("持有武器", _Component.Weapon,
            typeof(GameObject), true)as GameObject;
        _Component.Cloth = EditorGUILayout.ObjectField("衣服材质贴图", _Component.Cloth,
            typeof(Texture), false) as Texture;


        //枚举数据类型的绘制
        //整数转枚举
        //单选枚举(标题,组件上的原始值)
        _Component.Pro = (PlayerProfression)EditorGUILayout.EnumPopup("玩家职业", _Component.Pro);
        _Component.LoveColor = (PlayerLoveColor)EditorGUILayout.EnumFlagsField("玩家喜欢的颜色", _Component.LoveColor);
        

        //终极数据类型的绘制
        //更新可序列化数据
        serializedObject.Update();
        //通过成员变量名找到组件上的成员变量
        SerializedProperty sp = serializedObject.FindProperty("Items");
        //可序列化数据绘制(取到数据,标题,是否将所有获得序列化的数据显示出来)
        EditorGUILayout.PropertyField(sp, new GUIContent("道具信息"), true);
        //将修改的数据写入到可序列化的原始数据中
        serializedObject.ApplyModifiedProperties();
        
        
        //滑动条的绘制
        //滑动条显示(1.标题2.原始变量3.最小值,4.最大值)
        _Component.Atk = EditorGUILayout.Slider(new GUIContent("玩家攻击力"), _Component.Atk, 0, 100);
        if (_Component.Atk > 80)
        {
            //显示消息红框
            EditorGUILayout.HelpBox("攻击力太高了", MessageType.Error);
        }
        if (_Component.Atk < 20)
        {
            //显示消息黄框
            EditorGUILayout.HelpBox("攻击力太低了", MessageType.Warning);
        }

        //按钮显示和元素排列
        //(按钮是否被按下)显示按钮(按钮名称)
        GUILayout.Button("来个按钮");
        GUILayout.Button("来个按钮");

        //开始横向排列绘制
        EditorGUILayout.BeginHorizontal();

        GUILayout.Button("再来个按钮");
        GUILayout.Button("再来个按钮");

        //结束横向排列绘制
        EditorGUILayout.EndHorizontal();


        if(GUILayout.Button("测试点击"))
        {
            Debug.Log("测试点击");
        }
    }
}
菜单栏上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class Menu : Editor
{
    [MenuItem("工具/导出AB资源包")]
    private static void BuildAb()
    {
        //Debug.Log("导出AB包");
        Debug.Log(Application.persistentDataPath);
    }
}


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

public class PopupWindow : EditorWindow
{
    [MenuItem("工具/创建窗口")] 
    static void OpenWindow()
    {
       PopupWindow window= GetWindow<PopupWindow>(false, "弹窗", true);
        window.minSize=new Vector2(400,300);
        window.maxSize=new Vector2 (800,600);
    }

    //开窗口调用
    private void OnEnable()
    {
        Debug.Log("onenble");
    }

    //关窗口调用
    private void OnDisable()
    {
        Debug.Log("ondisenble");

    }

    //窗口开启调用
    private void Update()
    {
        Debug.Log("update");

    }

    private void OnGUI()
    {
        if(GUILayout.Button("测试点击"))
        {
            Debug.Log("测试点击");
        }
    }

    //场景结构发生变化执行回调函数
    private void OnHierarchyChange()
    {
        Debug.Log("hierarchy");
    }

    //项目结构发生变化执行回调函数
    private void OnProjectChange()
    {
        Debug.Log("Project");
    }
    //选中物体发生变化执行回调函数
    private void OnSelectionChange()
    {
        //获取当前选中的物体的名称
        Debug.Log(Selection.activeGameObject.name);
    }
}
编辑器工具制作

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

[ExecuteInEditMode]//在编辑模式下可以执行一些生命周期函数
public class NodeManage : MonoBehaviour
{
    
    //储存了所有编辑器下的节点,并使用预制体显示
    public List<GameObject> nodes;

    private void Start()
    {
        nodes=new List<GameObject>();
    }

    private void Update()
    {
        
        for (int i = 0; i < nodes.Count-1; i++)
        {
            Debug.DrawLine(nodes[i].transform.position,
                nodes[i+1].transform.position,
                Color.red,Time.deltaTime);
        }
    }
}



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

public class NodeWindow : EditorWindow
{
    private static NodeWindow window;
    private static GameObject nodeManager;

    public static void OpenWindow(GameObject manager)
    {
        nodeManager = manager;
        //真正开启一个窗口
        window = GetWindow<NodeWindow>();
    }
    

    private void Update()
    {
        //通过窗口的update每帧执行一次,当前被选中的对象为板子
        Selection.activeGameObject = nodeManager;
    }

    public static void CloseWindow()
    {
        window.Close();
    }
    
}


[CustomEditor(typeof(NodeManage))]
public class NodeManageEditor : Editor
{
    private NodeManage _nodeManage;

    private bool isEditor;
    //当选中带有nodemanage组建的时候 获得组件
    private void OnEnable()
    {
        _nodeManage = (NodeManage) target;
    }
    //绘制组件的生命周期函数
    public override void OnInspectorGUI()
    {
        //通过终极数据获取方法,显示列表中的数据
        serializedObject.Update();
        SerializedProperty nodes = serializedObject.FindProperty("nodes");
        EditorGUILayout.PropertyField(nodes, new GUIContent("路径"), true);
        serializedObject.ApplyModifiedProperties();
        //开始编辑的开关
        if (!isEditor&&GUILayout.Button("开始编辑"))
        {
            NodeWindow.OpenWindow(_nodeManage.gameObject);
            isEditor = true;
        }
        //结束编辑的开关
        else if (isEditor&&GUILayout.Button("结束编辑"))
        {
            NodeWindow.CloseWindow();
            isEditor = false;
        }
           
        if (GUILayout.Button("删除最后一个节点"))
        {
            RemoveAtLast();
        }
        else if (GUILayout.Button("删除所有节点"))
        {
            RemoveAll();
        }
        
    }

   

    private RaycastHit _hit;
    //当选中关联的脚本挂载的物体
    //当鼠标再scene视图下发生变化时,执行该方法,比如鼠标的移动,鼠标的点击
    //有点类似update函数,发送射线
    private void OnSceneGUI()
    {
        //非编辑状态下不能生成路点
        if (!isEditor)
        {
            return;
        }
        //当鼠标按下左键时发射一个射线
        //非运行的时候,使用event类
        //Event.current.button 判断鼠标是哪个按键的
        //Event.current.type  判断鼠标的事件方式的

        if (Event.current.button==0&&Event.current.type==EventType.MouseDown)
        {
            //从鼠标的位置需要发射线
            //因为是scene视图下发射的射线,跟场景中的摄像机并没关系,所以不能使用相机发射射线
            //从编辑器GUI的一个点向世界定义一条射线,参数一般都死鼠标的坐标
            Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            if (Physics.Raycast(ray,out _hit,100))
            {
                Debug.Log("213");
                //需要检测到的点实例化,路点
                InstancePathbNode(_hit.point + Vector3.up*0.1f);
            }
        }
    }

    //生成节点
    void InstancePathbNode(Vector3 position)
    {
        //点预制体
        GameObject prefab = Resources.Load<GameObject>("PathNode");
        //点对象生成到plane的子物体下
        GameObject pathNode = Instantiate(prefab, position, prefab.transform.rotation,
            _nodeManage.transform);
        //把生成的点放在路径里
        _nodeManage.nodes.Add(pathNode);
    }
    
    private void RemoveAtLast()
    {
        if (_nodeManage.nodes.Count>0)
        {
            //场景中删除游戏物体
            DestroyImmediate(_nodeManage.nodes[_nodeManage.nodes.Count-1]);
            //并把该节点从列表中删除
            _nodeManage.nodes.RemoveAt(_nodeManage.nodes.Count - 1);
        }
    }

    private void RemoveAll()
    {
        //场景中删除游戏物体
        foreach (var item in _nodeManage.nodes)
        {
            DestroyImmediate(item);
        }
        
        //并把该节点从列表中删除
        _nodeManage.nodes.Clear();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值