Exemple #1
0
        public void Init(BehaviourTree tree)
        {
            if (!IsInstance)
            {
                Debug.LogError("尝试初始化未实例化的结点: " + name);
                return;
            }
            Tree = tree;
            foreach (var field in GetType().GetFields(ZetanUtility.CommonBindingFlags).Where(field => field.FieldType.IsSubclassOf(typeof(SharedVariable))))
            {
                var hideAttr = field.GetCustomAttribute <HideIf_BTAttribute>();
                if (hideAttr != null && ZetanUtility.TryGetMemberValue(hideAttr.path, this, out var value, out _) && Equals(value, hideAttr.value))
                {
                    continue;
                }
                SharedVariable variable = field.GetValue(this) as SharedVariable;
                //if (variable.isShared) field.SetValue(this, this.owner.GetVariable(variable.name));
                //else if (variable.isGlobal) field.SetValue(this, BehaviourManager.Instance.GetVariable(variable.name));
                if (variable.isShared)
                {
                    variable.Link(Tree.GetVariable(variable.name));
                }
                else if (variable.isGlobal)
                {
                    variable.Link(BehaviourManager.Instance.GetVariable(variable.name));
                }
            }
            Shortcut = new NodeShortcut(Tree.Executor);
            OnAwake();
#if false
            void TryLinkSharedVariable(object onwer, FieldInfo field)
            {
                if (field.FieldType.IsSubclassOf(typeof(SharedVariable)))
                {
                    SharedVariable variable = field.GetValue(onwer) as SharedVariable;
                    field.SetValue(this, this.owner.GetVariable(variable.name));
                }
                else if (field.FieldType.IsArray)//因为Unity只能显示数组和列表,只对这两种特殊情况特殊处理
                {
                    var array = field.GetValue(owner) as SharedVariable[];
                    if (array.Length < 1)
                    {
                        return;
                    }
                    bool typeMatch  = false;
                    var  eType      = array[0].GetType();
                    var  fieldInfos = eType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                    if (eType.IsSubclassOf(typeof(SharedVariable)))
                    {
                        typeMatch = true;
                    }
                    for (int i = 0; i < array.Length; i++)
                    {
                        if (typeMatch)
                        {
                            array[i] = this.owner.GetVariable(array[i].name);
                        }
                        else
                        {
                            foreach (var _field in fieldInfos)
                            {
                                TryLinkSharedVariable(array[i], _field);
                            }
                        }
                    }
                }
                else if (typeof(IList).IsAssignableFrom(field.FieldType))
                {
                    var list = field.GetValue(owner) as IList;
                    if (list.Count < 1)
                    {
                        return;
                    }
                    bool typeMatch  = false;
                    var  eType      = list[0].GetType();
                    var  fieldInfos = eType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                    if (eType.IsSubclassOf(typeof(SharedVariable)))
                    {
                        typeMatch = true;
                    }
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (typeMatch)
                        {
                            list[i] = this.owner.GetVariable((list[i] as SharedVariable).name);
                        }
                        else
                        {
                            foreach (var _field in fieldInfos)
                            {
                                TryLinkSharedVariable(list[i], _field);
                            }
                        }
                    }
                }
            }
#endif
        }
Exemple #2
0
 public void InspectNode(BehaviourTree tree, NodeEditor node)
 {
     Clear();
     if (serializedObject != null)
     {
         serializedObject.Dispose();
     }
     this.tree = tree;
     if (!tree.IsInstance)
     {
         global = ZetanUtility.Editor.LoadAsset <GlobalVariables>();
     }
     else
     {
         global = BehaviourManager.Instance.GlobalVariables;
     }
     nodeEditor = node;
     if (tree && nodeEditor != null && nodeEditor.node)
     {
         serializedObject = new SerializedObject(tree);
         SerializedProperty nodes     = serializedObject.FindProperty("nodes");
         IMGUIContainer     container = new IMGUIContainer(() =>
         {
             if (tree && nodeEditor != null && nodeEditor.node)
             {
                 serializedObject.UpdateIfRequiredOrScript();
                 EditorGUI.BeginChangeCheck();
                 EditorGUILayout.LabelField($"[结点名称]\t{nodeEditor.node.name}");
                 EditorGUILayout.LabelField($"[优先级]\t{nodeEditor.node.priority}");
                 var nType     = nodeEditor.node.GetType();
                 var fields    = new HashSet <string>(nType.GetFields(ZetanUtility.CommonBindingFlags).Select(f => f.Name));
                 var fieldsMap = new HashSet <string>();
                 using (SerializedProperty property = nodes.GetArrayElementAtIndex(tree.Nodes.IndexOf(nodeEditor.node)))
                 {
                     using var end = property.GetEndProperty();
                     property.Next(true);
                     while (property.NextVisible(false) && !SerializedProperty.EqualContents(property, end))
                     {
                         string field = property.name;
                         if (field == "name" || field == "priority" || field == "child" || field == "children" || field == "start" ||
                             field == "isRuntime" || field == "isShared" || field == "isGlobal")
                         {
                             continue;
                         }
                         if (fields.Contains(field))
                         {
                             if (fieldsMap.Contains(field))
                             {
                                 break;
                             }
                             fieldsMap.Add(field);
                             var fInfo = nType.GetField(field, ZetanUtility.CommonBindingFlags);
                             DrawProperty(property, fInfo);
                         }
                     }
                 }
                 if (EditorGUI.EndChangeCheck())
                 {
                     serializedObject.ApplyModifiedProperties();
                 }
             }
         });
         Add(container);
     }
 }
