556 lines
21 KiB
C#
556 lines
21 KiB
C#
using asap.core;
|
|
using GameCore;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UniRx;
|
|
using UnityEngine.UI;
|
|
using game;
|
|
using System.Threading.Tasks;
|
|
using DG.Tweening;
|
|
using Game;
|
|
using TMPro;
|
|
using UnityEngine.Serialization;
|
|
|
|
|
|
public class ChallengeShowPlayerEvent
|
|
{
|
|
public int oldStep;
|
|
}
|
|
public class ChallengePlayAniEvent
|
|
{
|
|
public int oldStep;
|
|
public int newStep;
|
|
public TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
|
|
}
|
|
public class ChallengeFailEvent
|
|
{
|
|
public int oldStep;
|
|
public TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
|
|
}
|
|
|
|
// 定义显示Tips
|
|
//
|
|
public class ChallengeLevelTipsEvent
|
|
{
|
|
public bool IsGm;
|
|
public int oldScore;
|
|
public int newScore;
|
|
public TaskCompletionSource<bool> tcs = new();
|
|
}
|
|
|
|
public class ShowResidueNumEvent
|
|
{
|
|
public int num;
|
|
}
|
|
|
|
|
|
|
|
// 比赛场景中显示头像奖励等的UI,挂载与比赛场景上
|
|
public class ChallengeMatchSceneUI : MonoBehaviour
|
|
{
|
|
//
|
|
private Transform icon_reward;
|
|
private Transform text_title;
|
|
private Transform _textNumCash;
|
|
|
|
|
|
// 地点
|
|
public ChallengeMatchSceneUIRegion[] uiRegion;
|
|
|
|
public GameObject[] tipPlaceHolder;
|
|
|
|
public GameObject eventChallengeHead;
|
|
|
|
private EventChallengeLevelTips _levelTipController;
|
|
|
|
private FishingChallengeManager _fishingChallengeManager;
|
|
|
|
private List<EventChallengeHead> _headList = new();
|
|
|
|
private EventChallengeHead _myHead;
|
|
|
|
private int count;
|
|
|
|
private CompositeDisposable _disposables = new();
|
|
|
|
|
|
// 本人起跳间隔
|
|
[Header("本人起跳到其他人开始起跳")]
|
|
public float jumpIntervalMy = 0.1f;
|
|
//起跳间隔
|
|
[Header("其他人起跳开始间隔")]
|
|
public float jumpInterval = 0.1f;
|
|
// 最后一个起跳到淘汰时间
|
|
[Header("最后一人起跳到开始落水")]
|
|
public float jumpToEliminateTime = 0.6f;
|
|
// 落水到平台下沉时间
|
|
// [Header("开始落水到沉船")]
|
|
// public float eliminateToPlatformTime = 0.5f;
|
|
//int maxCount = 3;
|
|
[Header("每个人落水间隔")] public float eliminateInterval = 0.01f;
|
|
|
|
[Header("跳水动画时长")] public float jumpDuration = 0.6f;
|
|
|
|
[Header("淘汰落水时长")] public float jumpDead = 0.2f;
|
|
|
|
[Header("箱子破坏前延时")] public float BreakDuration = 0.1f;
|
|
|
|
private void Awake()
|
|
{
|
|
_fishingChallengeManager = GContext.container.Resolve<FishingChallengeManager>();
|
|
GetComponent<Canvas>().worldCamera = Camera.main;
|
|
_levelTipController = transform.Find("EventChallengeLevelTips").GetComponent<EventChallengeLevelTips>();
|
|
// _levelTipController.SetSpeed(speed);
|
|
// _levelTipController.UpdateControllerTime(uptime1, wait2, wait3);
|
|
|
|
// var evt = new ChallengeSetAnimationEvent()
|
|
// {
|
|
// speed = speed,
|
|
// timeForUnlocking = _timeForUnlocking,
|
|
// timeForUnLockingEnd = _timeForUnlockingEnd,
|
|
// timeForAttacking_1 = _timeForAttacking_1,
|
|
// timeForAttacking_2 = _timeForAttacking_2,
|
|
// timeForAttackStart = _timeForAttackStart,
|
|
// timeForAttackEnd = _timeForAttackEnd,
|
|
// timeForAttackEndWait = _timeForAttackEndEnd,
|
|
// };
|
|
// GContext.Publish(evt);
|
|
|
|
|
|
icon_reward = transform.Find("taizi_reward/icon_reward/icon_reward");
|
|
text_title = transform.Find("taizi_reward/total_reward/text_title");
|
|
_textNumCash = transform.Find("taizi_reward/total_reward/text_num_cash");
|
|
|
|
|
|
|
|
GContext.OnEvent<ChallengeShowPlayerEvent>().Subscribe(ShowPlayer).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengePlayAniEvent>().Subscribe(PlayAni).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengeFailEvent>().Subscribe(OnFail).AddTo(_disposables);
|
|
GContext.OnEvent<ChallengeLevelTipsEvent>().Subscribe(OnShowLevelTips).AddTo(_disposables);
|
|
}
|
|
private void Start()
|
|
{
|
|
var listItemData = GContext.container.Resolve<PlayerItemData>().GetItemDataByDropId(_fishingChallengeManager.eventChallengeMain.WinnerReward);
|
|
var totalCount = listItemData.Sum(itemData => itemData.count);
|
|
_textNumCash.GetComponent<TMP_Text>().text = "x" + ConvertTools.GetNumberString(totalCount);
|
|
InitLevelTip(_fishingChallengeManager.fishingChallengeData.ProcessedScore);
|
|
}
|
|
|
|
public void InitLevelTip(int score )
|
|
{
|
|
var step = _fishingChallengeManager.GetStepByScore(score,true);
|
|
if (step > tipPlaceHolder.Length - 1)
|
|
{
|
|
return;
|
|
}
|
|
_levelTipController.transform.localPosition = tipPlaceHolder[step].transform.localPosition;
|
|
_levelTipController.gameObject.SetActive(true);
|
|
_levelTipController.Init(score);
|
|
}
|
|
private void ShowPlayer(ChallengeShowPlayerEvent challengeShowPlayerEvent)
|
|
{
|
|
var oldStep = challengeShowPlayerEvent.oldStep;
|
|
var robots = GContext.container.Resolve<cfg.Tables>().TbRobot.DataMap;
|
|
var uiService = GContext.container.Resolve<IUIService>();
|
|
var randomPos = uiRegion[oldStep];
|
|
var posTran = randomPos.posTran;
|
|
var myself = randomPos.myself;
|
|
|
|
if (_headList.Count > 0)
|
|
{
|
|
_headList.ForEach(x => Destroy(x.gameObject));
|
|
_headList.Clear();
|
|
Destroy(_myHead.gameObject);
|
|
}
|
|
var residual = posTran.Count;
|
|
for (int i = 0; i < residual; i++)
|
|
{
|
|
GameObject go = Instantiate(eventChallengeHead.gameObject, posTran[i]);
|
|
go.transform.localScale = Vector3.one;
|
|
go.transform.localPosition = Vector3.zero;
|
|
var head = go.GetComponent<EventChallengeHead>();
|
|
if (robots.TryGetValue(_fishingChallengeManager.fishingChallengeData.robotAccountList[i], out cfg.Robot robot))
|
|
{
|
|
uiService.SetHeadImage(head.icon_head, robot.Avatar);
|
|
}
|
|
_headList.Add(head);
|
|
}
|
|
|
|
_myHead = Instantiate(eventChallengeHead.gameObject, myself).GetComponent<EventChallengeHead>();
|
|
_myHead.transform.localScale = Vector3.one;
|
|
_myHead.transform.localPosition = Vector3.zero;
|
|
_myHead.bg_head_myself.SetActive(true);
|
|
uiService.SetHeadImage(_myHead.icon_head, GContext.container.Resolve<IUserService>().AvatarUrl);
|
|
count = _headList.Count;
|
|
}
|
|
|
|
////打乱headList顺序
|
|
// void Shuffle(int curCount)
|
|
// {
|
|
// var newHeadList = new List<EventChallengeHead>();
|
|
// var robotAccountList = new List<int>();
|
|
// int index = 0;
|
|
// for (int i = 0; i < curCount; i++)
|
|
// {
|
|
// newHeadList.Insert(index, _headList[i]);
|
|
// robotAccountList.Insert(index, _fishingChallengeManager.fishingChallengeData.robotAccountList[i]);
|
|
// index = UnityEngine.Random.Range(0, newHeadList.Count + 1);
|
|
// }
|
|
// _headList = newHeadList;
|
|
// _fishingChallengeManager.fishingChallengeData.robotAccountList = robotAccountList;
|
|
// }
|
|
#if UNITY_EDITOR
|
|
bool isShow;
|
|
string oldStepStr, newStepStr;
|
|
private string _scoreStr; // 添加到渔获的价值
|
|
private int _level;
|
|
string oldScoreStr, newScoreStr;
|
|
private void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.K))
|
|
{
|
|
isShow = !isShow;
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.M))
|
|
{
|
|
_level = (_level + 1) % 7;
|
|
// _tipController.transform.localPosition = tipPlaceHolder[_level].transform.localPosition;
|
|
LocationLevelTips(_level);
|
|
}
|
|
|
|
}
|
|
private async void OnGUI()
|
|
{
|
|
|
|
GUILayout.Label($"当前段位: {_fishingChallengeManager.eventChallengeMain.ID}");
|
|
|
|
if (!isShow)
|
|
{
|
|
return;
|
|
}
|
|
// Set the button width and height
|
|
float buttonWidth = 300; // Replace with your desired width
|
|
float buttonHeight = 70; // Replace with your desired height
|
|
int fontSize = 40; // Replace with your desired font size
|
|
|
|
// Set the font size for text fields, buttons, and labels
|
|
GUI.skin.textField.fontSize = fontSize;
|
|
GUI.skin.button.fontSize = fontSize;
|
|
GUI.skin.label.fontSize = fontSize;
|
|
// 触发ChallengeShowPlayAniEvent 事件并能输入oldStep和newStep
|
|
GUILayout.Label("oldStep:");
|
|
oldStepStr = GUILayout.TextField(oldStepStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
|
int.TryParse(oldStepStr, out int oldStep);
|
|
if (GUILayout.Button("Fail"))
|
|
{
|
|
GContext.Publish(new ChallengeMatchPlayGMEvent() { step = oldStep });
|
|
ShowPlayer(new ChallengeShowPlayerEvent { oldStep = oldStep });
|
|
await Awaiters.Seconds(0.5f);
|
|
ChallengeFailEvent challengeFailEvent = new ChallengeFailEvent();
|
|
challengeFailEvent.oldStep = oldStep;
|
|
OnFail(challengeFailEvent);
|
|
}
|
|
GUILayout.Label("newStep:");
|
|
newStepStr = GUILayout.TextField(newStepStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
|
int.TryParse(newStepStr, out int newStep);
|
|
if (GUILayout.Button("PlayAni", GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)))
|
|
{
|
|
GContext.Publish(new ChallengeMatchPlayGMEvent() { step = oldStep });
|
|
ShowPlayer(new ChallengeShowPlayerEvent { oldStep = oldStep });
|
|
await Awaiters.Seconds(0.5f);
|
|
var challengePlayAniEvent = new ChallengePlayAniEvent();
|
|
challengePlayAniEvent.oldStep = oldStep;
|
|
challengePlayAniEvent.newStep = newStep;
|
|
PlayAni(challengePlayAniEvent);
|
|
}
|
|
|
|
GUILayout.Label("QualityScore:");
|
|
_scoreStr = GUILayout.TextField(_scoreStr,GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
|
int.TryParse(_scoreStr, out var score);
|
|
_fishingChallengeManager.SetQualityScore(score);
|
|
|
|
|
|
GUILayout.Label("oldScore:");
|
|
oldScoreStr = GUILayout.TextField(oldScoreStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
|
int.TryParse(oldScoreStr, out var oldScore);
|
|
//
|
|
GUILayout.Label("newScore:");
|
|
newScoreStr = GUILayout.TextField(newScoreStr, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight));
|
|
int.TryParse(newScoreStr, out var newScore);
|
|
//
|
|
if (GUILayout.Button("RunNewPlay", GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)))
|
|
{
|
|
// GContext.Publish(new ChallengeMatchPlayGMEvent() { step = oldStep });
|
|
var nStep = _fishingChallengeManager.GetStepByScore(oldScore,true);
|
|
var evt = new ChallengeInitStepEvent()
|
|
{
|
|
step = nStep
|
|
};
|
|
GContext.Publish(evt);
|
|
await Awaiters.NextFrame;
|
|
ShowPlayer(new ChallengeShowPlayerEvent { oldStep = nStep });
|
|
await Awaiters.Seconds(0.5f);
|
|
// 全部重置
|
|
|
|
var tipsEvent = new ChallengeLevelTipsEvent()
|
|
{
|
|
IsGm = true,
|
|
oldScore = oldScore,
|
|
newScore = newScore,
|
|
};
|
|
//OnShowLevelTips(tipsEvent);
|
|
GContext.Publish(tipsEvent);
|
|
}
|
|
}
|
|
#endif
|
|
private async void PlayAni(ChallengePlayAniEvent challengePlayAniEvent)
|
|
{
|
|
var oldStep = challengePlayAniEvent.oldStep;
|
|
var newStep = challengePlayAniEvent.newStep;
|
|
ChallengeMatchSceneUIRegion randomPos;
|
|
List<Transform> posTran;
|
|
Transform myself;
|
|
|
|
/// 更新剩余人数
|
|
ShowResidueNumEvent showResidueNumEvent = new ShowResidueNumEvent();
|
|
var eliminateNumber = _fishingChallengeManager.fishingChallengeData.eliminateNumber;
|
|
var newEliminate = _fishingChallengeManager.CalcResidualNumber(oldStep);
|
|
showResidueNumEvent.num = newEliminate;
|
|
GContext.Publish(showResidueNumEvent);
|
|
//
|
|
|
|
float speed = 1;
|
|
if (newStep > oldStep + 1)
|
|
{
|
|
speed = 0.7f;
|
|
}
|
|
|
|
//var uiRegionNum = uiRegion.Length;
|
|
//从oldStep到newStep
|
|
var brokeStepEvent = new ChallengeBrokeStepEvent
|
|
{
|
|
step = oldStep,
|
|
dealyTime = BreakDuration,
|
|
};
|
|
for (int i = oldStep; i < newStep; i++)
|
|
{
|
|
var regionIdx = Math.Min(uiRegion.Length - 1, i + 1);
|
|
randomPos = uiRegion[regionIdx];
|
|
posTran = randomPos.posTran;
|
|
myself = randomPos.myself;
|
|
int residual = posTran.Count;
|
|
// for (int j = 0; j < residual; j++)
|
|
// {
|
|
// _headList[j].rectTransform.SetParent(posTran[j]);
|
|
// }
|
|
// for (int j = residual; j < count; j++)
|
|
// {
|
|
// _headList[j].rectTransform.SetParent(posTran[residual - 1]);
|
|
// }
|
|
_myHead.rectTransform.SetParent(myself);
|
|
_myHead.rectTransform.localScale = Vector3.one;
|
|
_myHead.rectTransform.DOLocalMove(Vector3.zero,jumpDuration);
|
|
_myHead.headAni.Play("fx_anim_eventchallengehead_jump_success_01");
|
|
// 头狼起调
|
|
var myJumpAudioName = uiRegion[i].myJumpAudioName;
|
|
if (!string.IsNullOrEmpty(myJumpAudioName))
|
|
{
|
|
GContext.Publish(new EventUISound(myJumpAudioName));
|
|
}
|
|
await Awaiters.Seconds(jumpIntervalMy * speed);
|
|
// 跟随起跳
|
|
var followerJumpAudioName = uiRegion[i].followerJumpAudioName;
|
|
if (!string.IsNullOrEmpty(myJumpAudioName))
|
|
{
|
|
GContext.Publish(new EventUISound(followerJumpAudioName));
|
|
}
|
|
for (int j = 0; j < residual; j++)
|
|
{
|
|
await Awaiters.Seconds(jumpInterval * speed);
|
|
_headList[j].rectTransform.SetParent(posTran[j]);
|
|
_headList[j].rectTransform.DOLocalMove(Vector3.zero, jumpDuration).SetEase(Ease.OutCubic);
|
|
_headList[j].rectTransform.DOScale(Vector3.one, jumpDuration).SetEase(Ease.OutCubic);
|
|
_headList[j].headAni.Play("fx_anim_eventchallengehead_jump_success_01");
|
|
}
|
|
var posTranRect = uiRegion[i].posTranRect;
|
|
//淘汰动画
|
|
await Awaiters.Seconds(jumpToEliminateTime * speed);
|
|
// 播放动画声音
|
|
var audioName = uiRegion[i].fallAudioName;
|
|
if (!string.IsNullOrEmpty(audioName)){
|
|
GContext.Publish(new EventUISound(audioName));
|
|
}
|
|
|
|
//
|
|
int tranCount = posTranRect.Count;
|
|
RectTransform rectPos = posTranRect[0];
|
|
float width = 0, height = 0;
|
|
|
|
if (residual >= count)
|
|
{
|
|
GContext.Publish(brokeStepEvent);
|
|
}
|
|
else
|
|
{
|
|
for (int j = residual; j < count; j++)
|
|
{
|
|
if (tranCount > j - residual)
|
|
{
|
|
rectPos = posTranRect[j - residual];
|
|
width = rectPos.rect.width / 2;
|
|
height = rectPos.rect.height / 2;
|
|
}
|
|
|
|
Vector3 vector3 = new Vector3(UnityEngine.Random.Range(-width, width),
|
|
UnityEngine.Random.Range(-height, height), 0);
|
|
await Awaiters.Seconds(eliminateInterval * speed);
|
|
_headList[j].rectTransform.SetParent(rectPos);
|
|
_headList[j].rectTransform.DOScale(Vector3.one, jumpDead).SetEase(Ease.Linear);
|
|
_headList[j].rectTransform.DOLocalMove(vector3, jumpDead).SetEase(Ease.Linear);
|
|
_headList[j].headAni.Play("fx_anim_eventchallengehead_jump_defeat_01");
|
|
if (j == residual)
|
|
{
|
|
// 播放破坏动画
|
|
GContext.Publish(brokeStepEvent);
|
|
}
|
|
}
|
|
}
|
|
|
|
//从i到i+1平台,起点0不动
|
|
if (i > 0)
|
|
{
|
|
// await Awaiters.Seconds(eliminateToPlatformTime * speed );
|
|
GContext.Publish(new ChallengeMatchPlayEvent() { step = i });
|
|
}
|
|
|
|
count = residual;
|
|
newEliminate -= eliminateNumber[i];
|
|
showResidueNumEvent.num = newEliminate;
|
|
GContext.Publish(showResidueNumEvent);
|
|
|
|
// if (i < eliminateNumber.Count - 2)
|
|
// {
|
|
// _fishingChallengeManager.AddStageReward(i);
|
|
// }
|
|
|
|
// 直接写添加奖品
|
|
// var itemDataList = playerItemData.GetItemDataByDropId(eventChallengeMain.StageReward[newStep], fishingChallengeData.mapId);
|
|
// playerItemData.AddItem(itemDataList);
|
|
await Awaiters.Seconds(1f * speed);
|
|
await brokeStepEvent.Tcs.Task; //
|
|
}
|
|
challengePlayAniEvent.tcs.SetResult(true);
|
|
}
|
|
private async void OnFail(ChallengeFailEvent challengeFailEvent)
|
|
{
|
|
int oldStep = challengeFailEvent.oldStep;
|
|
var rectPos = uiRegion[oldStep].myselfRect;
|
|
//淘汰动画
|
|
float width = rectPos.rect.width / 2;
|
|
float height = rectPos.rect.height / 2;
|
|
Vector3 vector3 = new Vector3(UnityEngine.Random.Range(-width, width), UnityEngine.Random.Range(-height, height), 0);
|
|
_myHead.rectTransform.SetParent(rectPos);
|
|
_myHead.rectTransform.localScale = Vector3.one;
|
|
_myHead.rectTransform.DOLocalMove(vector3, 0.2f).SetEase(Ease.Linear);
|
|
_myHead.headAni.Play("fx_anim_eventchallengehead_jump_defeat_01");
|
|
await Awaiters.Seconds(1f);
|
|
challengeFailEvent.tcs.SetResult(true);
|
|
}
|
|
|
|
// 注意多组的情况,根据分数算,可能要跳好多次
|
|
private async void OnShowLevelTips(ChallengeLevelTipsEvent tipsEvent)
|
|
{
|
|
Log("OnShowLevelTips");
|
|
var oldScore = tipsEvent.oldScore;
|
|
var newScore = tipsEvent.newScore;
|
|
var isGm = tipsEvent.IsGm;
|
|
|
|
if (oldScore == newScore)
|
|
{
|
|
InitLevelTip(oldScore);
|
|
tipsEvent.tcs.SetResult(true);
|
|
return;
|
|
}
|
|
var step = _fishingChallengeManager.GetStepByScore(oldScore,true);
|
|
var maxScore = _fishingChallengeManager.GetMaxScoreByStep(step);
|
|
if (_levelTipController && step >= 0 && step < tipPlaceHolder.Length )
|
|
{
|
|
LocationLevelTips(step);
|
|
var curScore = await _levelTipController.ShowTips(oldScore,newScore);
|
|
// 播放显示动画
|
|
if (maxScore == curScore)
|
|
{
|
|
await _levelTipController.PlayInVisibleAni();
|
|
await ReceiveStageReward(step);
|
|
await JumpStage(step, curScore, newScore,isGm);
|
|
}
|
|
}
|
|
tipsEvent.tcs.SetResult(true);
|
|
}
|
|
|
|
private void LocationLevelTips(int step)
|
|
{
|
|
_levelTipController.transform.localPosition = tipPlaceHolder[step].transform.localPosition;
|
|
_levelTipController.SetCurStep(step);
|
|
_levelTipController.gameObject.SetActive(true);
|
|
}
|
|
|
|
|
|
// 看看需要加什么动画类的东西么
|
|
public async Task ReceiveStageReward(int step)
|
|
{
|
|
Log($"ReceiveStageReward {step}");
|
|
_fishingChallengeManager.AddStageReward(step);
|
|
}
|
|
|
|
private static async Task JumpStage(int step, int curScore, int newScore,bool isGm)
|
|
{
|
|
Log("JumpStage");
|
|
// 清理下一个台子
|
|
var cleanEvent = new ChallengeCleanStageEvent
|
|
{
|
|
stage = step + 1,
|
|
};
|
|
GContext.Publish(cleanEvent);
|
|
await cleanEvent.Tcs.Task;
|
|
|
|
// 播放跳跃动画
|
|
var cspe = new ChallengePlayAniEvent() { oldStep = step, newStep = step + 1 };
|
|
GContext.Publish(cspe);
|
|
await cspe.tcs.Task;
|
|
|
|
// // 播放破坏动画
|
|
// var brokeStepEvent = new ChallengeBrokeStepEvent { step = step };
|
|
// GContext.Publish(brokeStepEvent);
|
|
// await brokeStepEvent.Tcs.Task;
|
|
|
|
// -- 进入下一个循环
|
|
// if (curScore != newScore || newScore == maxScore)
|
|
// {
|
|
var nextStageEvent = new ChallengeLevelTipsEvent
|
|
{
|
|
oldScore = curScore,
|
|
newScore = newScore,
|
|
IsGm = isGm,
|
|
};
|
|
GContext.Publish(nextStageEvent);
|
|
await nextStageEvent.tcs.Task;
|
|
// }
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
_disposables?.Dispose();
|
|
_disposables = null;
|
|
}
|
|
|
|
private static void Log(object message)
|
|
{
|
|
Debug.Log($"<color=orange>ChallengeMatchSceneUI => {message} </color>");
|
|
}
|
|
}
|