Example #1
0
    /// <summary>
    /// 添加新的异常状态(其实这么写是有问题的,因为使用的是会变化的本次攻击的数据,而不是对象身上的常量数据 )
    /// </summary>
    /// <param name="statusData"></param>
    private void AddNewStatus(StatusDataInfo.StatusLevelDataInfo statusData)
    {
        //不存在测创建
        GameObject createBuffStateObj = GameObject.Instantiate <GameObject>(BuffPrefab);
        Transform  childTrans         = createBuffStateObj.transform.GetChild(0);
        Image      timeImage          = childTrans.GetComponent <Image>();
        float      usedMana           = Mathf.Clamp(target.thisUsedMana, statusData.MinMana, statusData.MaxMana);

        buffShowStructList.Add(new BuffShowStruct()
        {
            buffTarget = createBuffStateObj,
            maxTime    = statusData.DurationCuvre.Evaluate(usedMana),
            nowTime    = 0,
            statusData = statusData,
            timeImge   = timeImage
        });
    }
    private void OnGUI()
    {
        if (restart)
        {
            EditorGUILayout.LabelField("出现错误请重新打开");
            return;
        }
        try
        {
            EditorGUILayout.BeginHorizontal();
            //左侧的选择状态类型与保存面板
            EditorGUILayout.BeginVertical(GUILayout.Width(100));
            if (GUILayout.Button("保存", GUILayout.Width(95)))
            {
                string valueText = SerializeNow(dataDic);
                File.WriteAllText(dataDirecotryPath + "/Status.txt", valueText, Encoding.UTF8);
                EditorUtility.DisplayDialog("保存数据", "保存成功!", "确认");
            }
            EditorGUILayout.LabelField("状态类型");
            selectEnumStatusEffect = (EnumStatusEffect)EditorGUILayout.EnumPopup(selectEnumStatusEffect, GUILayout.Width(95));
            FieldInfo            fieldInfo    = typeof(EnumStatusEffect).GetField(selectEnumStatusEffect.ToString());
            FieldExplanAttribute fieldExplane = fieldInfo.GetCustomAttributes(typeof(FieldExplanAttribute), false).OfType <FieldExplanAttribute>().FirstOrDefault();
            if (fieldExplane != null)
            {
                EditorGUILayout.LabelField(fieldExplane.GetExplan(), GUILayout.Width(95));
            }
            EditorGUILayout.EndVertical();

            //右侧显示详细信息面板
            EditorGUILayout.BeginVertical();
            rightScroll = EditorGUILayout.BeginScrollView(rightScroll);
            if (dataDic.ContainsKey(selectEnumStatusEffect))
            {
                StatusDataInfo statusDataInfo = dataDic[selectEnumStatusEffect];
                ReflectUnit <StatusDataInfo> statusDataInfoUnit = Entry.On(statusDataInfo);
                EditorGUILayout.BeginHorizontal();
                //说明
                EditorGUILayout.BeginVertical();
                EditorGUILayout.LabelField("状态简要说明");
                string statusExplane = EditorGUILayout.TextArea(statusDataInfo.StatusExplane, GUILayout.Width(200), GUILayout.Height(100));
                if (!string.Equals(statusExplane, statusDataInfo.StatusExplane))
                {
                    statusDataInfoUnit.Field("statusExplane", statusExplane);
                }
                EditorGUILayout.EndVertical();
                //图片
                EditorGUILayout.BeginVertical();
                EditorGUILayout.LabelField("状态的图标");
                statusDataInfo.Load();
                Sprite statusSprite = (Sprite)EditorGUILayout.ObjectField(statusDataInfo.StatusSprite, typeof(Sprite), true, GUILayout.Width(100), GUILayout.Height(100));
                if (!Sprite.Equals(statusSprite, statusDataInfo.StatusSprite) && statusSprite != null)
                {
                    string statusSpriteID = SpriteManager.GetName(statusSprite);
                    statusDataInfoUnit.Field("statusSpriteID", statusSpriteID).End();
                    statusDataInfoUnit.Field("statusSprite", null);
                }
                EditorGUILayout.EndVertical();
                EditorGUILayout.EndHorizontal();
                //不同等级的具体状态
                Dictionary <int, StatusDataInfo.StatusLevelDataInfo> levelToDataDic = statusDataInfoUnit.Field <Dictionary <int, StatusDataInfo.StatusLevelDataInfo> >("levelToDataDic").Element;
                //等级
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("最大等级:" + (levelToDataDic.Count - 1), GUILayout.Width(70));
                if (levelToDataDic.Count > 0 && GUILayout.Button("-", GUILayout.Width(20)))
                {
                    if (EditorUtility.DisplayDialog("警告!", "将会减去最后一个等级的数据!", "确认", "取消"))
                    {
                        levelToDataDic.Remove(levelToDataDic.Count - 1);
                    }
                }
                if (GUILayout.Button("+", GUILayout.Width(20)))
                {
                    levelToDataDic.Add(levelToDataDic.Count, new StatusDataInfo.StatusLevelDataInfo());
                }
                EditorGUILayout.LabelField("当前选择:" + selectLevel, GUILayout.Width(70));
                if (selectLevel > 0 && GUILayout.Button("-", GUILayout.Width(20)))
                {
                    selectLevel--;
                }
                if (selectLevel < levelToDataDic.Count - 1 && GUILayout.Button("+", GUILayout.Width(20)))
                {
                    selectLevel++;
                }
                selectLevel = Mathf.Clamp(selectLevel, 0, levelToDataDic.Count - 1);
                EditorGUILayout.EndHorizontal();
                //具体状态
                if (selectLevel >= 0 && selectLevel < levelToDataDic.Count)
                {
                    StatusDataInfo.StatusLevelDataInfo statusLeveDataInfo = levelToDataDic[selectLevel];
                    EditorGUILayout.LabelField("具体说明");
                    statusLeveDataInfo.LevelExplane = EditorGUILayout.TextArea(statusLeveDataInfo.LevelExplane, GUILayout.Height(60));
                    //该等级的耗魔对应基础持续时间曲线
                    EditorGUILayout.LabelField("持续时间曲线设置:");
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("最小魔力:", GUILayout.Width(75));
                    statusLeveDataInfo.MinMana       = EditorGUILayout.IntField(statusLeveDataInfo.MinMana, GUILayout.Width(75));
                    statusLeveDataInfo.DurationCuvre = EditorGUILayout.CurveField(statusLeveDataInfo.DurationCuvre, GUILayout.Width(150));
                    EditorGUILayout.LabelField("最大魔力:", GUILayout.Width(75));
                    statusLeveDataInfo.MaxMana = EditorGUILayout.IntField(statusLeveDataInfo.MaxMana, GUILayout.Width(75));
                    EditorGUILayout.EndHorizontal();
                    //设置具体的数据
                    EditorGUILayout.LabelField("具体数据设置:");
                    StatusActionAttribute statusAction = fieldInfo.GetCustomAttributes(typeof(StatusActionAttribute), false).OfType <StatusActionAttribute>().FirstOrDefault();
                    if (statusAction != null)
                    {
                        EnumStatusAction[] enumStatusActions = statusAction.GetStatusActions();
                        //如果不存在该项则添加
                        foreach (EnumStatusAction enumStatusAction in enumStatusActions)
                        {
                            if (!statusLeveDataInfo.StatusActionDataInfoDic.ContainsKey(enumStatusAction))
                            {
                                Type t = assembly.GetType("StatusActionDataInfo_" + enumStatusAction.ToString());
                                if (t != null)
                                {
                                    StatusActionDataInfo_Base sb = Activator.CreateInstance(t) as StatusActionDataInfo_Base;
                                    statusLeveDataInfo.StatusActionDataInfoDic.Add(enumStatusAction, sb);
                                }
                            }
                        }
                        //如果多余则删除
                        IEnumerable <EnumStatusAction> checkEnumStatusActions = statusLeveDataInfo.StatusActionDataInfoDic.Keys.OfType <EnumStatusAction>();
                        foreach (EnumStatusAction item in checkEnumStatusActions)
                        {
                            if (!enumStatusActions.Contains(item))
                            {
                                statusLeveDataInfo.StatusActionDataInfoDic.Remove(item);
                            }
                        }
                        //循环
                        Type enumStatusActionType = typeof(EnumStatusAction);
                        foreach (KeyValuePair <EnumStatusAction, StatusActionDataInfo_Base> item in statusLeveDataInfo.StatusActionDataInfoDic)
                        {
                            FieldExplanAttribute fieldExplanAttribute = enumStatusActionType.GetField(item.Key.ToString()).GetCustomAttributes(typeof(FieldExplanAttribute), false).OfType <FieldExplanAttribute>().First();
                            if (fieldExplanAttribute != null)
                            {
                                EditorGUILayout.Space();
                                EditorGUILayout.LabelField(fieldExplanAttribute.GetExplan()); //显示该状态效果的名字
                                Type statusActionDataInfoBaseType = item.Value.GetType();     // assembly.GetType("StatusActionDataInfo_" + item.Key.ToString());
                                if (statusActionDataInfoBaseType != null)
                                {
                                    FieldInfo[] statusActionDataInfoBaseInfos = statusActionDataInfoBaseType.GetFields();
                                    //便利该效果对应的数据对象并显示
                                    foreach (FieldInfo statusActionDataInfoBaseInfo in statusActionDataInfoBaseInfos)
                                    {
                                        object innerValueData = statusActionDataInfoBaseInfo.GetValue(item.Value);
                                        FieldExplanAttribute innerAttribute = statusActionDataInfoBaseInfo.GetCustomAttributes(typeof(FieldExplanAttribute), false).OfType <FieldExplanAttribute>().FirstOrDefault();
                                        if (innerAttribute != null)
                                        {
                                            EditorGUILayout.BeginHorizontal();
                                            EditorGUILayout.LabelField(innerAttribute.GetExplan());
                                            if (statusActionDataInfoBaseInfo.FieldType.Equals(typeof(int)))
                                            {
                                                int innerValue = EditorGUILayout.IntField((int)innerValueData);
                                                statusActionDataInfoBaseInfo.SetValue(item.Value, innerValue);
                                            }
                                            else if (statusActionDataInfoBaseInfo.FieldType.Equals(typeof(float)))
                                            {
                                                float innerValue = EditorGUILayout.FloatField((float)innerValueData);
                                                statusActionDataInfoBaseInfo.SetValue(item.Value, innerValue);
                                            }
                                            else if (statusActionDataInfoBaseInfo.FieldType.Equals(typeof(string)))
                                            {
                                                string innerValue = EditorGUILayout.TextField((string)innerValueData);
                                                statusActionDataInfoBaseInfo.SetValue(item.Value, innerValue);
                                            }
                                            else if (statusActionDataInfoBaseInfo.FieldType.Equals(typeof(bool)))
                                            {
                                                bool innerValue = EditorGUILayout.Toggle((bool)innerValueData);
                                                statusActionDataInfoBaseInfo.SetValue(item.Value, innerValue);
                                            }
                                            EditorGUILayout.EndHorizontal();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
        }
        catch
        {
            restart = false;
        }
    }
    /// <summary>
    /// 根据技能获取粒子的初始化数据
    /// </summary>
    /// <param name="playerObj">对象</param>
    /// <param name="nowIAttributeState">本次计算所使用的状态数据</param>
    /// <param name="skills">技能数组</param>
    /// <returns></returns>
    public ParticalInitParamData[] GetParticalInitParamData(GameObject playerObj, IAttributeState nowIAttributeState, params SkillBaseStruct[] skills)
    {
        List <ParticalInitParamData> resultList            = new List <ParticalInitParamData>();
        ParticalInitParamData        particalInitParamData = default(ParticalInitParamData);
        ISkillState iSkillState = GameState.Instance.GetEntity <ISkillState>();
        PlayerState playerState = DataCenter.Instance.GetEntity <PlayerState>();

        EnumSkillType[] skillTyps = skills.Where(temp => temp != null).Select(temp => temp.skillType).OrderBy(temp => (int)temp).ToArray();
        //耗魔量
        float        holdingRate  = iSkillState.SkillStartHoldingTime / GameState.BaseSkillStartHoldingTime; //计算蓄力程度
        float        maxUseMana   = nowIAttributeState.MaxUseMana;                                           //当前的最大耗魔上限
        float        baseUseMana  = nowIAttributeState.MustUsedBaseMana;                                     //基础耗魔值
        float        thisUsedMana = baseUseMana + maxUseMana * holdingRate;                                  //该技能的耗魔值
        IPlayerState iPlayerState = GameState.Instance.GetEntity <IPlayerState>();

        if (iPlayerState.Mana < thisUsedMana)
        {
            thisUsedMana = iPlayerState.Mana;
        }
        //技能附加的特效(特殊效果和debuff)
        StatusData statusData = DataCenter.Instance.GetMetaData <StatusData>();                                                          //保存特殊状态的数据
        Dictionary <StatusDataInfo.StatusLevelDataInfo, int> statusEffects = new Dictionary <StatusDataInfo.StatusLevelDataInfo, int>(); //特殊效果对应该等级数据与对应等级字典

        foreach (SkillBaseStruct skillBaseStruct in skills)
        {
            if (skillBaseStruct == null)
            {
                continue;
            }
            //选取debuff和特殊效果
            IEnumerable <EnumStatusEffect> enumStatusEffects = skillBaseStruct.skillStatusEffect.Where(temp => (temp > EnumStatusEffect.DebuffStart && temp < EnumStatusEffect.DebuffEnd) || (temp > EnumStatusEffect.SpecialStart && temp < EnumStatusEffect.SpecialEnd));
            foreach (EnumStatusEffect enumStatusEffect in enumStatusEffects)
            {
                StatusDataInfo statusDataInfo = statusData[enumStatusEffect];
                if (statusDataInfo == null)
                {
                    continue;
                }
                int level = 0;
                playerState.SkillPoint.TryGetValue(skillBaseStruct.skillType, out level);
                StatusDataInfo.StatusLevelDataInfo statusLevelDataInfo = statusDataInfo[level];
                if (statusLevelDataInfo != null)
                {
                    if (statusEffects.Count(temp => temp.Key.EffectType == enumStatusEffect) > 0)//如果已经存在相同类型的特效
                    {
                        KeyValuePair <StatusDataInfo.StatusLevelDataInfo, int> tempStatusEffect = statusEffects.FirstOrDefault(temp => temp.Key.EffectType == enumStatusEffect);
                        int nowLevel = tempStatusEffect.Value;
                        if (nowLevel < level)//计算当前存放的特效等级是否高于新加的等级
                        {
                            statusEffects.Remove(tempStatusEffect.Key);
                            statusEffects.Add(statusLevelDataInfo, level);
                        }
                    }
                    else
                    {
                        statusEffects.Add(statusLevelDataInfo, level);
                    }
                }
            }
        }
        StatusDataInfo.StatusLevelDataInfo[] statusLevelDataInfos = statusEffects.Keys.ToArray();
        //这几个是基础数据
        particalInitParamData.position = playerObj.transform.position + playerObj.transform.forward * 0.3f + playerObj.transform.up * 1.5f;
        particalInitParamData.lifeTime = 5;
        particalInitParamData.checkCollisionIntervalTime = 1;
        particalInitParamData.targetObjs = new GameObject[0];
        particalInitParamData.forward    = playerObj.transform.forward;
        particalInitParamData.color      = new Color(0.5f, 0.5f, 0.5f, 0.1f);
        particalInitParamData.layerMask  = LayerMask.GetMask("Monster", "Default");
        //下面的是变化数据
        //颜色
        SkillBaseStruct combine_secondSkill = skills.Where(temp => temp != null).FirstOrDefault(temp => temp.skillType > EnumSkillType.MagicCombinedLevel2Start && temp.skillType < EnumSkillType.MagicCombinedLevel2End);

        if (combine_secondSkill != null)
        {
            switch (combine_secondSkill.skillType)
            {
            case EnumSkillType.YSX01:    //火元素
                particalInitParamData.color = Color.red;
                break;

            case EnumSkillType.YSX02:    //水元素
                particalInitParamData.color = Color.blue;
                break;

            case EnumSkillType.YSX03:    //土元素
                particalInitParamData.color = Color.yellow;
                break;

            case EnumSkillType.YSX04:    //风元素
                particalInitParamData.color = Color.green;
                break;

            case EnumSkillType.SM06:    //冰元素
                particalInitParamData.color = Color.cyan;
                break;

            case EnumSkillType.SM07:    //雷元素
                particalInitParamData.color = new Color(0.5f, 0, 0.5f, 1);
                break;

            case EnumSkillType.DSM03:        //光明元素
            case EnumSkillType.XYX01_Target: //光明信仰基础_对敌军
                particalInitParamData.color = Color.white;
                break;

            case EnumSkillType.DSM04:        //黑暗元素
            case EnumSkillType.XYX02_Target: //黑暗信仰基础_对敌军
                particalInitParamData.color = Color.black;
                break;

            case EnumSkillType.XYX03_Target:    //生物信仰基础_对敌军
                particalInitParamData.color = new Color(0, 1, 0.2f, 1);
                break;

            case EnumSkillType.XYX04_Target:    //自然信仰基础_对敌军
                //颜色选择为当前环境对应的元素
                IEnvironment iEnvironment = GameState.Instance.GetEntity <IEnvironment>();
                switch (iEnvironment.TerrainEnvironmentType)
                {
                case EnumEnvironmentType.Plain:
                    particalInitParamData.color = new Color(0.5f, 0, 0.5f, 1);
                    break;

                case EnumEnvironmentType.Swamp:
                    particalInitParamData.color = Color.blue;
                    break;

                case EnumEnvironmentType.Desert:
                    particalInitParamData.color = Color.yellow;
                    break;

                case EnumEnvironmentType.Forest:
                    particalInitParamData.color = Color.green;
                    break;

                case EnumEnvironmentType.Volcano:
                    particalInitParamData.color = Color.red;
                    break;
                }
                break;
            }
        }
        //技能最基础表现形式
        SkillBaseStruct    combine_firstSkill = skills.Where(temp => temp != null).FirstOrDefault(temp => temp.skillType > EnumSkillType.MagicCombinedLevel1Start && temp.skillType < EnumSkillType.MagicCombinedLevel1End);
        IMonsterCollection iMonsterCollection = GameState.Instance.GetEntity <IMonsterCollection>();
        GameObject         selectTargetObj    = null;//魔力导向选中的对象

        if (combine_firstSkill != null)
        {
            switch (combine_firstSkill.skillType)
            {
            case EnumSkillType.FS01:                          //奥数弹
                particalInitParamData.range             = 20; //表示距离
                particalInitParamData.CollisionCallBack = temp => CalculateCombineMagicHurt(nowIAttributeState, temp, thisUsedMana, statusLevelDataInfos, skillTyps);
                break;

            case EnumSkillType.FS02:                         //奥数震荡
                particalInitParamData.range             = 1; //表示比例
                particalInitParamData.CollisionCallBack = temp => CalculateCombineMagicHurt(nowIAttributeState, temp, thisUsedMana, statusLevelDataInfos, skillTyps);
                particalInitParamData.position          = playerObj.transform.position + playerObj.transform.forward * 2f;
                break;

            case EnumSkillType.FS03:                         //魔力屏障
                particalInitParamData.range             = 1; //表示比例
                particalInitParamData.CollisionCallBack = temp => CalculateCombineMagicHurt(nowIAttributeState, temp, thisUsedMana, statusLevelDataInfos, skillTyps);
                break;

            case EnumSkillType.FS04:    //魔力导向
                //查找前方45度方位内距离自己最近的怪物
                GameObject[] selectObjs = iMonsterCollection.GetMonsters(playerObj, 45, 20);
                if (selectObjs != null && selectObjs.Length > 0)
                {
                    selectTargetObj = selectObjs[0];
                }
                if (selectTargetObj)
                {
                    particalInitParamData.range             = Vector3.Distance(selectTargetObj.transform.position, playerObj.transform.position);//表示距离
                    particalInitParamData.targetObjs        = new GameObject[] { selectTargetObj };
                    particalInitParamData.CollisionCallBack = temp => CalculateCombineMagicHurt(nowIAttributeState, temp, thisUsedMana, statusLevelDataInfos, skillTyps);
                }
                else
                {
                    particalInitParamData.range = 10;
                }
                break;

            case EnumSkillType.MFS05:            //魔力脉冲
                particalInitParamData.range = 1; //表示比例
                if (combine_secondSkill != null)
                {
                    switch (combine_secondSkill.skillType)
                    {
                    case EnumSkillType.YSX03:       //土元素 大地咆哮
                    case EnumSkillType.YSX04:       //风元素 风暴突袭
                    case EnumSkillType.SM06:        //冰元素 寒霜吐息
                        particalInitParamData.position = playerObj.transform.position + playerObj.transform.forward * 1f;
                        break;
                    }
                }
                particalInitParamData.CollisionCallBack = temp => CalculateCombineMagicHurt(nowIAttributeState, temp, thisUsedMana, statusLevelDataInfos, skillTyps);
                break;
            }
        }
        resultList.Add(particalInitParamData);
        //第三阶段的连续魔力导向有点特殊
        SkillBaseStruct combine_thirdSkill = skills.Where(temp => temp != null).FirstOrDefault(temp => temp.skillType > EnumSkillType.MagicCombinedLevel3Start && temp.skillType < EnumSkillType.MagicCombinedLevel3End);

        if (combine_thirdSkill != null && combine_thirdSkill.skillType == EnumSkillType.MFS06)
        {
            //查找周围距离查找到的怪物的最近的怪物
            if (selectTargetObj)
            {
                GameObject[]       nextObjs     = iMonsterCollection.GetMonsters(selectTargetObj, -1, 100);//测试用100 默认是10
                Queue <GameObject> queueNextObj = new Queue <GameObject>();
                queueNextObj.Enqueue(selectTargetObj);
                foreach (var item in nextObjs)
                {
                    queueNextObj.Enqueue(item);
                }
                while (queueNextObj.Count > 1)
                {
                    GameObject            firstObj  = queueNextObj.Dequeue(); //第一个怪物
                    GameObject            secondObj = queueNextObj.Peek();    //第二个怪物
                    ParticalInitParamData temp_particalInitParamData = particalInitParamData;
                    temp_particalInitParamData.forward           = (secondObj.transform.position - firstObj.transform.position).normalized;
                    temp_particalInitParamData.position          = firstObj.transform.position + temp_particalInitParamData.forward;
                    temp_particalInitParamData.range             = Vector3.Distance(firstObj.transform.position, secondObj.transform.position);
                    temp_particalInitParamData.targetObjs        = new GameObject[] { secondObj };
                    temp_particalInitParamData.CollisionCallBack = (temp) => CalculateCombineMagicHurt(nowIAttributeState, temp, thisUsedMana, statusLevelDataInfos, skillTyps);
                    resultList.Add(temp_particalInitParamData);
                }
            }
        }

        return(resultList.ToArray());
    }