【游戏技术群】959392658  【游戏出海群】12067810
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2373

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 1418|回复: 52

[zhang273162308] Unity实用小工具或脚本——屏幕消息打印显示

[复制链接]  [移动端链接]
排名
137
昨日变化

116

主题

551

帖子

6751

积分

Rank: 9Rank: 9Rank: 9

UID
3579
好友
106
蛮牛币
4680
威望
0
注册时间
2013-9-10
在线时间
1441 小时
最后登录
2018-12-14

专栏作家社区QQ达人活力之星游戏蛮牛QQ群会员蛮牛哥

发表于 2018-9-11 16:15:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
一、前言
       在屏幕上打印游戏中的消息是经常需要的功能,本文实现一个带有一定特色的文字消息打印,效果如图所示:消息列表框会根据消息缓存的行数来决定显示速度,如果缓存列表里存储的消息行数比较多,则显示的速度会加快。另外,在打印消息的时候,还加入了一个输入光标“-”在每行消息的末尾,消息打印完毕则隐藏。该效果是在Unity的UGUI里实现,一个文本Text显示控件+一个背景图就可以搞定了。

printMessageShow.gif
二、实现
1、主要思路:先将消息按照一行一条存储到列表中;然后取出一条进行逐字符打印,并且删除列表中这一行。
[C#] 纯文本查看 复制代码
        if(listMessage.Count>0)
        {
            if(!isPrinting)
            {
                isPrinting = true;
                string tempPrintStr = listMessage[0];
                listMessage.RemoveAt(0);
                StartCoroutine(PrintMessage(tempPrintStr));
            }
        }


打印这一行消息的时候,首先将其转化成字符数组,然后按照一次显示的文字行数= 预设值的固定值 + 列表中存储的消息行数
如果队列中存储了很多待显示的消息,则加快显示的速度。在显示的过程中先产出尾部的光标(如果有的话),然后按照一次将要显示的文字个数将当前这条要显示的消息文字添加进来;接着追加上光标,如果超过了最大显示的行数,则删除;最后,文字显示结束后再次删除光标。

[C#] 纯文本查看 复制代码
 char[] tempMesCharactors = new char[256];

        //删除超过存储空间的文字
        if(255<strMes.Length)
        {
            strMes = strMes.Substring(0, 254);
        }
        //将每个文字分割开
        tempMesCharactors = strMes.ToCharArray();
        //获取当前已经显示的文字
        string tempCurScreenShowText = uiTextshowMessage.text;
        tempCurScreenShowText += "\n";

        //一次显示的文字行数= 预设值的固定值 + 列表中存储的消息行数
        //如果队列中存储了很多待显示的消息,则加快显示的速度
        int tempAdditionNum = ADDITION_NUM + listMessage.Count;

        for (int i = 0; i < tempMesCharactors.Length; i+=tempAdditionNum)
        {
            //暂时删除尾部的光标
            if (tempCurScreenShowText.EndsWith(CURSOR_STR))
            {
                tempCurScreenShowText = tempCurScreenShowText.Remove(tempCurScreenShowText.Length - 1);
            }

            //按照一次显示tempAdditionNum个将当前这条要显示的消息文字添加进来
            for (int j = 0; j < tempAdditionNum; j++)
            {
                if(i+j>=tempMesCharactors.Length)
                {
                    break;
                }
                tempCurScreenShowText += tempMesCharactors[i + j];
            }

            //追加光标
            tempCurScreenShowText += CURSOR_STR;
            //删除超过画面外的行
            string[] tempLines = tempCurScreenShowText.Split('\n');
            if(MAX_ROW_COUNT<tempLines.Length)
            {
                tempCurScreenShowText = "";
                //从后往前追加MAX_ROW_COUNT行
                for (int j = tempLines.Length-MAX_ROW_COUNT; j < tempLines.Length; j++)
                {
                    tempCurScreenShowText += tempLines[j];
                    if(j<tempLines.Length-1)
                    {
                        tempCurScreenShowText += "\n";
                    }
                }
            }

            uiTextshowMessage.text = tempCurScreenShowText;

            yield return new WaitForSeconds(0.001f);
        }

        //文字显示结束后,隐藏光标
        if(tempCurScreenShowText.EndsWith(CURSOR_STR))
        {
            tempCurScreenShowText = tempCurScreenShowText.Remove(tempCurScreenShowText.Length - 1);
            uiTextshowMessage.text = tempCurScreenShowText;
        }


2、完整的脚本代码
[C#] 纯文本查看 复制代码
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ScreenMessageCtr : MonoBehaviour {

    public static ScreenMessageCtr M_Instance
    {
        get
        {
            if(null==_instance)
            {
                _instance = FindObjectOfType<ScreenMessageCtr>();
            }
            return _instance;
        }
    }
    [SerializeField]
    private  TextMeshProUGUI uiTextshowMessage;

    private static ScreenMessageCtr _instance;

    private List<string> listMessage = new List<string>();
    private bool isPrinting = false;

    /// <summary>
    /// 显示的最大行数
    /// </summary>
    private const int MAX_ROW_COUNT = 6;
    /// <summary>
    /// 一次显示的字符数
    /// </summary>
    private const int ADDITION_NUM = 1;
    /// <summary>
    /// 光标文字
    /// </summary>
    private const string CURSOR_STR = "_";

    private int textNum = 0;
        // Use this for initialization
        void Start () {
        // 向sub screen添加换行(为了让第一条消息从最下面开始显示)
        uiTextshowMessage.text = "\n\n\n\n\n\n";
        // 游戏开始时显示消息
        AddMessage("Start PrintMessage");
        AddMessage(" ");
    }
        
        // Update is called once per frame
        void Update () {

        if(Input.GetKey(KeyCode.Space))
        {
            string textMes = "This is text message type one:" + textNum++;
            AddMessage(textMes);
        }

                if(listMessage.Count>0)
        {
            if(!isPrinting)
            {
                isPrinting = true;
                string tempPrintStr = listMessage[0];
                listMessage.RemoveAt(0);
                StartCoroutine(PrintMessage(tempPrintStr));
            }
        }
        }

    private IEnumerator PrintMessage(string strMes)
    {
        char[] tempMesCharactors = new char[256];

        //删除超过存储空间的文字
        if(255<strMes.Length)
        {
            strMes = strMes.Substring(0, 254);
        }
        //将每个文字分割开
        tempMesCharactors = strMes.ToCharArray();
        //获取当前已经显示的文字
        string tempCurScreenShowText = uiTextshowMessage.text;
        tempCurScreenShowText += "\n";

        //一次显示的文字行数= 预设值的固定值 + 列表中存储的消息行数
        //如果队列中存储了很多待显示的消息,则加快显示的速度
        int tempAdditionNum = ADDITION_NUM + listMessage.Count;

        for (int i = 0; i < tempMesCharactors.Length; i+=tempAdditionNum)
        {
            //暂时删除尾部的光标
            if (tempCurScreenShowText.EndsWith(CURSOR_STR))
            {
                tempCurScreenShowText = tempCurScreenShowText.Remove(tempCurScreenShowText.Length - 1);
            }

            //按照一次显示tempAdditionNum个将当前这条要显示的消息文字添加进来
            for (int j = 0; j < tempAdditionNum; j++)
            {
                if(i+j>=tempMesCharactors.Length)
                {
                    break;
                }
                tempCurScreenShowText += tempMesCharactors[i + j];
            }

            //追加光标
            tempCurScreenShowText += CURSOR_STR;
            //删除超过画面外的行
            string[] tempLines = tempCurScreenShowText.Split('\n');
            if(MAX_ROW_COUNT<tempLines.Length)
            {
                tempCurScreenShowText = "";
                //从后往前追加MAX_ROW_COUNT行
                for (int j = tempLines.Length-MAX_ROW_COUNT; j < tempLines.Length; j++)
                {
                    tempCurScreenShowText += tempLines[j];
                    if(j<tempLines.Length-1)
                    {
                        tempCurScreenShowText += "\n";
                    }
                }
            }

            uiTextshowMessage.text = tempCurScreenShowText;

            yield return new WaitForSeconds(0.001f);
        }

        //文字显示结束后,隐藏光标
        if(tempCurScreenShowText.EndsWith(CURSOR_STR))
        {
            tempCurScreenShowText = tempCurScreenShowText.Remove(tempCurScreenShowText.Length - 1);
            uiTextshowMessage.text = tempCurScreenShowText;
        }

        //结束显示处理
        isPrinting = false;
    }

    public void AddMessage(string mes)
    {
        listMessage.Add(mes);
    }
}


三、总结
1、能够同时存储N条数据,然后逐条逐字显示,在打印显示的过程中还有光标的效果,视觉感比较好
2、同时存储的信息再多也能显示出来,但是一条信息不能超过字符数组的长度,我这里设置为256,如果超过了就去掉,这里还可以优化一下
3、工程地址
游客,如果您要查看本帖隐藏内容请回复










回复

使用道具 举报

7日久生情
1626/5000
排名
1546
昨日变化
1

20

主题

200

帖子

1626

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
225323
好友
1
蛮牛币
395
威望
0
注册时间
2017-6-5
在线时间
610 小时
最后登录
2018-12-13
发表于 2018-9-11 17:19:53 | 显示全部楼层
非常实用的Debug小工具~!

回复 支持 反对

使用道具 举报

5熟悉之中
741/1000
排名
4848
昨日变化
29

0

主题

67

帖子

741

积分

Rank: 5Rank: 5

UID
283972
好友
2
蛮牛币
259
威望
0
注册时间
2018-6-3
在线时间
386 小时
最后登录
2018-12-15
发表于 2018-9-11 18:14:52 | 显示全部楼层
11111111111111111111

回复 支持 反对

使用道具 举报

7日久生情
3990/5000
排名
448
昨日变化
1

132

主题

671

帖子

3990

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
7831
好友
3
蛮牛币
7256
威望
0
注册时间
2013-11-12
在线时间
1303 小时
最后登录
2018-12-15

活力之星锦衣玉食

发表于 2018-9-11 20:47:59 | 显示全部楼层
富文本有用吗?

回复

使用道具 举报

7日久生情
3023/5000
排名
350
昨日变化

1

主题

377

帖子

3023

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
2219
好友
1
蛮牛币
8094
威望
0
注册时间
2013-8-19
在线时间
922 小时
最后登录
2018-12-14
发表于 2018-9-11 21:57:25 | 显示全部楼层
Unity实用小工具或脚本—

回复 支持 反对

使用道具 举报

4四处流浪
382/500
排名
5642
昨日变化
2

1

主题

25

帖子

382

积分

Rank: 4

UID
270889
好友
0
蛮牛币
546
威望
0
注册时间
2018-3-6
在线时间
116 小时
最后登录
2018-12-12
发表于 2018-9-12 08:25:11 | 显示全部楼层
战斗日志。

回复

使用道具 举报

7日久生情
2687/5000
排名
1072
昨日变化

0

主题

486

帖子

2687

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
155931
好友
0
蛮牛币
114
威望
0
注册时间
2016-7-8
在线时间
1189 小时
最后登录
2018-11-22
发表于 2018-9-12 08:27:15 | 显示全部楼层
6666666666666666666666666

回复 支持 反对

使用道具 举报

7日久生情
1585/5000
排名
1438
昨日变化
5

0

主题

467

帖子

1585

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
87577
好友
0
蛮牛币
5351
威望
0
注册时间
2015-3-31
在线时间
270 小时
最后登录
2018-12-15
发表于 2018-9-12 08:32:54 | 显示全部楼层
too good too strong!

回复 支持 反对

使用道具 举报

7日久生情
1778/5000
排名
2256
昨日变化
1

12

主题

830

帖子

1778

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
218409
好友
3
蛮牛币
5254
威望
0
注册时间
2017-4-19
在线时间
348 小时
最后登录
2018-12-14
发表于 2018-9-12 09:04:13 | 显示全部楼层
6666666666666666666666666666

回复 支持 反对

使用道具 举报

排名
22533
昨日变化
15

0

主题

13

帖子

66

积分

Rank: 2Rank: 2

UID
211128
好友
0
蛮牛币
91
威望
0
注册时间
2017-3-10
在线时间
34 小时
最后登录
2018-10-22
发表于 2018-9-12 09:18:15 | 显示全部楼层
666666666666666666666

回复 支持 反对

使用道具 举报

5熟悉之中
631/1000
排名
4943
昨日变化
3

1

主题

143

帖子

631

积分

Rank: 5Rank: 5

UID
224031
好友
3
蛮牛币
2058
威望
0
注册时间
2017-5-27
在线时间
203 小时
最后登录
2018-9-12
发表于 2018-9-12 09:22:30 | 显示全部楼层
66666666666666666

回复 支持 反对

使用道具 举报

2初来乍到
119/150
排名
14130
昨日变化
7

0

主题

38

帖子

119

积分

Rank: 2Rank: 2

UID
295054
好友
0
蛮牛币
84
威望
0
注册时间
2018-8-29
在线时间
27 小时
最后登录
2018-11-9
发表于 2018-9-12 09:23:29 | 显示全部楼层
666,感谢楼主分享

回复 支持 反对

使用道具 举报

7日久生情
2330/5000
排名
872
昨日变化
3

1

主题

675

帖子

2330

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
56496
好友
0
蛮牛币
7036
威望
0
注册时间
2014-11-19
在线时间
524 小时
最后登录
2018-12-15
发表于 2018-9-12 09:28:00 | 显示全部楼层
稳啊,其实我也想发一个上来的,可是懒

回复 支持 反对

使用道具 举报

5熟悉之中
667/1000
排名
3414
昨日变化
19

0

主题

105

帖子

667

积分

Rank: 5Rank: 5

UID
276682
好友
0
蛮牛币
1387
威望
0
注册时间
2018-4-11
在线时间
140 小时
最后登录
2018-12-15
发表于 2018-9-12 09:29:54 | 显示全部楼层
感谢分享

回复

使用道具 举报

4四处流浪
398/500
排名
6205
昨日变化
1

3

主题

46

帖子

398

积分

Rank: 4

UID
185502
好友
1
蛮牛币
1384
威望
0
注册时间
2016-11-21
在线时间
137 小时
最后登录
2018-11-28
发表于 2018-9-12 09:44:24 | 显示全部楼层
谢谢楼主分享
[发帖际遇]: 一个袋子砸在了 huxingyue 头上,huxingyue 赚了 1 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表