任务弹窗更新为任务对话框

本文描述了游戏中的任务UI设计优化,从频繁的手动操作改为自动接取,以及任务完成时的逻辑调整,包括使用FakeObj对话框显示任务提示和更新任务状态。同时提及了角色头像的动态加载和对话内容的播放控制。
摘要由CSDN通过智能技术生成

1.设计初心

在这里插入图片描述

在玩家接取任务/交付任务时,界面弹出的UI ,需要与玩家互动,点击“接取”“完成”。等等字样
【改动前】
image.png
频繁的手动点击会中断玩家跑图的流畅性,也降低了任务寻路系统的实际体验。
于是现在变成类似FakeObj + 对话框的模式去显示任务的提示字。不再显示任务的接取 / 完成 状态。
自动接取任务。
【改动后】
image.png

2.逻辑梳理

在任务完成时通过ObjNpc.ShowDialg(); 显示弹窗
现在需要改动这里面的内容。

  bool ShowMission()
    {
        if (true == SetFindNpcMisCompleted())
        {
            return true;
        }    

        // 弹出已完成任务
        if (true == PopCommitNpcDialog())
        {
            return true;
        }

        // 弹出可接任务
        if (true == PopAcceptNpcDialog())
        {
            return true;
        }
        
        return false;
    }

拿已经完成的任务来说,需要改动 PopCommitNpcDialog()
现在在任务MisBase配置表中加了新的一列,决定是否启用对话框代替任务弹板。当PopType 字段为1 表示启用
image.png
第一步读取字典,判断显示方式

Tab_MisBase misBase = TableManager.GetMisBaseByID(nMisID);
            //弹窗
if (misBase.PopType == 0)
{
      //...          
}
else
{
    //...
    StoryPlayerController.PlayMisDialogue(1, MissionManager.MisCommit,nMisID);
}
                

在PlayMisDialogue方法中我们需要一个任务ID 和 当前任务状态来标识。

    public static bool PlayMisDialogue(int misState,OnFinshMisTips finshMisTips = null,int param = -1)
    {
        m_curMisState = misState;
        Init(finshMisTips, param);
        UIManager.CloseUI(UIInfo.OnlineReminderWindow);
        return UIManager.ShowUI(UIInfo.StoryPlayer);
    }

我设置了三个参数,第一个是任务号标识当前任务,第二个需要接受一个对话框显示结束后的逻辑,可能需要更新任务状态,同步服务器(已完成)等等。

    static void Init(OnFinshMisTips finshMisTips = null, int param = -1)
    {
        m_finshMisTips = finshMisTips;
        misID = param;
        m_StoryTab = null;
        isMisTips = true;
        if (m_Instance != null)
        {
            m_Instance.isPlayFinish = false;
            m_Instance.m_BaseOffset.SetActive(true);
        }
    }

Init作为初始化对话框的前序操作。主要是存储数据到文件里。
接下来是异步的关闭提示窗口打开剧情对话框。
播放剧情逻辑

    private void PlayMissionTips(int misState)
    {
        if (!isMisTips)
        {
            OnPlayOver();
            return;
        }
        Tab_MisDictionary misDictionary = TableManager.GetMisDictionaryByID(misID);
        string dialogue = string.Empty;
        if (misState == 0)
        {
             dialogue = misDictionary.GetAceptDescbyIndex(0);    
        }
        else
        {
            dialogue = misDictionary.GetComitDescbyIndex(0);
        }

        int curNpcId = misState == 0 ? misDictionary.AceptNpcDataID : misDictionary.ComitNpcDataID;
        //生成对话框头像
        InitCharUI(curNpcId);
        m_strAniDialog = dialogue;
        ShowAniDialogEnd();
        m_fStoryTimer = 5f;
        isMisTips = false;
        //播放结束后处理
        m_curMisState = -1;
    }

初始化对话框人物头像和角色信息

