碧血红天的HomePage

U3d杂谈 — 使用GraphView做工具–03

前面,我们能够成功的创建出节点,然后通过Port的连接正常的执行。但是前面说过,目前这种粗暴的连接和如此简单的处理方式是存在问题的。比如输入值来自于兄弟节点。为了解决这样的问题,我这里实现了了一个方式。

我们需要把我们的MyBaseNode重新泛化出2种新的类型,一种是处理节点,一种是参数节点。

处理节点

我姑且命名味处理节点吧,这个节点的特点就是节点存在父子关系,一个节点只能有一个父节点,也能力连接一个子节点。这样的做法就行程序的执行是一行一行的。我们不存在并行代码执行的情况,我们通过节点的父子关系来约束这种执行方式。

处理节点的处理之前,会遍历自己的输入端口列表,判断端口连接的是处理节点还是参数节点,处理节点的话,我们就不需要再执行父节点的执行方法了,因为我们需要保证父节点执行完成后,需要把输出Port连接的节点的Port的数据设置好。如果是参数节点,我们需要重新执行参数节点的处理方法,因为参数节点往往是一些Get方法,在不同的节点期,变量的值会发生改变,所以需要实时计算,计算完成后,一样把输出Port连接的节点的Port的值设置好,这样就能递归的从上到下执行下来了。

参数节点

参数节点最大的区别是没有父子节点的顺序,往往一般是一些不改变程序内存,Get方法采用的节点类型。它能够通过当前执行道哪个节点需要使用参数的时候才会执行,不会影响节点执行的顺序流程。它通过直接点反向通过Port的连接执行上去。

修改内容

我们需要在把MyBaseNode 进行修改如下,添加一个Compute方法,从方法变成内部逻辑的计算,然后设置输出Port和连接输出Port的值。

using UnityEditor.Experimental.GraphView;
using UnityEngine.UIElements;

public class MyBaseNode : Node
{
    public int id;
    public MyBaseNode()
    {
        id = GetHashCode();
    }
    //处理节点计算
    public virtual void OnExecute()
    {
        
    }

    protected virtual void Compute()
    {
        //内部值得计算,同时把值通过输出端口设置连接得端口值

    }

    public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
    {
        evt.menu.InsertAction(0, "执行", OnExcMenu);
    }

    private void OnExcMenu(DropdownMenuAction a)
    {
        OnExecute();
    }
}

添加ProcessBaseNode节点类

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

public class ProcessBaseNode : MyBaseNode
{
    private Port ParentNode;
    private Port ChildNode;

    public ProcessBaseNode():base()
    {
        ParentNode = Port.Create<Edge>(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(ProcessBaseNode));
        ParentNode.portName = "父节点";
        ParentNode.source = null;

        ChildNode = Port.Create<Edge>(Orientation.Horizontal, Direction.Output, Port.Capacity.Single, typeof(ProcessBaseNode));
        ChildNode.portName = "子节点";
        ChildNode.source = null;

        inputContainer.Add(ParentNode);
        outputContainer.Add(ChildNode);
    }

    public override void OnExecute()
    {
        int count = inputContainer.childCount - 1;
        for (int i = 0; i < count; ++i)
        {
            if (inputContainer.ElementAt(i) is Port && inputContainer.ElementAt(i) != ParentNode)
            {
                Port p = inputContainer.ElementAt(i) as Port;
                foreach(var e in  p.connections)
                {
                    if(e.output.node is ProcessBaseNode)
                    {
                        //如果是处理节点,就不管参数,直接由父节点执行的时候把直接点的Port设置好
                        continue;
                    }else
                    {
                        //如果事参数节点,每次执行都再计算参数的实时值
                        MyBaseNode n = e.output.node as MyBaseNode;
                        n.OnExecute();
                    }
                }
            }
        }

        //对应的节点需要实现
        Compute();

        //执行完成,开始执行下面子节点
        foreach (var e in ChildNode.connections)
        {
            ProcessBaseNode node = e.input.node as ProcessBaseNode;
            node.OnExecute();
        }
    }

}

添加参数节点

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

public class ParamBaseNode : MyBaseNode
{
    public ParamBaseNode() : base()
    {

    }