Exemple #3
0
        public override void OnInspectorGUI()
        {
            if (target is RuntimeBehaviourExecutor exe)
            {
                if (PrefabUtility.IsPartOfAnyPrefab(exe))
                {
                    EditorGUILayout.HelpBox("不能在预制件使用RuntimeBehaviourExecutor", MessageType.Error);
                    return;
                }
                else
                {
                    EditorGUILayout.HelpBox("只在本场景生效,若要制作预制件,请使用BehaviourExecutor", MessageType.Info);
                }
            }
            serializedObject.UpdateIfRequiredOrScript();
            EditorGUI.BeginChangeCheck();
            var hasTreeBef = behaviour.objectReferenceValue;

            if (target is not RuntimeBehaviourExecutor)
            {
                bool shouldDisable = Application.isPlaying && !PrefabUtility.IsPartOfAnyPrefab(target);
                EditorGUI.BeginDisabledGroup(shouldDisable);
                if (shouldDisable)
                {
                    EditorGUILayout.PropertyField(behaviour, new GUIContent("行为树"));
                }
                else
                {
                    treeDrawer.DoLayoutDraw();
                }
                EditorGUI.EndDisabledGroup();
            }
            if (behaviour.objectReferenceValue != hasTreeBef)
            {
                InitTree();
            }
            if (behaviour.objectReferenceValue)
            {
                if (GUILayout.Button("编辑"))
                {
                    BehaviourTreeEditor.CreateWindow(target as BehaviourExecutor);
                }
                serializedTree.UpdateIfRequiredOrScript();
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.PropertyField(serializedTree.FindProperty("_name"));
                EditorGUILayout.PropertyField(serializedTree.FindProperty("description"));
                if (EditorGUI.EndChangeCheck())
                {
                    serializedTree.ApplyModifiedProperties();
                }
            }
            else
            {
                if (GUILayout.Button("新建"))
                {
                    BehaviourTree tree = ZetanUtility.Editor.SaveFilePanel(CreateInstance <BehaviourTree>, "new behaviour tree");
                    if (tree)
                    {
                        behaviour.objectReferenceValue = tree;
                        InitTree();
                        treeDrawer = new ObjectSelectionDrawer <BehaviourTree>(behaviour, string.Empty, string.Empty, "行为树");
                        EditorApplication.delayCall += delegate { BehaviourTreeEditor.CreateWindow(target as BehaviourExecutor); };
                    }
                }
            }
            EditorGUILayout.PropertyField(frequency, new GUIContent("执行频率"));
            if (frequency.enumValueIndex == (int)BehaviourExecutor.Frequency.FixedTime)
            {
                EditorGUILayout.PropertyField(interval, new GUIContent("间隔(秒)"));
            }
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(startOnStart, new GUIContent("开始时执行"));
            EditorGUILayout.PropertyField(restartOnComplete, new GUIContent("完成时重启"));
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(resetOnRestart, new GUIContent("重启时重置"));
            EditorGUILayout.PropertyField(gizmos, new GUIContent("显示Gizmos"));
            EditorGUILayout.EndHorizontal();
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }
            if (behaviour.objectReferenceValue)
            {
                serializedTree.UpdateIfRequiredOrScript();
                showList.target = EditorGUILayout.Foldout(serializedVariables.isExpanded, "行为树共享变量", true);
                if (EditorGUILayout.BeginFadeGroup(showList.faded))
                {
                    variableList.DoLayoutList();
                }
                EditorGUILayout.EndFadeGroup();
                if (target is not RuntimeBehaviourExecutor && !Application.isPlaying && !ZetanUtility.IsPrefab((target as BehaviourExecutor).gameObject))
                {
                    showPreset.target = EditorGUILayout.Foldout(presetVariables.isExpanded, "变量预设列表", true);
                    if (EditorGUILayout.BeginFadeGroup(showPreset.faded))
                    {
                        presetVariableList.DoLayoutList();
                    }
                    EditorGUILayout.EndFadeGroup();
                }
                serializedTree.ApplyModifiedProperties();
            }
        }