image.png

 private void InitCharUI(int nSpeakerID)
    {
        string strSpeakerName = string.Empty;
        int nDataID = nSpeakerID;
        Obj_Char objChar = null;

        if (GlobeVar.INVALID_ID == nDataID)
        {
            // 主角
            nDataID = ObjManager.MainPlayer.RoleBaseID;
            strSpeakerName = ObjManager.MainPlayer.RoleName;
            m_SpeakerName.text = strSpeakerName;

            if (m_NpcFakeObj)
            {
                m_NpcFakeObj.gameObject.SetActive(false);
            }

            if (m_ChildFakeObj)
            {
                m_ChildFakeObj.gameObject.SetActive(false);
            }

            // 已经有缓存了
            if (m_PlayerFakeObj != null)
            {
                m_PlayerFakeObj.gameObject.SetActive(true);
                m_PlayerFakeObj.ResetFakeObjTransform();
                RefixFakeObjCamera(m_PlayerFakeObj);
                return;
            }

            // 创建模型

            GameManager.CurActiveScene.ShowFakeCamera(true);
            m_PlayerFakeObj = m_UIObjTexture.ShowMainPlayerFakeObj(FAKEOBJTYPE.HALF, RefixFakeObjCamera);
            return;
        }
        else if (-2 == nDataID)
        {
            // 孩子
            if (m_PlayerFakeObj)
            {
                m_PlayerFakeObj.gameObject.SetActive(false);
            }

            if (m_NpcFakeObj)
            {
                m_NpcFakeObj.gameObject.SetActive(false);
            }

            // 已经有缓存了
            if (m_ChildFakeObj != null)
            {
                m_ChildFakeObj.gameObject.SetActive(true);
                m_ChildFakeObj.ResetFakeObjTransform();
                RefixFakeObjCamera(m_ChildFakeObj);
                return;
            }

            ChildInfo m_CurChild = null;

            if (GameManager.PlayerDataPool.PlayerBirthManager.IsHaveSelfChild(true))
            {
                m_CurChild = GameManager.PlayerDataPool.PlayerBirthManager.m_ChildInfo;
            }

            if (m_CurChild == null)
            {
                return;
            }
            else
            {
                strSpeakerName = m_CurChild.m_Name;
                m_SpeakerName.text = strSpeakerName;

                int childType = m_CurChild.GetChildType();
                Tab_ChildInfo tabChildInfo = TableManager.GetChildInfoByID(childType);
                if (tabChildInfo != null)
                {
                    Tab_CharModel charModel = TableManager.GetCharModelByID(tabChildInfo.BodyIdFakeObj);
                    if (charModel != null)
                    {
                        AvatarLoadInfo info = ChildFashionManager.GetChildAvatarInfo(m_CurChild);
                        GameManager.CurActiveScene.ShowFakeCamera(true);
                        //m_ChildFakeObj = ObjManager.CreateFakeObj(charModel.HalfFakeOjbID, info, GlobeVar.INVALID_ID, "Child", null, GlobeVar.FAKEOBJ_LAYER, GlobeVar.INVALID_ID, RefixFakeObjCamera);
                        m_ChildFakeObj = m_UIObjTexture.ShowFakeObj(charModel.HalfFakeOjbID, info, -1, -1, -1,
                            RefixFakeObjCamera);
                        return;
                    }
                }
            }
        }
        else
        {
            // 普通NPC
            Tab_NpcAttr NpcAttr = TableManager.GetNpcAttrByID(nDataID);
            if (NpcAttr != null)
            {
                //冒牌师姐任务特殊处理,npc名字改成玩家名字
                if (nDataID == 8345 && GameManager.RunningScene == (int)SCENE_DEFINE.SCENE_MAOPAISHIJIE)
                {
                    strSpeakerName = ObjManager.MainPlayer.RoleName;                   
                }
                else 
                {
                    strSpeakerName = NpcAttr.Name;
                }

                m_SpeakerName.text = strSpeakerName;

                if (m_PlayerFakeObj)
                {
                    m_PlayerFakeObj.gameObject.SetActive(false);
                }
                if (m_ChildFakeObj)
                {
                    m_ChildFakeObj.gameObject.SetActive(false);
                }

                // 已经有缓存了
                if (m_NpcFakeObj != null && m_NpcFakeObj.gameObject.name == nDataID.ToString())
                {
                    m_NpcFakeObj.gameObject.SetActive(true);
                    m_NpcFakeObj.ResetFakeObjTransform();
                    RefixFakeObjCamera(m_NpcFakeObj);
                    return;
                }

                // 创建模型
                Tab_RoleBaseAttr RoleBase = TableManager.GetRoleBaseAttrByID(nDataID);
                if (RoleBase != null)
                {
                    objChar = ObjManager.FindObjCharInSceneByData(nDataID);
                    if (objChar != null)
                    {
                        Tab_CharModel charModel = TableManager.GetCharModelByID(RoleBase.CharModelID);
                        if (charModel != null)
                        {
                            if (m_NpcFakeObj != null)
                            {
                                GameObject.DestroyImmediate(m_NpcFakeObj.gameObject);
                            }
                            GameManager.CurActiveScene.ShowFakeCamera(true);
                            //m_NpcFakeObj = ObjManager.CreateFakeObj(charModel.HalfFakeOjbID, objChar, nDataID.ToString(), null, GlobeVar.FAKEOBJ_LAYER, RefixFakeObjCamera);                           
                            m_NpcFakeObj = m_UIObjTexture.ShowFakeObj(charModel.HalfFakeOjbID, objChar, RefixFakeObjCamera);
                            return;
                        }
                    }
                    else
                    {
                        // 找不到
                        Tab_CharModel charModel = TableManager.GetCharModelByID(RoleBase.CharModelID);
                        if (charModel != null)
                        {
                            if (m_NpcFakeObj != null)
                            {
                                GameObject.DestroyImmediate(m_NpcFakeObj.gameObject);
                            }
                           

                            int nNpcProfession = GlobeVar.INVALID_ID;
                            AvatarLoadInfo info = new AvatarLoadInfo();
                            info.m_BodyId = charModel.Id;
                            //增加Npc头身分离逻辑
                            Tab_NpcAttr npcAttr = TableManager.GetNpcAttrByID(nDataID);
                            if (npcAttr != null && npcAttr.IsHeadBodyLeave == 1)
                            {
                                Tab_NpcModelInfo modelinfo = TableManager.GetNpcModelInfoByID(nDataID);
                                if (modelinfo != null)
                                {
                                    info.m_FaceId = modelinfo.FaceModelId;
                                    info.m_HairId = modelinfo.HairModelId;
                                    if (modelinfo.WeaponModelId != -1)
                                    {
                                        info.m_WeaponId = modelinfo.WeaponModelId;
                                        nNpcProfession = modelinfo.AvatarProfession;
                                    }
                                }
                            }
                            GameManager.CurActiveScene.ShowFakeCamera(true);
                            //m_NpcFakeObj = ObjManager.CreateFakeObj(charModel.HalfFakeOjbID, info, -1, nDataID.ToString(), null, GlobeVar.FAKEOBJ_LAYER, GlobeVar.INVALID_ID, RefixFakeObjCamera);                          
                            m_NpcFakeObj = m_UIObjTexture.ShowFakeObj(charModel.HalfFakeOjbID, info, nNpcProfession, -1, -1,RefixFakeObjCamera);
                            return;
                        }
                    }
                }
            }
        }
    }