    public override void OnExecute()
    {
        int count = inputContainer.childCount - 1;
        for (int i = 0; i < count; ++i)
        {
            if (inputContainer.ElementAt(i) is Port)
            {
                Port p = inputContainer.ElementAt(i) as Port;
                foreach (var e in p.connections)
                {
                    if (e.output.node is ProcessBaseNode)
                    {
                        //如果事处理节点,就不管参数,直接由父节点执行的时候把直接点的Port设置好
                        continue;
                    }
                    else
                    {
                        //如果事参数节点,每次执行都再计算参数的实时值
                        MyBaseNode n = e.output.node as MyBaseNode;
                        n.OnExecute();
                    }
                }
            }
        }

        //对应的节点需要实现
        Compute();
    }
}

然后我们对前面添加的2个节点进行改造

using UnityEditor.Experimental.GraphView;
using UnityEngine.UIElements;

public class AddIntNode : ProcessBaseNode
{
    private TextField Param1;
    private TextField Param2;

    private Port Result;
    public AddIntNode() : base()
    {
        title = "Int加";
        Param1 = new TextField("参数1:");
        Param1.RegisterValueChangedCallback(OnParam1ValueChange);
        Param1.value = "0";

        Param2 = new TextField("参数2:");
        Param2.RegisterValueChangedCallback(OnParam2ValueChange);
        Param2.value = "0";

        Result = Port.Create<Edge>(Orientation.Horizontal, Direction.Output, Port.Capacity.Multi, typeof(int));
        Result.portName = "结果";
        Result.source = 0;

        inputContainer.Add(Param1);
        inputContainer.Add(Param2);

        outputContainer.Add(Result);
    }

    private void OnParam1ValueChange(ChangeEvent<string> e)
    {
        int r = 0;
        if(int.TryParse(e.newValue,out r))
        {
            string s = string.Format("{0}", r);
            Param1.value = s;
        }
        else
        {
            Param1.value = "0";
        }      
    }

    private void OnParam2ValueChange(ChangeEvent<string> e)
    {
        int r = 0;
        if (int.TryParse(e.newValue, out r))
        {
            string s = string.Format("{0}", r);
            Param2.value = s;
        }
        else
        {
            Param2.value = "0";
        }
    }

    protected override void Compute()
    {
        Result.source = int.Parse(Param2.value) + int.Parse(Param2.value);
        foreach(var e in Result.connections)
        {
            e.input.source = Result.source;
        }
        base.Compute();
    }
}

我们需要实现Compute方法,内部计算处理完,然后把输出Port的值设置起。

using UnityEditor.Experimental.GraphView;
using UnityEngine;

public class LogNode : ProcessBaseNode
{
    private Port LogText;
    public LogNode():base()
    {
        title = "Log打印";

        LogText = Port.Create<Edge>(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(object));
        LogText.portName = "输出文本";
        LogText.source = 0;

        inputContainer.Add(LogText);
    }

    protected override void Compute()
    {
        Debug.Log(LogText.source);
        base.Compute();
    }
}

好了,现在试试,可以看见执行的效果跟之前一样。下面我们修改下EditorWindow,把整个Window分成2半,左边是节点列表,右边是GraphView窗口,然后通过反射机制来自动识别我们添加的节点,然后填充道列表中。

