切换职业时,如果某个部位存在职业冲突(如弓箭手不让用重甲),那么应该做一次自动切换(UI和模型),默认切换职业只改变了武器和待机动画。

alt

为了能让方法根据我们想要的部位类型进行切换(默认是当前部位类型),对其进行改造。

alt 改造前。

alt 改造后,实际就是把部位类型作为参数传进方法,其他逻辑不变。

    private void SelectProfession(ProfessionType professionType)
    {
        //处理实际的职业切换逻辑
        CharacterCreator.Instance.SetProfession(professionType);

        //检查当前已经应用的部位是否有不支持这个职业的情况
        CharacterPartConfigBase partConfig = GetCurrentCharacterPartConfig(CharacterParType.Face);
        if (!partConfig.ProfessionTypes.Contains(professionType))
        {
            //切换这个脸部的部位
            SetNextCHaracterPart(false,false, CharacterParType.Face);
        }

        partConfig = GetCurrentCharacterPartConfig(CharacterParType.Hair);
        if (!partConfig.ProfessionTypes.Contains(professionType))
        {
            //切换这个头发的部位
            SetNextCHaracterPart(false,false, CharacterParType.Hair);
        }

        partConfig = GetCurrentCharacterPartConfig(CharacterParType.Cloth);
        if (!partConfig.ProfessionTypes.Contains(professionType))
        {
            //切换这个上衣的部位
            SetNextCHaracterPart(false,false, CharacterParType.Cloth);
        }

    }

SetNextCHaracterPart(false ,false, CharacterParType.Face)的第一个参数代表向右切换,第二个代表不更新UI,第三个打表切换的部位类型。

第二个参数不更新UI的意义在于,这里隐含一个问题,因为我们对三个部位都进行检测,如果在切换职业之前,当前职业和切换之后职业有冲突的部位并不是当前选择的部位,那么切换之后有冲突的部位会刷新UI,当前的部位类型和实际的部位配置会对不上。

alt

坦克职业穿着重甲,如果此时从脸部配置窗口切换职业,由于弓箭手没有重甲,会切换成粗布衣,刷新UI之后粗布衣和脸部配置就对不上。

所以可以在切换职业起冲突时自动切换部位的更新UI逻辑关闭,但仍存在问题。

alt

切换职业起冲突时是需要刷新UI的,如果关闭UI,如图从重甲坦克切换到弓箭手时,只有模型做出了冲突切换,UI没有。

    /// <summary>
    /// 选择职业
    /// </summary>
    private void SelectProfession(ProfessionType professionType,bool isInit)
    {
        //处理实际的职业切换逻辑
        CharacterCreator.Instance.SetProfession(professionType);


        //还原UI为当前选择的部位类型
        if (!isInit)
        {
            //检查当前已经应用的部位是否有不支持这个职业的情况
            CharacterPartConfigBase partConfig = GetCurrentCharacterPartConfig(CharacterParType.Face);
            if (!partConfig.ProfessionTypes.Contains(professionType))
            {
                //切换这个脸部的部位
                SetNextCHaracterPart(false, true, CharacterParType.Face);
            }

            partConfig = GetCurrentCharacterPartConfig(CharacterParType.Hair);
            if (!partConfig.ProfessionTypes.Contains(professionType))
            {
                //切换这个头发的部位
                SetNextCHaracterPart(false, true, CharacterParType.Hair);
            }

            partConfig = GetCurrentCharacterPartConfig(CharacterParType.Cloth);
            if (!partConfig.ProfessionTypes.Contains(professionType))
            {
                //切换这个上衣的部位
                SetNextCHaracterPart(false, true, CharacterParType.Cloth);
            }

            CharacterParType currPartType = currentFacadeMenu_Tab.CharacterParType;
            int currIndex = characterConfigIndexDic[(int)currPartType];
            int currID = projectConfig.CustomCharacterPartConfigIDDic[currPartType][currIndex];
            SetCharacterPart(currPartType, currID, true, false);
        }


    }

所以最好的解决方式并不是关闭UI,而是在切换职业检查完所有冲突之后,再刷新一次UI为当前选择的部位类型,并且注意在游戏初始化时选择默认值也是不需要检查的(这时候也获取不到当前的CharacterPartType),扩展一个参数来进行判断。

alt

最终结果。

PS:上面问题的解决方式有点麻烦,问题本质是切换职业时起冲突的部位和当前选择的部位不一致所导致的,所以直接加个判断条件让不一致时不刷新UI即可,一致还是正常刷新。

    private void SelectProfession(ProfessionType professionType)
    {
        //处理实际的职业切换逻辑
        CharacterCreator.Instance.SetProfession(professionType);


            //检查当前已经应用的部位是否有不支持这个职业的情况
            CharacterPartConfigBase partConfig = GetCurrentCharacterPartConfig(CharacterParType.Face);
            if (!partConfig.ProfessionTypes.Contains(professionType))
            {
                //切换这个脸部的部位
                SetNextCHaracterPart(false, currentFacadeMenu_Tab.CharacterParType == CharacterParType.Face, CharacterParType.Face);
            }

            partConfig = GetCurrentCharacterPartConfig(CharacterParType.Hair);
            if (!partConfig.ProfessionTypes.Contains(professionType))
            {
                //切换这个头发的部位
                SetNextCHaracterPart(false, currentFacadeMenu_Tab.CharacterParType == CharacterParType.Hair, CharacterParType.Hair);
            }

            partConfig = GetCurrentCharacterPartConfig(CharacterParType.Cloth);
            if (!partConfig.ProfessionTypes.Contains(professionType))
            {
                //切换这个上衣的部位
                SetNextCHaracterPart(false, currentFacadeMenu_Tab.CharacterParType == CharacterParType.Cloth, CharacterParType.Cloth);
            }

    }

另外Init参数的扩展也没有必要。

alt

只需要严格控制获取当前部位之前已经初始化好了facadeMenu_Tabs和currentFacadeMenu_Tab就不会存在currentFacadeMenu_Tab空引用的问题,且新写法默认设置没有冲突压根不会进if语句去判断。