在Unity中创建基于Node节点的编辑器 (二) 窗口序列化

本文作者孙广东分享了在Unity中创建基于Node节点的编辑器系列内容,着重讨论了如何实现窗口序列化。文章指出,XML序列化要求类拥有public字段且具备无参构造函数。
摘要由CSDN通过智能技术生成

孙广东  2018.5.13

csdn 的产品 , 真垃圾, 不想吐槽了, 文章保存就丢!     没办法  。    怎么不满意, 还是得继续用, 哎~~~

第二部分 在Unity中序列化基于节点的编辑器

重温基于节点的编辑器

重温XML序列化
有许多序列化选项,例如JSON或Unity自己的序列化系统。 我们以前已经介绍过XML序列化 我们将使用 XMLOp  类和本文中的一些XML属性。

添加一个菜单栏(添加保存, 加载等按钮)
我们将从添加菜单栏开始,然后从控制台窗口clone中复制它(一起弄的一个 仿Unity Console窗口的脚本):
     private float menuBarHeight = 20f ;
     private Rect menuBar ;

     private void OnGUI ()
     {
         DrawGrid ( 20 , 0.2f , Color . gray );
         DrawGrid ( 100 , 0.4f , Color . gray );
         DrawMenuBar ();
 
         DrawNodes ();
         DrawConnections ();
 
         DrawConnectionLine ( Event . current );
 
         ProcessNodeEvents ( Event . current );
         ProcessEvents ( Event . current );
 
         if ( GUI . changed ) Repaint ();
     }
 
     private void DrawMenuBar ()
     {
         menuBar = new Rect ( 0 , 0 , position . width , menuBarHeight );
 
         GUILayout . BeginArea ( menuBar , EditorStyles . toolbar );
         GUILayout . BeginHorizontal ();
 
         GUILayout . Button ( new GUIContent ( "Save" ), EditorStyles . toolbarButton , GUILayout . Width ( 35 ));
         GUILayout . Space ( 5 );
         GUILayout . Button ( new GUIContent ( "Load" ), EditorStyles . toolbarButton , GUILayout . Width ( 35 ));
 
         GUILayout . EndHorizontal ();
         GUILayout . EndArea ();
     }
在第56行,我们调用 DrawMenuBar()方法,并在第69-82行之间创建菜单栏。控制台窗口克隆有一个 button和6个 toggles,但由于我们只是序列化和反序列化,所以我们不需要两个以上的按钮。请记住,编辑器GUI系统具有绘制顺序,并按照您调用它们的顺序从后向前绘制元素。这就是我们绘制网格后绘制菜单栏的原因。否则,网格将被拖到菜单栏上。

DrawMenuBar() 在 DrawGrid() 之前被调用,因此在菜单栏上有一个丑陋的网格。

目前,保存和加载按钮什么都不做,但我们会做到。

序列化
接下来,我们需要准备我们的类(节点 Node和连接 Connection)进行序列化。让我们记住关于XML序列化的两个重要关键点:

  1. XML序列化程序只能序列化public 字段。
  2. 要序列化的类应该有一个无参数的构造函数。
规则1号不会导致很多问题(它仍然会导致一些问题,但我们会做到这一点),但规则编号2是有问题的。我们的两个类都有带参数的构造函数。首先解决这个问题:
     public Node () { }
    
     public Node ( Vector2 position , float width , float height , GUIStyle nodeStyle , GUIStyle selectedStyle , GUIStyle inPointStyle , GUIStyle outPointStyle , Action < ConnectionPoint > OnClickInPoint , Action < ConnectionPoint > OnClickOutPoint , Action < Node > OnClickRemoveNode )
     {
         rect = new Rect ( position . x , position . y , width , height );
         style = nodeStyle ;
         inPoint = new ConnectionPoint ( this , ConnectionPointType . In , inPointStyle , OnClickInPoint );
         outPoint = new ConnectionPoint ( this , ConnectionPointType . Out , outPointStyle , OnClickOutPoint );
         defaultNodeStyle = nodeStyle ;
         selectedNodeStyle = selectedStyle ;
         OnRemoveNode = OnClickRemoveNode ;
     }

     public Connection () { }
    
     public Connection ( ConnectionPoint inPoint , ConnectionPoint outPoint , Action < Connection > OnClickRemoveConnection )
     {
         this . inPoint = inPoint ;
         this . outPoint = outPoint ;
         this . OnClickRemoveConnection = OnClickRemoveConnection ;
     }

接下来,我们将忽略无法序列化或不需要序列化的属性。 例如,在 Node  类中, GUIStyle 可以不用序列化,因为它们已经由编辑器自己提供。 我们不需要 isDraggedisSelected。 实际上,Node类只有一个需要序列化的属性: rect。 让我们来看看如何正确地忽略不必要和不可序列化的属性后Node类的样子:
public class Node
{
public Rect rect ;
 
[ XmlIgnore ] public string title ;
[ XmlIgnore ] public bool isDragged ;
[ XmlIgnore ] public bool isSelected ;
 
[ XmlIgnore ] public ConnectionPoint inPoint ;
[ XmlIgnore ] public ConnectionPoint outPoint ;
 
[ XmlIgnore ] public GUIStyle style ;
[ XmlIgnore ] public
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值