两个页面接入完成

This commit is contained in:
2026-05-19 22:40:52 +08:00
parent 3daebf56ab
commit 369783939b
32 changed files with 1165 additions and 590 deletions

View File

@@ -2,10 +2,10 @@ using System;
using System.Collections;
using System.IO;
using RenderStreaming;
using Script.Util;
using Stary.Evo;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
namespace Script
{
@@ -20,7 +20,7 @@ namespace Script
private MeetingContacts _meetingContacts;
private Transform _messageText;
private Transform _nameText;
private MeetingContacts.UsersItem _usersItem;
private MainPanel.UsersItem _usersItem;
private void OnDestroy()
{
@@ -33,14 +33,14 @@ namespace Script
return MainArchitecture.Interface;
}
public void SetData(MeetingContacts.UsersItem item, MeetingContacts meetingContactsController)
public void SetData(MainPanel.UsersItem item, MeetingContacts meetingContactsController)
{
_usersItem = item;
_meetingContacts = meetingContactsController;
///头像赋值
if (string.IsNullOrEmpty(item.avatar))
{
var randomColor = GetRandomColor();
var randomColor = WebRTCUtil.GetRandomColor();
_background = transform.Find("headBackground");
if (_background != null)
{
@@ -62,7 +62,7 @@ namespace Script
if (_background != null)
{
var imageComponent = _background.GetComponent<Image>();
if (imageComponent != null) DownloadAndSetAvatar(item.avatar, imageComponent);
if (imageComponent != null) WebRTCUtil.DownloadAndSetAvatar(item.avatar, imageComponent);
}
_backgroundName = _background.transform.Find("Name");
@@ -161,41 +161,5 @@ namespace Script
_confirmButton.interactable = true;
_confirmBtnTime.gameObject.SetActive(false);
}
private Color GetRandomColor()
{
return new Color(
Random.Range(0.2f, 0.8f),
Random.Range(0.2f, 0.8f),
Random.Range(0.2f, 0.8f),
1f
);
}
private async void DownloadAndSetAvatar(string avatarUrl, Image targetImage)
{
try
{
var tempPath = Path.Combine(Application.temporaryCachePath, $"avatar_{Guid.NewGuid()}.png");
var result = await WebRequestSystem.GetFile(avatarUrl, tempPath);
if (result.code == 200)
{
var bytes = File.ReadAllBytes(tempPath);
var texture = new Texture2D(2, 2);
texture.LoadImage(bytes);
var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height),
Vector2.one * 0.5f);
targetImage.sprite = sprite;
File.Delete(tempPath);
}
}
catch (Exception e)
{
Debug.LogError($"下载头像失败: {e.Message}");
}
}
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using Stary.Evo;
using Stary.Evo.UIFarme;
using UnityEngine;
using UnityEngine.UI;
@@ -12,13 +14,30 @@ namespace Script
/// </summary>
private Button _arrowLeft;
private Toggle _chatTog;
private Toggle _contactsTog;
private Toggle _meetingOrganizersTog;
/// <summary>
/// 房间ID
/// </summary>
private Text _idText;
/// <summary>
/// 会议联系人类和面板
/// </summary>
private MeetingContacts _meetingContacts;
/// <summary>
/// 会议参与者列表和面板
/// </summary>
private MeetingInfoList _meetingInfoList;
/// <summary>
/// 会议聊天面板
/// </summary>
private MeetingChat _meetingChat;
/// <summary>
/// 房间人数
/// </summary>
@@ -46,15 +65,30 @@ namespace Script
_arrowLeft = panelGo.transform.Find("Header/arrow-left").GetComponent<Button>();
_idText = panelGo.transform.Find("MeetingInfoCard/meeting/id").GetComponent<Text>();
_roomPeopleNumText = panelGo.transform.Find("MeetingInfoCard/numberOfPeople/number").GetComponent<Text>();
_chatTog = panelGo.transform.Find("Tabs/Chat").GetComponent<Toggle>();
_contactsTog = panelGo.transform.Find("Tabs/Contacts").GetComponent<Toggle>();
_meetingOrganizersTog = panelGo.transform.Find("Tabs/MeetingOrganizers").GetComponent<Toggle>();
_meetingContacts = new MeetingContacts();
_meetingContacts.Initialize(panelGo.transform.Find("MeetingContacts").gameObject);
_meetingInfoList = new MeetingInfoList();
_meetingInfoList.Initialize(panelGo.transform.Find("MeetingInfoList").gameObject);
_meetingChat = new MeetingChat();
_meetingChat.Initialize(panelGo.transform.Find("MeetingChat").gameObject);
}
public override void OnEnter(Action complete = null)
{
base.OnEnter(complete);
_meetingContacts.OnEnter();
_meetingInfoList.OnEnter();
_titleText.text = this.GetSystem<IGlobalConfigSystem>().GetConnectionName();
this.GetSystem<IGlobalConfigSystem>().StartConnectionTime(_timeText);
_arrowLeft.onClick.AddListener(OnArrowLeftClick);
_chatTog.onValueChanged.AddListener(OnChatTog);
_contactsTog.onValueChanged.AddListener(OnContactsTog);
_meetingOrganizersTog.onValueChanged.AddListener(OnMeetingOrganizersTog);
}
@@ -62,7 +96,27 @@ namespace Script
{
base.OnExit(delay);
_meetingContacts.OnExit();
_meetingInfoList.OnExit();
_arrowLeft.onClick.RemoveListener(OnArrowLeftClick);
_chatTog.onValueChanged.RemoveListener(OnChatTog);
_contactsTog.onValueChanged.RemoveListener(OnContactsTog);
_meetingOrganizersTog.onValueChanged.RemoveListener(OnMeetingOrganizersTog);
}
private void OnMeetingOrganizersTog(bool value)
{
_meetingInfoList.PanelGo.SetActive(value);
}
private void OnContactsTog(bool value)
{
_meetingContacts.PanelGo.SetActive(value);
if (value) _meetingContacts.OnEnter();
}
private void OnChatTog(bool value)
{
_meetingChat.PanelGo.SetActive(value);
}
private void OnArrowLeftClick()
@@ -73,5 +127,49 @@ namespace Script
{
base.OnDestroy();
}
[Serializable]
public class ResponseUsers
{
/// <summary>
/// </summary>
public List<UsersItem> users { get; set; }
/// <summary>
/// </summary>
public int totalCount { get; set; }
}
[Serializable]
public class UsersItem
{
/// <summary>
/// </summary>
public string socketId { get; set; }
/// <summary>
/// </summary>
public string connectionId { get; set; }
/// <summary>
/// </summary>
public string participantId { get; set; }
/// <summary>
/// </summary>
public string role { get; set; }
/// <summary>
/// </summary>
public string userId { get; set; }
/// <summary>
/// </summary>
public string name { get; set; }
/// <summary>
/// </summary>
public string avatar { get; set; }
}
}
}

