/// <summary>
 /// 运行对话资源,会等待所有对话结束才会开始
 /// </summary>
 /// <param name="info"></param>
 /// <param name="callBack"></param>
 /// <returns></returns>
 public static IEnumerator RunDialogAwait(AbstractDialogInfoAsset info, Action callBack = null)
 {
     while (stackSize != 0)
     {
         yield return(null);
     }
     yield return(RunDialog(info, callBack));
 }
        private static int FindUnitFromIndex(AbstractDialogInfoAsset asset, int index, UnitType type)
        {
            bool skip = false || (type == UnitType.Else || type == UnitType.EndIf);

            int ifCount = 0;

            var DialogUnits = asset.DialogUnits;

            for (var i = index + 1; i < DialogUnits.Count; i++)
            {
                if (skip && DialogUnits[i].UnitType == UnitType.If)
                {
                    //                    print("执行ifCount++");
                    ifCount++;
                }

                if (DialogUnits[i].UnitType == type)
                {
                    if (skip)
                    {
                        if (ifCount <= 0)
                        {
                            return(i);
                        }
                        else
                        {
                            ifCount--;
                        }
                    }
                    else
                    {
                        return(i);
                    }
                }
            }

            return(-1);
        }
Example #3
0
        private void OnEnable()
        {
            this._abstractDialogInfoAsset = target as AbstractDialogInfoAsset;

            this.wordFinishTimeProp = serializedObject.FindProperty("wordFinishTime");
            this.refreshProp        = serializedObject.FindProperty("refreshStringChooser");
            this.affectedByTimeProp = serializedObject.FindProperty("affectedByTimeScale");
            this.canPlayerMoveProp  = serializedObject.FindProperty("canMoveOnTalking");


            #region DialogUnitList

            foreach (var VARIABLE in _abstractDialogInfoAsset.DialogUnits)
            {
                if (VARIABLE.abstractAbstractDialogInfoAsset == null)
                {
                    VARIABLE.abstractAbstractDialogInfoAsset = _abstractDialogInfoAsset;
                }
            }

            dialogUnitListProp = serializedObject.FindProperty("DialogUnits");


            dialogUnitList = new ReorderableList(serializedObject, dialogUnitListProp, true, true, true, true)
            {
                elementHeight = 2 * EditorGUIUtility.singleLineHeight
            };


            //绘制单个元素
            dialogUnitList.drawElementCallback =
                (rect, index, isActive, isFocused) =>
            {
                var dialogUnit = dialogUnitListProp.GetArrayElementAtIndex(index);
                var type       = _abstractDialogInfoAsset.DialogUnits[index];

                EditorGUI.PropertyField(rect.GetRight(1 - _abstractDialogInfoAsset.GetIntOffset(index) * offset), dialogUnit);
            };

            //背景色
            dialogUnitList.drawElementBackgroundCallback = (rect, index, isActive, isFocused) =>
            {
                GUI.backgroundColor = isFocused ? new Color(1f, 1f, 0.05f) : Color.white;
            };

            dialogUnitList.onSelectCallback = (list) => { this.selectIndex = list.index; };

            dialogUnitList.onAddDropdownCallback = (rect, list) =>
            {
                var menu      = new GenericMenu();
                var enumIndex = -1;
                foreach (var value in EnumUtil.GetValues <UnitType>())
                {
                    enumIndex++;
                    if ((UnitType)value == UnitType.Panel && _abstractDialogInfoAsset.PanelType == null)
                    {
                        continue;
                    }
                    if ((UnitType)value == UnitType.Scene && _abstractDialogInfoAsset.SceneType == null)
                    {
                        continue;
                    }
                    if ((UnitType)value == UnitType.Message && _abstractDialogInfoAsset.MessageType == null)
                    {
                        continue;
                    }
                    if ((UnitType)value == UnitType.Audio && _abstractDialogInfoAsset.AudioType == null)
                    {
                        continue;
                    }

                    var itemName = "";
                    if (value >= 10 && value < 20)
                    {
                        itemName += "Dialog/";
                    }
                    else if (value >= 20 && value < 30)
                    {
                        itemName += "Logic/";
                    }
                    else if (value >= 40 && value < 50)
                    {
                        itemName += "Game/";
                    }
                    else if (value >= 60 && value < 70)
                    {
                        itemName += "Var/";
                    }
                    else if (value >= 50 && value < 60)
                    {
                        itemName += "Trigger/";
                    }
                    else if (value >= 30 && value < 40)
                    {
                        itemName += "Effect/";
                    }
                    else if (value >= 80 && value < 90)
                    {
                        itemName += "Debug/";
                    }

                    menu.AddItem(new GUIContent(itemName + (UnitType)value), false, OnAddUnitCallBack, enumIndex);
                }

                menu.ShowAsContext();
            };

            //头部
            dialogUnitList.drawHeaderCallback = (rect) =>
                                                EditorGUI.LabelField(rect, dialogUnitListProp.displayName);

            #endregion
        }
        /// <summary>
        /// 运行DialogInfoAsset资源
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public static IEnumerator RunDialog(AbstractDialogInfoAsset info, Action endCall = null)
        {
            #region 对话开始事件


            if (!IsRunningAll && stackSize == 0)
            {
                onStartDialog?.Invoke();
            }
            if (DialogSettings.Instance.ShowDialogStackInfo)
            {
                var text = "对话开始-";
                for (var i = 0; i < stackSize; i++)
                {
                    text += "-";
                }
                print(text + info.name);
            }


            #endregion



            stackSize++;

            var DialogUnits = info.DialogUnits;

            var ifConditions = new Stack <bool>();
            var ifTrue       = false;

            var currentIndex = 0;

            if (!info.canMoveOnTalking)
            {
                info.SetPlayerMovable(false);
            }



            while (currentIndex < DialogUnits.Count)
            {
                var dialogUnitInfo = DialogUnits[currentIndex];

//                Debug.Log(dialogUnitInfo.UnitType);
//                Debug.Log(info.name+":"+ dialogUnitInfo.id);

                switch (dialogUnitInfo.UnitType)
                {
                case UnitType.Word:
//                        Debug.Log("DialogSystem_RunDialog_Switch_UnitType.Word_Start");
                    yield return(dialogUnitInfo.RunWordUnit());

//                        Debug.Log("DialogSystem_RunDialog_Switch_UnitType.Word_end");
                    break;

                case UnitType.Choose:
                    yield return(dialogUnitInfo.RunChooseUnit());

                    if (GetAssetMessage(ChooseNotBack, info.name))
                    {
                        endCall?.Invoke();
                        EndRunningDialog("End by ChooseNotBack", info.name);
                        yield break;
                    }
                    break;

                case UnitType.Narrator:
                    yield return(dialogUnitInfo.RunNarratorUnit());

                    break;

                case UnitType.ExWord:
                    yield return(dialogUnitInfo.RunExWordUnit());

                    break;


                case UnitType.If:

                    ifTrue = dialogUnitInfo.Complare();
                    ifConditions.Push(ifTrue);


                    if (!ifTrue)    //如果不满足IF条件,IF到Else或者EndIF之间不执行
                    {
                        //寻找Else
                        var id = FindUnitFromIndex(info, currentIndex, UnitType.Else);
                        if (id != -1)
                        {
                            //找到Else
                            currentIndex = id - 1;
                        }
                        else    //没找到Else,查找EndIF
                        {
                            id = FindUnitFromIndex(info, currentIndex, UnitType.EndIf);

                            if (-1 == id)
                            {
                                endCall?.Invoke();
                                EndRunningDialog("End by 在IF处, if 条件不满足,同时没有EndIf", info.name);
                                yield break;
                            }
                            else
                            {
                                //找到EndIf
                                currentIndex = id - 1;
                            }
                        }
                    }

                    break;

                case UnitType.Else:

                    if (ifConditions.Peek())    //如果满足条件,Else到EndIF不执行
                    {
                        //寻找下一个EndIF
                        var id = FindUnitFromIndex(info, currentIndex, UnitType.EndIf);
                        if (-1 == id)
                        {
                            //没找到
                            endCall?.Invoke();
                            EndRunningDialog("End by 在Else处, if 条件满足,同时没有EndIf", info.name);
                            yield break;
                        }
                        else
                        {
                            //找到了
                            currentIndex = id - 1;
                        }
                    }

                    break;

                case UnitType.EndIf:
                    ifConditions.Pop();
                    break;

                case UnitType.Message:
                    dialogUnitInfo.RunMessageUnit();
                    break;

                case UnitType.SetVar:
                    dialogUnitInfo.RunSetVarUnit();
                    break;

                case UnitType.End:
                    endCall?.Invoke();
                    EndRunningDialog("End By UnitType.End", info.name);
                    yield break;

                case UnitType.Skip:
                    currentIndex += dialogUnitInfo.skipNum;
                    break;

                case UnitType.Event:
                    dialogUnitInfo.RunEventUnit();
                    break;

                case UnitType.Print:
                    dialogUnitInfo.RunPrintUnit();
                    break;

                case UnitType.VarInfo:
                    dialogUnitInfo.ShowVarInfo();
                    break;

                case UnitType.Wait:
                    yield return(dialogUnitInfo.WaitForTime());

                    break;

                case UnitType.Jump:
                    yield return(dialogUnitInfo.RunJumpUnit());

                    if (GetAssetMessage(ChooseNotBack, info.name))
                    {
                        endCall?.Invoke();
                        EndRunningDialog("End by JumpNotBack", info.name);
                        yield break;
                    }

                    break;

                case UnitType.Shining:
                    yield return(dialogUnitInfo.Shining());

                    break;

                case UnitType.FadeIn:
                    yield return(dialogUnitInfo.FadeIn());

                    break;

                case UnitType.FadeOut:
                    yield return(dialogUnitInfo.FadeOut());

                    break;

                case UnitType.Audio:
                    dialogUnitInfo.RunAudio();
                    break;

                case UnitType.Panel:
//                        Debug.Log("DialogSystem_RunDialog_Switch_UnitType_Panel");
                    dialogUnitInfo.RunPanelUnit();
                    break;

                case UnitType.Scene:
                    yield return(dialogUnitInfo.RunSceneUnit());

//                        Debug.Log("DialogSystem_RunDialog_Switch_UnitType.Scene_end");
                    break;

                case UnitType.Progress:
                    dialogUnitInfo.RunProgressUnit();
                    break;

                case UnitType.ProcessInfo:
                    dialogUnitInfo.RunProgressInfoUnit();
                    break;

                case UnitType.Camera:
                    yield return(dialogUnitInfo.RunCameraUnit());

                    break;
                }

                currentIndex++;
            }

            if (!info.canMoveOnTalking)
            {
                info.SetPlayerMovable(true);
            }
            endCall?.Invoke();
            EndRunningDialog("End by normalEnd", info.name);
        }
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            _abstractDialogSystem = property.FindPropertyRelative("abstractAbstractDialogInfoAsset").objectReferenceValue as AbstractDialogInfoAsset;

            if (_abstractDialogSystem == null)
            {
                throw new Exception("abstractAbstractDialogInfoAsset is null");
            }

            indexProp = property.FindPropertyRelative("selectedIndex");

            var valueTypeProp = property.FindPropertyRelative("valueType");

            valueTypeProp.enumValueIndex = EditorGUI.Popup(position.GetLeft(ValueChooser.valueTypeWidth),
                                                           valueTypeProp.enumValueIndex, valueTypeProp.enumNames);

            if (valueTypeProp.enumValueIndex == 0) // Value
            {
                ArgChooser.argTypeWidth  = ValueChooser.argTypeWidth / (1 - ValueChooser.valueTypeWidth);
                ArgChooser.typeChangAble = true;

                EditorGUI.PropertyField(position.GetRight(1 - ValueChooser.valueTypeWidth),
                                        property.FindPropertyRelative("ArgChooser"));
            }
            else // Var
            {
                var argType = property.FindPropertyRelative("argType");

                argType.enumValueIndex =
                    EditorGUI.Popup(position.GetLeft(ValueChooser.valueTypeWidth + ValueChooser.argTypeWidth, ValueChooser.valueTypeWidth),
                                    argType.enumValueIndex, argType.enumNames);


                Dictionary <string, string> ans = null;
                switch (argType.enumValueIndex)
                {
                case 0:     // Int
                    ans = _abstractDialogSystem.GetValueStrings(ArgType.Int);

                    if (ans.Count == 0)
                    {
                        break;
                    }
                    indexProp.intValue = EditorGUI.Popup(position.GetRight(ArgValueWidth), indexProp.intValue,
                                                         ans.Keys.ToArray());
                    break;

                case 1:     // Float
                    ans = _abstractDialogSystem.GetValueStrings(ArgType.Float);
                    if (ans.Count == 0)
                    {
                        break;
                    }
                    indexProp.intValue = EditorGUI.Popup(position.GetRight(ArgValueWidth), indexProp.intValue,
                                                         ans.Keys.ToArray());
                    break;

                case 2:     // String
                    ans = _abstractDialogSystem.GetValueStrings(ArgType.String);
                    if (ans.Count == 0)
                    {
                        //property.FindPropertyRelative("StrArg").stringValue = "";
                        break;
                    }
                    indexProp.intValue = EditorGUI.Popup(position.GetRight(ArgValueWidth), indexProp.intValue,
                                                         ans.Keys.ToArray());
                    break;

                case 3:     // bool
                    ans = _abstractDialogSystem.GetValueStrings(ArgType.Bool);
                    if (ans.Count == 0)
                    {
                        break;
                    }
                    indexProp.intValue = EditorGUI.Popup(position.GetRight(ArgValueWidth), indexProp.intValue,
                                                         ans.Keys.ToArray());
                    break;
                }
            }
        }