36 评论

  1. I believe other website owners should take this site as an model, very clean and superb user pleasant design.

  2. Aw, this was a very nice post. In thought I would like to put in writing like this moreover – taking time and actual effort to make a very good article… however what can I say… I procrastinate alot and under no circumstances appear to get one thing done.

  3. buy stromectol 12mg TNC can also induce the secretion of growth factors, like EGF or FGF, and interact with fibronectin, heparin sulfate proteoglycans, fibrinogen, integrins, MMPs, and EGFR 164

  4. Scott RmQMYOhIYSaOlT 6 27 2022 clomid online Here the clinical trials assistant expresses discomfort about the quality and implications of her participation and seeks reassurance from the researcher, further demonstrating a limit on participation we encountered across our research with practitioners and patients, but also troubling the identity of the researcher and challenging us to acknowledge the burdens we generate when we ask clinicians to facilitate our research

  5. They may also cause palpitations and irregular heart rhythms buy 5mg propecia in the uk The non survivors n 42 had higher APACHE II score 23

  6. Thanx for the effort, keep up the good work Great work, I am going to start a small Blog Engine course work using your site I hope you enjoy blogging with the popular BlogEngine.net.Thethoughts you express are really awesome. Hope you will right some more posts.

  7. You are my inhalation, I possess few web logs and often run out from to brand : (.

  8. I believe you have noted some very interesting points, thanks for the post.

  9. Hi my friend! I wish to say that this article is awesome, nice written and include almost all vital infos. I would like to see more posts like this.

  10. I think other web-site proprietors should take this website as an model, very clean and great user friendly style and design, let alone the content. You’re an expert in this topic!

  11. It¦s actually a nice and useful piece of information. I am glad that you shared this useful info with us. Please stay us informed like this. Thanks for sharing.

  12. I’ve been browsing online more than three hours today, yet I never found any interesting article like yours. It is pretty worth enough for me. Personally, if all webmasters and bloggers made good content as you did, the web will be a lot more useful than ever before.

  13. I like what you guys are up too. Such smart work and reporting! Carry on the excellent works guys I?¦ve incorporated you guys to my blogroll. I think it will improve the value of my website 🙂

  14. Just wanna input that you have a very nice website , I enjoy the design and style it actually stands out.

  15. Some really quality articles on this site, saved to fav.

  16. Thanks a bunch for sharing this with all of us you really know what you are talking about! Bookmarked. Please also visit my website =). We could have a link exchange contract between us!

  17. Utterly indited articles, Really enjoyed reading through.

  18. As soon as I noticed this web site I went on reddit to share some of the love with them.

  19. Great post. I used to be checking continuously this weblog and I’m inspired! Extremely useful info specially the final phase 🙂 I take care of such info much. I was looking for this certain information for a long time. Thank you and best of luck.

  20. Youre so cool! I dont suppose Ive read anything like this before. So nice to find any individual with some original ideas on this subject. realy thanks for starting this up. this web site is one thing that is needed on the net, somebody with a bit originality. helpful job for bringing one thing new to the web!

  21. Hi there just wanted to give you a quick heads up. The text in your content seem to be running off the screen in Opera. I’m not sure if this is a format issue or something to do with web browser compatibility but I thought I’d post to let you know. The style and design look great though! Hope you get the issue resolved soon. Kudos

  22. Great write-up, I¦m normal visitor of one¦s website, maintain up the excellent operate, and It’s going to be a regular visitor for a lengthy time.

  23. Its excellent as your other posts : D, thankyou for posting.

  24. Greetings! Very helpful advice on this article! It is the little changes that make the biggest changes. Thanks a lot for sharing!

  25. Hello. magnificent job. I did not expect this. This is a great story. Thanks!

  26. cialis without prescription When aqueous suspensions and or elixirs are desired for oral administration, the active ingredient may be combined with various sweetening or flavoring agents, coloring matter or dyes, and, if so desired, emulsifying and or suspending agents as well, together with such diluents as water, ethanol, propylene glycol, glycerin and various like combinations thereof

  27. Minimally invasive treatment of complicated parapneumonic effusions and empyemas in adults how to order clomid on line in canada

  28. The incremental cost per QALY gained with letrozole is 28 728 tamoxifen nolvadex

  29. cialis no prescription In summary, these data highlight HIF О± driven epigenetic silencing of FXN following exposure to hypoxia in vitro and suggest a shared mechanism in multiple PH subtypes

  30. Bwin предлага голямо разнообразие от онлайн покер игри и турнири. Освен че имат ежедневни игри с кеш маси и над 1 милион долара месечно награди в различни турнири, те предлагат възнаграждаващи игри в покер мисия, които ще помогнат на играчите да спечелят повече пари, като същевременно подобряват уменията си в онлайн покер. Благодарение на поддръжката на Биткойн и системата за бърз депозит и теглене, получаването на печалбите от BetOnline едва ли ще бъде по-лесно. И, разбира се, покерът не е всичко, за което е полезно това онлайн казино. Можете също да използвате BetOnline, за да опитате ръката си в други традиционни казино игри или спортни залагания. https://remingtonxpds764310.ja-blog.com/14804489/вид-игра-със-залагания Гарантирано безопасно напускане Внимание: Последни наличности! 【В индивидуална опаковка】 Всеки спринцовка индивидуално запечатани, чист, перфектен за зареждане с го АКТУАЛИЗИРАНЕ НА ИНФОРМАЦИЯТА Няма продукти Калъф за игрална карта в акрил, моля, свържете се с нас, ако има нужда Всички Права Запазени.Easy-Stock.cam Powered by Prestashop. идеално всички може да съдържа покер чипове 100 *задължителни полета 25 бр./лот EPT керамични тексас покер чипове професионални казино европейските покер чипове набор от 39*3.3 mm 10 g

发表评论