View File

@@ -0,0 +1,29 @@
using RenderStreaming;
using Stary.Evo;
using UnityEngine;
namespace Script
{
public class MeetingChat : IController
{
public GameObject PanelGo;
public void Initialize(GameObject panelGo)
{
PanelGo = panelGo;
}
public async void OnEnter()
{
}
public async void OnExit()
{
}
public IArchitecture GetArchitecture()
{
return MainArchitecture.Interface;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c6a093f6facf40398f5a84d8c2c2e13f
timeCreated: 1779162068

View File

@@ -16,7 +16,7 @@ namespace Script
/// Key: 参与者ID
/// Value: 联系人列表项实例
/// </summary>
private readonly Dictionary<GameObject, ContactEntryController> _contactEntries = new();
private readonly List<ContactEntryController> _contactEntries = new();
private Image _avatarImage;
private Button _cancelButton;
@@ -39,10 +39,12 @@ namespace Script
private Text _messageText;
private Text _nameText;
private GameObject _panelGo;
public GameObject PanelGo;
public ContactEntryController CurrentEntry { get; set; }
private GameObjectPool _objectPool;
public IArchitecture GetArchitecture()
{
return MainArchitecture.Interface;
@@ -50,12 +52,12 @@ namespace Script
public void Initialize(GameObject panelGo)
{
_panelGo = panelGo;
PanelGo = panelGo;
_contactEntryPrefab = Resources.Load<GameObject>("ContactEntry");
_content = _panelGo.transform.Find("MeetingGrid/Viewport/Content");
_content = PanelGo.transform.Find("MeetingGrid/Viewport/Content");
//邀请界面
_confirmingPop = _panelGo.transform.Find("MeetingGrid/ConfirmingPop").gameObject;
_confirmingPop = PanelGo.transform.Find("MeetingGrid/ConfirmingPop").gameObject;
_confirmingPop.SetActive(false);
//确认邀请
_idText = _confirmingPop.transform.Find("bg/id").GetComponent<Text>();
@@ -66,21 +68,28 @@ namespace Script
_avatarImage = _confirmingPop.transform.Find("ParticipantEntry/head").GetComponent<Image>();
_nameText = _confirmingPop.transform.Find("ParticipantEntry/Name").GetComponent<Text>();
_messageText = _confirmingPop.transform.Find("ParticipantEntry/Message").GetComponent<Text>();
_objectPool = PanelGo.transform.Find("MeetingGrid/Pool").GetComponent<GameObjectPool>();
}
public async void OnEnter()
{
foreach (var entry in _contactEntries)
_objectPool.Release(entry.gameObject);
_contactEntries.Clear();
var response =
await WebRequestSystem.Get<ResponseUsers>(this.GetSystem<IGlobalConfigSystem>().IP, "/signaling/users");
await WebRequestSystem.Get<MainPanel.ResponseUsers>(this.GetSystem<IGlobalConfigSystem>().IP,
"/signaling/users");
if (response != null && response.totalCount > 0)
for (var i = 0; i < response.totalCount; i++)
{
var item = response.users[i];
if (string.IsNullOrEmpty(item.name) ||
string.IsNullOrEmpty(item.userId)) continue;
var entry = GameObject.Instantiate(_contactEntryPrefab, _content);
var entry = _objectPool.Get();
var contactEntryController = entry.GetOrAddComponent<ContactEntryController>();
contactEntryController.SetData(item, this);
_contactEntries.Add(contactEntryController);
}
}
@@ -89,7 +98,7 @@ namespace Script
{
}
public void ClickContactEntry(Sprite avatarImage, string name, UsersItem item)
public void ClickContactEntry(Sprite avatarImage, string name, MainPanel.UsersItem item)
{
_confirmingPop.SetActive(true);
@@ -119,7 +128,8 @@ namespace Script
inviterName = this.GetSystem<IGlobalConfigSystem>().GetConnectionName(),
inviterAvatar =
$"{this.GetSystem<IGlobalConfigSystem>().IP}/images/head/" +
$"{this.GetSystem<IGlobalConfigSystem>().GetConnectionTexture().name}.png"
$"{this.GetSystem<IGlobalConfigSystem>().GetConnectionTexture()}.png",
applyReason = _leaveMessage.text
}
};
SignalingMessageHelper.SendMessage(JsonConvert.SerializeObject(userInfo));
@@ -130,59 +140,5 @@ namespace Script
CurrentEntry = null;
});
}
public class ContactEntryData
{
public string avatar;
public GameObject entry;
public Toggle invitationTog;
public string name;
public string participantId;
public string role;
}
[Serializable]
public class ResponseUsers
{
/// <summary>
/// </summary>
public List<UsersItem> users { get; set; }
/// <summary>
/// </summary>
public int totalCount { get; set; }
}
[Serializable]
public class UsersItem
{
/// <summary>
/// </summary>
public string socketId { get; set; }
/// <summary>
/// </summary>
public string connectionId { get; set; }
/// <summary>
/// </summary>
public string participantId { get; set; }
/// <summary>
/// </summary>
public string role { get; set; }
/// <summary>
/// </summary>
public string userId { get; set; }
/// <summary>
/// </summary>
public string name { get; set; }
/// <summary>
/// </summary>
public string avatar { get; set; }
}
}
}