他会根据NPCid 分为三类,玩家、场景NPC 和其他Obj 头像(可能是一团火、或者怪物 )
他们读取的配置表不同。
ShowAniDialogEnd()的内容很简单,大概就是把任务提示的内容,保存到本地str,便于后续播放。

播放字幕

在FixUpdate中更新内容

   void FixedUpdate()
    {
        if(isPlayFinish)
            return;
        Tick_PlayStory();
    }

逻辑如下

void Tick_PlayStory()
    {
        if (false != m_bAniDialog)
        {
            return;
        }

        if (StoryTriggerCtl.Instance.IsPlaying())
        {
            return;
        }
        
        if (m_fStoryTimer == GlobeVar.INVALID_ID || m_fStoryTimer <= 0)
        {
            if (!isMisTips)
            {
                if (m_nextBlackScreenId > 0 && !m_bAniDialog)
                {
                    StoryTriggerCtl.Instance.ToStartBlackScreen(m_nextBlackScreenId, onPlayFinished: PlayNextCallback);
                    m_nextBlackScreenId = -1;
                }
                else
                {
                    PlayNext();
                }
            }
            else
            {
                PlayMissionTips(m_curMisState);
            }
        }
        else
        {
            m_fStoryTimer -= Time.fixedDeltaTime;
        }
    }

当下一个对话内容不为空的时候,PlayNext()
主要是从对应的剧情字典Tab_StoryContent中取相应播放的文案。

void PlayNext()
    {
        if (m_bAniDialog)
        {
            // 动态文字展示
            ShowAniDialogEnd();
        }
        else
        {
            if (m_StoryTab == null)
            {
                OnPlayOver();
                return;    
            }
            m_nStoryIndex++;
            Tab_StoryContent mStoryItem = TableManager.GetStoryContentByID(m_StoryTab.StoryID, m_nStoryIndex);
            if (null == mStoryItem)
            {
                OnPlayOver();
                return;    
            }
            UpdateStoryUI(mStoryItem);
            //更新下一组对话框时间
            m_fStoryTimer = mStoryItem.LifeTime;
            JudgeSpeaker(mStoryItem);

            if (mStoryItem.BlackScreenEffect > 0)
                m_nextBlackScreenId = mStoryItem.BlackScreenEffect;
        }
    }

更新时间间隔在 m_fStoryTimer = mStoryItem.LifeTime;中
在FixUpdate中
m_fStoryTimer -= Time.fixedDeltaTime;计时

任务内容以对话框形式显示

1.gif

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值