结果展示:
界面搭建:
1.ChattingPanel(根据名字和后缀可以知道类型,无明确类型的,为空物体)
2.WorldMyChatItem(根据名字和后缀可以知道类型,无明确类型的,为空物体)
3.WorldOtherPeopleChatItem(根据名字和后缀可以知道类型,无明确类型的,为空物体)
代码:一共三个脚本
1.ChattingPanel.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ChattingPanel : MonoBehaviour
{
public GameObject chattingPanel_Go;
Button m_OtherChat_Btn;
Button m_MyChat_Btn;
Button m_Close_Btn;
GameObject m_World_Go;
Button m_NewMessage_Btn;
Text m_NewMessage_Txt;
InputField m_Msg_InputField;
GameObject m_WorldChatPanel_Go;
Transform m_ChatContent_Ts;
private string valueText;
//输入框输入最大字节
int MaxLimit = 80;
//发送信息倒计时
int countTimeNum = 10;
//显示的最大聊天数量
int showMaxNum = 200;
//几条新消息
int newMessageNum = 0;
//所有的聊天(最大长度是展示的两倍)
List<GameObject> allChatItemList = new List<GameObject>();
//展示的聊天
List<GameObject> chatItemShowList = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
allChatItemList.Clear();
chatItemShowList.Clear();
FunFind();
OnCloseNewMessage();
this.AddUIListener();
}
void FunFind()
{
m_OtherChat_Btn = chattingPanel_Go.transform.Find("root/TopBtns/OtherChat_Btn").GetComponent<Button>();
m_MyChat_Btn = chattingPanel_Go.transform.Find("root/TopBtns/MyChat_Btn").GetComponent<Button>();
m_Close_Btn = chattingPanel_Go.transform.Find("root/Close_Btn").GetComponent<Button>();
m_World_Go = chattingPanel_Go.transform.Find("root/World_Go").gameObject;
m_NewMessage_Btn = chattingPanel_Go.transform.Find("root/World_Go/NewMessage_Btn").GetComponent<Button>();
m_NewMessage_Txt = chattingPanel_Go.transform.Find("root/World_Go/NewMessage_Btn/NewMessage_Txt").GetComponent<Text>();
m_Msg_InputField = chattingPanel_Go.transform.Find("root/World_Go/Msg_InputField").GetComponent<InputField>();
m_WorldChatPanel_Go = chattingPanel_Go.transform.Find("root/World_Go/WorldChatPanel_Go").gameObject;
m_ChatContent_Ts = chattingPanel_Go.transform.Find("root/World_Go/WorldChatPanel_Go/Viewport/ChatContent_Ts").GetComponent<Transform>();
}
void AddUIListener()
{
m_Close_Btn.onClick.AddListener(OnClose);
m_OtherChat_Btn.onClick.AddListener(OnOtherInfo);
m_MyChat_Btn.onClick.AddListener(OnSendMessage);
m_NewMessage_Btn.onClick.AddListener(OnClickNewMessage);
//用户输入文本时就会调用
m_Msg_InputField.onValueChanged.AddListener(ChangedValue);
m_WorldChatPanel_Go.GetComponent<ScrollRect>().onValueChanged.AddListener(FunScrollRectChangeValue);
}
private void OnClose()
{
chattingPanel_Go.SetActive(false);
}
//发送消息
private void OnSendMessage()
{
if (string.IsNullOrEmpty(m_Msg_InputField.text))
{
Debug.Log("输入不可为空");
return;
}
GameObject chatItem = null;
if (chatItemShowList.Count <= showMaxNum)
{
chatItem = (GameObject)Instantiate(Resources.Load("WorldMyChatItem"));
}
else
{
bool isHave = false;
for (int i = 0; i < allChatItemList.Count - showMaxNum; i++)
{
allChatItemList[i].SetActive(false);
}
for (int i = 0; i < allChatItemList.Count - showMaxNum; i++)
{
if (allChatItemList[i].name == "WorldMyChatItem")
{
chatItem = allChatItemList[i];
allChatItemList.RemoveAt(i);
isHave = true;
break;
}
}
if (!isHave)
{
chatItem = (GameObject)Instantiate(Resources.Load("WorldMyChatItem"));
}
chatItemShowList.RemoveAt(0);
chatItem.SetActive(false);
}
WorldMyChatItem myChatItem = chatItem.transform.GetComponent<WorldMyChatItem>();
myChatItem.Init(m_Msg_InputField.text);
chatItem.name = "WorldMyChatItem";
chatItem.transform.SetParent(m_ChatContent_Ts);
chatItem.transform.localScale = Vector3.one;
chatItem.transform.localPosition = Vector3.zero;
chatItem.transform.SetAsLastSibling();
chatItem.SetActive(true);
this.chatItemShowList.Add(chatItem);
this.allChatItemList.Add(chatItem);
m_Msg_InputField.text = "";
OnClickNewMessage();
}
//其他人消息
private void OnOtherInfo()
{
if (string.IsNullOrEmpty(m_Msg_InputField.text))
{
Debug.Log("输入不可为空");
return;
}
GameObject chatItem = null;
if (chatItemShowList.Count <= showMaxNum)
{
chatItem = (GameObject)Instantiate(Resources.Load("WorldOtherPeopleChatItem"));
}
else
{
bool isHave = false;
for (int i = 0; i < allChatItemList.Count - showMaxNum; i++)
{
allChatItemList[i].SetActive(false);
}
for (int i = 0; i < allChatItemList.Count - showMaxNum; i++)
{
if (allChatItemList[i].name == "WorldOtherPeopleChatItem")
{
chatItem = allChatItemList[i];
allChatItemList.RemoveAt(i);
isHave = true;
break;
}
}
if (!isHave)
{
chatItem = (GameObject)Instantiate(Resources.Load("WorldOtherPeopleChatItem"));
}
chatItemShowList.RemoveAt(0);
chatItem.SetActive(false);
}
WorldOtherPeopleChatItem myChatItem = chatItem.transform.GetComponent<WorldOtherPeopleChatItem>();
myChatItem.Init(m_Msg_InputField.text);
chatItem.name = "WorldOtherPeopleChatItem";
chatItem.transform.SetParent(m_ChatContent_Ts);
chatItem.transform.localScale = Vector3.one;
chatItem.transform.localPosition = Vector3.zero;
chatItem.transform.SetAsLastSibling();
chatItem.SetActive(true);
this.chatItemShowList.Add(chatItem);
this.allChatItemList.Add(chatItem);
m_Msg_InputField.text = "";
if (m_WorldChatPanel_Go.GetComponent<ScrollRect>().verticalNormalizedPosition <= 2f / this.chatItemShowList.Count)
{
StartCoroutine(SetScrollView());
}
else
{
newMessageNum++;
if (newMessageNum >= 99)
{
newMessageNum = 99;
}
m_NewMessage_Btn.gameObject.SetActive(true);
m_NewMessage_Txt.text = newMessageNum + "条新消息";
}
}
IEnumerator SetScrollView()
{
yield return null;
m_WorldChatPanel_Go.GetComponent<ScrollRect>().verticalNormalizedPosition = 0;
}
//点击新消息提示
private void OnClickNewMessage()
{
StartCoroutine(SetScrollView());
OnCloseNewMessage();
}
//关闭新消息提示
void OnCloseNewMessage()
{
newMessageNum = 0;
m_NewMessage_Btn.gameObject.SetActive(false);
}
//用户输入时的变化
private void ChangedValue(string value)
{
if (System.Text.Encoding.UTF8.GetBytes(value).Length > MaxLimit)
{
m_Msg_InputField.text = valueText;
return;
}
valueText = value;//将用户输入的值赋值给内部的空字符串,我们可以将其来进行后续的操作
m_Msg_InputField.text = value;
}
//ScrollRect滚动监听,判断是否移动到了下面
void FunScrollRectChangeValue(Vector2 vector2)
{
if (m_WorldChatPanel_Go.GetComponent<ScrollRect>().verticalNormalizedPosition <= 2f / this.chatItemShowList.Count)
{
m_NewMessage_Btn.gameObject.SetActive(false);
}
}
}
2.WorldMyChatItem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class WorldMyChatItem : MonoBehaviour
{
public Text m_PlayerName_Txt;
public Image m_HeadIcon_Img;
public Image m_HeadIconEdge_Img;
public Image m_DialogBg_Img;
public Text m_Msg_Txt;
public TextGenerator textGenerator;
TextGenerationSettings settings;
float width;//气泡的宽度
bool isShow = false;
// Start is called before the first frame update
void Awake()
{
m_PlayerName_Txt = this.gameObject.transform.Find("PlayerName_Txt").GetComponent<Text>();
m_HeadIcon_Img = this.gameObject.transform.Find("HeadIcon_Img").GetComponent<Image>();
m_HeadIconEdge_Img = this.gameObject.transform.Find("HeadIconEdge_Img").GetComponent<Image>();
m_DialogBg_Img = this.gameObject.transform.Find("DialogBg_Img").GetComponent<Image>();
m_Msg_Txt = this.gameObject.transform.Find("DialogBg_Img/Msg_Txt").GetComponent<Text>();
}
public void Init(string str)
{
gameObject.SetActive(true);
m_Msg_Txt.text = str;
width = m_DialogBg_Img.GetComponent<RectTransform>().rect.width;
textGenerator = m_Msg_Txt.cachedTextGeneratorForLayout;
//显示省略号,与OnText()二选一
//SetTextWithEllipsis();
OnText();
}
void OnText()
{
settings = m_Msg_Txt.GetGenerationSettings(Vector2.zero);
Canvas.ForceUpdateCanvases();
//获取显示文本的长和宽
float textHeight = m_Msg_Txt.GetComponent<RectTransform>().rect.height;
float textWidth = textGenerator.GetPreferredWidth(m_Msg_Txt.text, settings) / m_Msg_Txt.pixelsPerUnit;
//修改聊天背景框的大小
if (textWidth <= width)
{
m_DialogBg_Img.GetComponent<RectTransform>().sizeDelta = new Vector2(textWidth + 70, textHeight + 30);
m_DialogBg_Img.GetComponent<RectTransform>().anchoredPosition = new Vector2((textWidth / 2 * -1) - 210, -60);
}
else
{
m_DialogBg_Img.GetComponent<RectTransform>().sizeDelta = new Vector2(width + 70, textHeight + 30);
m_DialogBg_Img.GetComponent<RectTransform>().anchoredPosition = new Vector2((width / 2 * -1) - 210, -60);
}
isShow = true;
}
void LateUpdate()
{
if (isShow)
{
//修改item的大小,排列使用
//放在LateUpdate,延迟渲染
gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(gameObject.GetComponent<RectTransform>().rect.width, m_Msg_Txt.GetComponent<RectTransform>().rect.height + 100);
isShow = false;
}
}
/// <summary>
/// 文本超出部分省略号
/// </summary>
/// <param name="textTemp">目标文本框</param>
/// <param name="value">文本</param>
private void SetTextWithEllipsis(Text textTemp, string value)
{
var generator = new TextGenerator();
var rectTransform = textTemp.GetComponent<RectTransform>();
//设置文本绘制范围
Vector2 vector2 = new Vector2(m_Msg_Txt.GetComponent<RectTransform>().rect.width, 100);
var settings = textTemp.GetGenerationSettings(vector2);
generator.Populate(value, settings);
//设置可见的字符数
var characterVisibleCount = generator.characterCountVisible;
var updateText = value;
//超出部分以省略号显示
if (value.Length > characterVisibleCount)
{
updateText = value.Substring(0, characterVisibleCount - 1);
updateText += "...";
}
textTemp.text = updateText;
}
}
3.WorldOtherPeopleChatItem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class WorldOtherPeopleChatItem : MonoBehaviour
{
public Text m_PlayerName_Txt;
public Image m_HeadIcon_Img;
public Image m_HeadIconEdge_Img;
public Button m_HeadIcon_Btn;
public Image m_DialogBg_Img;
public Text m_Msg_Txt;
public TextGenerator textGenerator;
TextGenerationSettings settings;
object m_Info;
float width;//气泡的宽度
bool isShow = false;
// Start is called before the first frame update
void Awake()
{
m_PlayerName_Txt = this.gameObject.transform.Find("PlayerName_Txt").GetComponent<Text>();
m_HeadIcon_Img = this.gameObject.transform.Find("HeadIcon_Img").GetComponent<Image>();
m_HeadIconEdge_Img = this.gameObject.transform.Find("HeadIconEdge_Img").GetComponent<Image>();
m_HeadIcon_Btn = this.gameObject.transform.Find("HeadIcon_Btn").GetComponent<Button>();
m_DialogBg_Img = this.gameObject.transform.Find("DialogBg_Img").GetComponent<Image>();
m_Msg_Txt = this.gameObject.transform.Find("DialogBg_Img/Msg_Txt").GetComponent<Text>();
}
public void Init(string str)
{
gameObject.SetActive(true);
m_Msg_Txt.text = str;
width = m_DialogBg_Img.GetComponent<RectTransform>().rect.width;
textGenerator = m_Msg_Txt.cachedTextGeneratorForLayout;
OnText();
}
void OnText()
{
settings = m_Msg_Txt.GetGenerationSettings(Vector2.zero);
Canvas.ForceUpdateCanvases();
float textHeight = m_Msg_Txt.GetComponent<RectTransform>().rect.height;
float textWidth = textGenerator.GetPreferredWidth(m_Msg_Txt.text, settings) / m_Msg_Txt.pixelsPerUnit;
if (textWidth <= width)
{
m_DialogBg_Img.GetComponent<RectTransform>().sizeDelta = new Vector2(textWidth + 80, textHeight + 30);
m_DialogBg_Img.GetComponent<RectTransform>().anchoredPosition = new Vector2((textWidth / 2) + 200, -60);
}
else
{
m_DialogBg_Img.GetComponent<RectTransform>().sizeDelta = new Vector2(width + 80, textHeight + 30);
m_DialogBg_Img.GetComponent<RectTransform>().anchoredPosition = new Vector2((width / 2) + 200, -60);
}
isShow = true;
}
public void LateUpdate()
{
if (isShow)
{
gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(gameObject.GetComponent<RectTransform>().rect.width, m_Msg_Txt.GetComponent<RectTransform>().rect.height + 100);
isShow = false;
}
}
}
提示:如果这还不懂,就去下载项目看看吧