View File

@@ -0,0 +1,244 @@
using System.Collections.Generic;
using RenderStreaming;
using Script.Util;
using Stary.Evo;
using Unity.RenderStreaming;
using UnityEngine;
using UnityEngine.UI;
namespace Script
{
public class MeetingInfoList : IController
{
public GameObject PanelGo;
/// <summary>
/// 联系人列表项预制体
/// </summary>
private GameObject _contactEntryPrefab;
/// <summary>
/// 全部联系人列表容器
/// </summary>
private Transform _content;
private Text _meetingNum;
private Dictionary<string, MessageRecordInfo> _meetingList = new();
private GameObjectPool _objectPool;
public void Initialize(GameObject panelGo)
{
PanelGo = panelGo;
_contactEntryPrefab = Resources.Load<GameObject>("ParticipantEntry");
_content = panelGo.transform.Find("MeetingGrid/Viewport/Content");
_meetingNum = panelGo.transform.Find("MeetingNum/Num").GetComponent<Text>();
_objectPool = PanelGo.transform.Find("MeetingGrid/Pool").GetComponent<GameObjectPool>();
}
public void OnEnter()
{
LoadUsers();
GameObject.FindObjectOfType<MessageChannel>().OnMediaStateChangeReceived += OnMediaStateChangeReceived;
GameObject.FindObjectOfType<MessageChannel>().OnUserInfoMessageReceived += OnUserInfoMessageReceived;
GameObject.FindObjectOfType<HostConnection>().OnParticipantDisconnected += OnParticipantDisconnected;
}
/// <summary>
/// 当有用户断开连接时调用
/// </summary>
/// <param name="id"></param>
private void OnParticipantDisconnected(string id)
{
var userId = "";
foreach (var value in _meetingList.Values)
if (value.item.participantId == id)
{
_objectPool.Release(value.participant);
userId = value.item.userId;
break;
}
_meetingList.Remove(userId);
}
/// <summary>
/// 当有用户加入会议时调用
/// </summary>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
private void OnUserInfoMessageReceived(string arg1, UserInfo arg2)
{
foreach (var info in _meetingList.Values) _objectPool.Release(info.participant);
_meetingList.Clear();
LoadUsers();
}
/// <summary>
/// 当有用户媒体状态改变时调用
/// </summary>
/// <param name="connectionId"></param>
/// <param name="message"></param>
private async void OnMediaStateChangeReceived(string connectionId, MediaStateChange message)
{
Debug.Log($"OnMediaStateChangeReceived: {message}");
if (_meetingList.ContainsKey(message.userId))
{
var info = _meetingList[message.userId];
SetMediaStateMic(info.participant, message.audio);
SetMediaStateVideo(info.participant, message.video);
}
}
private async void LoadUsers()
{
var response =
await WebRequestSystem.Get<MainPanel.ResponseUsers>(this.GetSystem<IGlobalConfigSystem>().IP,
$"/signaling/users?connectionId={this.GetSystem<IGlobalConfigSystem>().GetConnectionId()}");
if (response != null && response.totalCount > 0)
{
_meetingNum.text = response.totalCount.ToString();
for (var i = 0; i < response.totalCount; i++)
{
var item = response.users[i];
if (string.IsNullOrEmpty(item.name) ||
string.IsNullOrEmpty(item.userId)) continue;
var entry = _objectPool.Get();
SetData(entry, item);
}
}
}
public void SetData(GameObject entry, MainPanel.UsersItem item)
{
var transform = entry.transform;
///头像赋值
var background = transform.Find("headBackground");
var backgroundName = background.transform.Find("Name");
if (string.IsNullOrEmpty(item.avatar))
{
var randomColor = WebRTCUtil.GetRandomColor();
if (background != null)
{
var image = background.GetComponent<Image>();
if (image != null) image.color = randomColor;
}
if (backgroundName != null)
{
var textComponent = backgroundName.GetComponent<Text>();
if (textComponent != null && !string.IsNullOrEmpty(item.name))
textComponent.text = item.name.Substring(0, 1);
}
}
else
{
background = transform.Find("headBackground");
if (background != null)
{
var imageComponent = background.GetComponent<Image>();
if (imageComponent != null) WebRTCUtil.DownloadAndSetAvatar(item.avatar, imageComponent);
}
if (backgroundName != null) backgroundName.GetComponent<Text>().text = "";
}
if (!string.IsNullOrEmpty(item.name))
{
var nameText = transform.Find("Name");
if (nameText != null)
{
var textComponent = nameText.GetComponent<Text>();
if (textComponent != null) textComponent.text = item.name;
}
}
if (!string.IsNullOrEmpty(item.userId))
{
var messageText = transform.Find("Message");
if (messageText != null)
{
var textComponent = messageText.GetComponent<Text>();
if (textComponent != null) textComponent.text = item.userId;
}
}
if (!string.IsNullOrEmpty(item.role))
{
var role = item.role;
var participant = transform.Find("Name/state/participant");
var host = transform.Find("Name/state/host");
if (role.Equals("host"))
{
host.gameObject.SetActive(true);
participant.gameObject.SetActive(false);
SetMediaStateMic(entry, true);
SetMediaStateVideo(entry, true);
}
else if (role.Equals("participant"))
{
participant.gameObject.SetActive(true);
host.gameObject.SetActive(false);
SetMediaStateMic(entry, false);
SetMediaStateVideo(entry, true);
}
}
_meetingList.Add(item.userId, new MessageRecordInfo(item, entry));
}
private void SetMediaStateMic(GameObject entry, bool isAudio)
{
var mic = entry.transform.Find("mic");
var micBackground = mic.transform.Find("Background");
var micCheckmark = mic.transform.Find("Checkmark");
micCheckmark.gameObject.SetActive(isAudio);
micBackground.gameObject.SetActive(!isAudio);
}
private void SetMediaStateVideo(GameObject entry, bool isVideo)
{
var video = entry.transform.Find("video");
var videoBackground = video.transform.Find("Background");
var videoCheckmark = video.transform.Find("Checkmark");
videoCheckmark.gameObject.SetActive(isVideo);
videoBackground.gameObject.SetActive(!isVideo);
}
public async void OnExit()
{
GameObject.FindObjectOfType<MessageChannel>().OnMediaStateChangeReceived -= OnMediaStateChangeReceived;
GameObject.FindObjectOfType<MessageChannel>().OnUserInfoMessageReceived -= OnUserInfoMessageReceived;
GameObject.FindObjectOfType<HostConnection>().OnParticipantDisconnected -= OnParticipantDisconnected;
}
public class MessageRecordInfo
{
public MainPanel.UsersItem item;
public GameObject participant;
public MessageRecordInfo(MainPanel.UsersItem item, GameObject participant)
{
this.item = item;
this.participant = participant;
}
}
public IArchitecture GetArchitecture()
{
return MainArchitecture.Interface;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 808f780c6849419d8c7235091a0295e7
timeCreated: 1779162087