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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/453653.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Filebeat(Beats)详细介绍与使用

1. 什么是 Beats? Beats 是开源数据传送器&#xff0c;将其作为代理安装在服务器上&#xff0c;以将操作数据发送到 Elasticsearch。 Elastic提供Beats用于捕获&#xff1a; 审核数据&#xff1a;Auditbeat 日志文件和日志&#xff1a;Filebeat 云数据&#xff1a;Functio…

网络学习:9个计算机的“网络层”知识点

目录 一、IP 地址 1.1 分类表示法&#xff1a; 1.1.1 分类表示地址的其他说明 1.2 无分类编址 CIDR 二、IP 数据报文格式 Q: IP 报文里有什么&#xff1f;可以不按顺序或者字节来讲一讲 三、 路由概念 3.1 路由表 3.2 路由网络匹配 3.3 ARP 解析 3.4 RARP 逆地址解析…

matplotlib系统学习记录

日期&#xff1a;2024.03.12 内容&#xff1a;将matplotlib的常用方法做一个记录&#xff0c;方便后续查找。 基本使用 # demo01 from matplotlib import pyplot as plt # 设置图片大小,也就是画布大小 fig plt.figure(figsize(20,8),dpi80)#图片大小&#xff0c;清晰度# 准…

代码学习记录18

随想录日记part18 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.13 主要内容&#xff1a;今天的主要内容是二叉树的第七部分&#xff0c;主要涉及二叉搜索树的最近公共祖先 &#xff1b;二叉搜索树的最近公共祖先&#xff1b;删除二叉搜索树中的节点 。 23…

HQChart实战教程70-K线图增加成本线

HQChart实战教程70-K线图增加成本线 成本线Y轴子自定义刻度HQChart插件地址步骤1. 创建成本线2. 动态计算盈利值3. 删除成本线交流示例源码成本线 在K线图上,显示一个根当前账户持仓的成本线,可以快速看到盈利状态。方便盯盘。 效果入下图: 第1行是成本价 第2行是盈利点数…

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

基于大模型的 Agent 进行任务规划的10种方式

本文首发自博客 基于大模型的 Agent 进行任务规划的10种方式 基于大模型的 Agent 基本组成应该包含规划&#xff08;planning)&#xff0c;工具&#xff08;Tools)&#xff0c;执行(Action)&#xff0c;和记忆(Memory)四个方面&#xff0c;上一篇中重点讲了进行长记忆管理的 8…

MFC 添加MFC类方法

1、打开工程目录的"类视图" 2、工程名右键添加"MFC类" 3、填写"类名"并选择“基类”CDialog&#xff0c;对话框ID填写添加好的对话框ID

Vue3 前端生成随机id( 生成 UUID )

效果展示 封装工具&#xff08;代码展示&#xff09; 重新创建一个文件**/utils/someTools.js**&#xff0c;并在里面写入如下代码。 function Tools() {}Tools.prototype.guid function () {return xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g, function (c) {v…

Junit4入门之什么是单元测试?

干了一年多的后端了&#xff0c;从来没有了解过单元测试。虽然我知道测试不仅仅是测试们的任务&#xff0c;后端也要进行自测来保证自己的代码的可用性&#xff0c;但我一直都只是用postman来实施的&#xff0c;调用调通了即可。虽然我也知道Junit是用于测试的软件&#xff0c;…

汽车屏类产品(五):仪表Cluster常用芯片i.MX117x

前言: 仪表一般就是指方向盘前面那个表盘。做仪表的芯片最主要需要支持显示Display,而仪表的主要排版布局多种多样,但是主旨显示内容不尽相同。 仪表需求: 1、rpm转速表盘 仪表Cluster一般会有转速表盘rpm,单位一般是x1000,大部分汽车仪表范围就是0~8,也就是最高8000…

【Vue3】深入理解Vue3路由器的工作原理to的两种写法

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

大数据 - HBase《一》- Hbase基本概念

目录 1.1. Hbase简介 1.2 Hbase,Hive, Mysql对比 1.3 Hbase数据模型 &#x1f959;region(区域) &#x1f959;rowkey(行键) &#x1f959;列族&#xff08;column family) &#x1f959;列&#xff08;column Qualifier) &#x1f959;版本&#xff08;version)-默认按…

Sui与数据平台ZettaBlock达成合作,为其公测提供数据

Sui一向以闪电般的速度、无限水平扩展著称&#xff0c;现已迅速成为DeFi活动的重要场所。近期&#xff0c;数据平台ZettaBlock宣布在其开创性的Web3数据平台发布中&#xff0c;选择Sui作为基础集成合作伙伴之一。在ZettaBlock的开放测试版发布之际&#xff0c;构建者和开发者将…

【node】初识node以及fs操作,path操作以及http操作(一)

1、不同浏览器使用不同的javaScript引擎 chrome > v8 Firefox > OdinMonkey&#xff08;奥丁猴&#xff09; safri > JSCore IE浏览器>Chakra(查克拉) 2、node是一个基于chrome v8引擎的javaScript运行环境 浏览器是JavaScript的前端运行环境&#xff0c;…

AcrelEMS-MED医院综合能效管理平台在医院电力中的应用

彭姝麟 Acrelpsl 0引言 全医院是公共服务组织&#xff0c;其机构的特殊性决定了医院在提供医疗服务的同时&#xff0c;也需要发挥榜样作用&#xff0c;通过进行能源管理系统的应用&#xff0c;为医院的电力使用和能源消耗进行好的管理&#xff0c;从而减少电能消耗&#xff0…

Web端3D图形引擎HOOPS Commuicator如何实现BIM轻量化?

面对建筑信息模型&#xff08;BIM&#xff09;中复杂大型模型的挑战&#xff0c;如何实现轻量化&#xff0c;并使其能在Web端流畅运行是我们需要解决的问题。而HOOPS Communicator正可凭借其出色的Web端3D模型敏捷解决性&#xff0c;为我们提供强有力的支撑。 HOOPS Communica…

【四】【算法分析与设计】贪心算法的初见

455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都有…

阿里云数据盘挂载目录

1、先登录服务器创建新目录aaa 2、云盘都快照备份下。后续操作完核实无误了&#xff0c;您根据您需求删除快照就行&#xff0c; 然后登录服务器内执行&#xff1a; fdisk -l lsblk blkid ll /aaa 3、执行&#xff1a;&#xff08;以下命令是进行数据盘做ext4文件系统并挂载到…

tigramite教程(五)使用TIGRAMITE 进行自助聚合和链接置信度量化

使用TIGRAMITE 进行自助聚合和链接置信度量化 自助聚合&#xff08;Bagging&#xff09;和置信度估计例子数据生成模型基本的PCMCIBagged-PCMCI使用优化后的pc_alpha进行自举聚合使用优化的pc_alpha进行CMIknn的自举聚合 TIGRAMITE是一个用于时间序列分析的Python模块。它基于P…