unityzgy/Assets/Scripts/UIScripts/Student/StudentSub2EditorPanel.cs
ayuan9957 bf12e02276 feat: 多语言本地化系统 - 支持中/英/法/俄实时切换
- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg)
- LoginPanel: InputField placeholder本地化、字体颜色保持
- HistoryPanel: 用时数据本地化、placeholder本地化
- RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建)
- AppraiseWindowBase: 评价等级本地化、操作消息重建
- EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized
- StudentOperateRecorder: 新增InjectOperateMsgLocalized方法
- LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选
- 字体切换时保留颜色和verticalOverflow
2026-07-16 10:05:59 +08:00

452 lines
19 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XFramework;
using UnityEngine.UI;
using System;
using VRTK;
using XFramework.NetOuter;
public class StudentSub2EditorPanel : BasePanel
{
const string panelName = "Panel_studentSub2";
private Button button_CarInteractive;//汽车交互按钮
private Text text_ButtonCarInter;
private Button button_editorOver;//编辑完成按钮
PromptTextCtrl prompt_editorOverButton;
private StudentButtonIcon[] studentButtonIcons;//一区九厂规划交互按钮
private Button button_areaPlanning;//厂区规划按钮
private MyToggleButton toggleButton_ceju;
Text text_areaPlanning;//按钮显示的文字
bool areaPlanned;//厂区规划完成
PromptTextCtrl prompt_planningButton;//结束/开启厂区位置规划按钮提示文字
Dropdown dropdown_changeView;//切换展示模式 2维/三维
Toggle toggle_openVR;//启用/关闭VR
VRManager VRManager;
bool firstOpenVR = true;
MapManager map;
string terrainName;//地形名称 根据名称获取
private GameObject masterPanel;//分组训练时 组长开启的部分
GameObject areaIconPrefab;
Button button_quitLearn;//结束训练按钮
bool enterVR;//当前是否进入了VR模式 VR模式结束时需要先关闭VR眼镜
bool AreaPlanned//规划状态 默认false未完成
{
set
{
areaPlanned = value;
if (areaPlanned)
{
text_areaPlanning.text = LocalizationManager.Get("重新规划厂区位置");
}
else
{
text_areaPlanning.text = LocalizationManager.Get("厂区位置规划完成");
}
GameObjectManager.Instance.ChangeAreaFlagePick(!areaPlanned); //规划过程中可以 捡起棋子更换位置 规划完成后不能捡起
CameraCtrl.Instance.ChangeCameraEvent(areaPlanned);//规划完成后启用摄像机交互功能 能够控制车辆
VRManager?.SetInteractable(areaPlanned);//规划完成后启用VR 能够控制车辆
}
}
//bool isContinuity;//是否延续前一科目训练
public StudentSub2EditorPanel() : base(new UIType(panelName))
{
}
protected override void InitEvent()
{
MapHelper.InitHelper(new Vector2(10000, 10000), new Vector2(8192, 8192));
button_CarInteractive = ActivePanel.FindChildTrans("Button_carInteractive").GetComponent<Button>();
text_ButtonCarInter = button_CarInteractive.GetComponentInChildren<Text>();
button_CarInteractive.onClick.AddListener(() => GameObjectManager.Instance.ChangeCarOpening());
button_editorOver = ActivePanel.FindChildTrans("Button_editorOver").GetComponent<Button>();
studentButtonIcons = ActivePanel.FindChildTrans("Content_areas").GetComponentsInChildren<StudentButtonIcon>();
List<string> areaName = new List<string>();
foreach (string name in Enum.GetNames(typeof(AreaNameEnum)))
{
areaName.Add(name);
}
for (int i = 0; i < studentButtonIcons.Length; i++)
{
studentButtonIcons[i].SetName(areaName[i]);
}
button_editorOver.onClick.AddListener(EditorOver);
button_CarInteractive.gameObject.SetActive(false);
button_areaPlanning = ActivePanel.FindChildTrans("Button_AreaPlanning").GetComponent<Button>();
button_areaPlanning.onClick.AddListener(AreaPlanningButtonClick);
text_areaPlanning = button_areaPlanning.GetComponentInChildren<Text>();
prompt_planningButton = button_areaPlanning.GetComponentInChildren<PromptTextCtrl>();
prompt_planningButton.SetPrompt(LocalizationManager.Get("提示:厂区规划后,需点击完成按钮,否则无法继续。"), Color.black);
toggleButton_ceju = ActivePanel.FindChildTrans("Button_ceju").GetComponent<MyToggleButton>();
toggleButton_ceju.valueChange += CeJuButton;
prompt_editorOverButton = button_editorOver.GetComponentInChildren<PromptTextCtrl>();
AreaPlanned = false;
dropdown_changeView = ActivePanel.FindChildTrans("Dropdown_changeViewState").GetComponent<Dropdown>();
map = ActivePanel.FindChildTrans("Panel_MapMask").GetComponent<MapManager>();
dropdown_changeView.onValueChanged.AddListener(ViewStateChanged);
dropdown_changeView.value = 0;
ViewStateChanged(0);
toggle_openVR = ActivePanel.FindChildTrans("Toggle_OpenVR").GetComponent<Toggle>();
toggle_openVR.isOn = false;
toggle_openVR.onValueChanged.AddListener(VRToggleChanged);
areaIconPrefab = ResourcesManager.Load<GameObject>("Image_areaFlageIcon");
EventCenter.Instance.AddEventListener<IBindIcon>("CreatAreaFlageIcon", CreatAreaIcon);//发起创建UI指令
masterPanel = ActivePanel.FindChildTrans("Panel_master").gameObject;
if (GroupLearnHelper.isGroup && !GroupLearnHelper.isMaster) //分组训练时 组员隐藏部分UI 注册组长操作事件
{
masterPanel.SetActive(false);
EventCenter.Instance.AddEventListener<MasterActionType>("SyncMasterAction", MasterSyncAction);
}
button_quitLearn = ActivePanel.FindChildTrans("Button_QuitLearn").GetComponent<Button>();
if (StudentStateManager.Instance.LearnState == LearnState.examing)//考核模式不能主动结束
button_quitLearn.gameObject.SetActive(false);
button_quitLearn.onClick.AddListener(QuitButton);
}
//同步教员端的操作指令
private void MasterSyncAction(MasterActionType masterActionType)
{
switch (masterActionType)
{
case MasterActionType.StartSyncOperation:
AreaPlanned = true;
break;
case MasterActionType.PauseSyncOperation:
AreaPlanned = false;
break;
case MasterActionType.StopSyncOperation://组长端结束训练 断开VR设备 直接返回初始场景 记录上传和评价展示在组长端完成
if (enterVR)//开启VR后结束时 先断开VR设备链接 后返回
{
VRManager.ShoutDwonVR((p) => SceneSystem.Instance.SetScene(new StudentLoginScene(LoadSceneType.Login)));
}
else//直接返回
{
SceneSystem.Instance.SetScene(new StudentLoginScene(LoadSceneType.Login));
}
break;
default:
break;
}
}
//科目信息初始化场景 直接下发科目2时通过该方法初始化场景
public override void Change(object newData)
{
NetSub2Msg subMsg = (NetSub2Msg)newData;
//isContinuity = false;
List<OnMapCarData> onMapCarDatas = subMsg.recordClass.onMapCars;
List<CarData> carDatas = new List<CarData>();
terrainName = subMsg.recordClass.TerrainName;
for (int i = 0; i < onMapCarDatas.Count; i++)
{
CarData carData = new CarData();
if (i == 0)//第一辆车是首车
carData.carType = CarPosType.firstCar;
else
carData.carType = CarPosType.fllowCar;
carData.Speed = 25;//km/h 开始科目2时 默认车速为25
carData.carName = onMapCarDatas[i].name;
string carType = carData.carName.Split('(')[0];
if (OnboardManager.Instance.onboardDic.ContainsKey(carType))//具备车载装备
carData.onboardEquip = OnboardManager.Instance.onboardDic[carType];
carData.postion = MapHelper.GetWorldPosFromAnchPos(new Vector2(onMapCarDatas[i].aPX, onMapCarDatas[i].aPY));
carData.rotation = new Vector3(0, 180 - onMapCarDatas[i].angleZ, 0);
carDatas.Add(carData);
}
GameObjectCreater.CreateCarFromAB(carDatas, GameObjectManager.Instance.transform, SubStart);//等待车辆创建完毕后开始科目操作
}
//根据地形信息初始化地图信息
async void InitMap(string mapName)
{
Texture2D sprite = await OutSpriteLoader.LoadTexture(StreamingAssetsManager.GetPath(mapName));
map.SetTexture(sprite);
InitCarIcon();
}
//初始化车辆图标信息
private void InitCarIcon()
{
GameObject carIconPrefab = ResourcesManager.Load<GameObject>("Image_carInstance");
List<CarCtrl> cars = GameObjectManager.Instance.GetCarList();
for (int i = 0; i < cars.Count; i++)
{
//CarIconInstanceCtrl icon = GameObject.Instantiate<GameObject>(carIconPrefab, map.transform).GetComponent<CarIconInstanceCtrl>();
CarIconInstanceCtrl icon = (CarIconInstanceCtrl)map.CreatGOIcon(carIconPrefab, cars[i]);
icon.Interactable = false;
icon.SetFixedAnchoredPos(MapHelper.GetAnchorPostionFromWorld(cars[i].transform.position));
icon.SetUpdateIconMsg(null, "Sub2Init");//初始化图标
}
}
//科目开始 初始化地图 生成车辆图标
private void SubStart()
{
InitMap($"{terrainName}_Map");
GameObjectManager.Instance.StartPersonCtrl();//准备人员控制环境
CameraCtrl.Instance.ChangeCameraEvent(false);//先关闭人员控制功能 厂区规划完成后再次开启
CameraCtrl.Instance.LookAtTarget(GameObjectManager.Instance.GetCarList()[0].transform);//定位到首车
}
//连续训练 /车辆状态更新
public override void Change(string msgType, object value)
{
switch (msgType)
{
case "CarState"://更新选中车辆的状态
ShowCarState((CarState)value);
break;
case "continuity"://连续训练时进入本科目 立即开始科目
//isContinuity = true;
terrainName = (string)value;
SubStart();
break;
case "AreaChanged"://连续训练时进入本科目 立即开始科目
//isContinuity = true;
terrainName = (string)value;
SubStart();
break;
default:
break;
}
}
//显示车辆状态
private void ShowCarState(CarState carState)
{
switch (carState)
{
case CarState.none:
button_CarInteractive.gameObject.SetActive(false);
break;
case CarState.moving:
button_CarInteractive.gameObject.SetActive(true);
button_CarInteractive.interactable = false;
text_ButtonCarInter.text = LocalizationManager.Get("移动中...");
break;
case CarState.parking:
button_CarInteractive.gameObject.SetActive(true);
button_CarInteractive.interactable = true;
text_ButtonCarInter.text = LocalizationManager.Get("展开车辆");
break;
case CarState.openingAnim:
button_CarInteractive.gameObject.SetActive(true);
button_CarInteractive.interactable = false;
text_ButtonCarInter.text = LocalizationManager.Get("展开中...");
break;
case CarState.closingAnim:
button_CarInteractive.gameObject.SetActive(true);
button_CarInteractive.interactable = false;
text_ButtonCarInter.text = LocalizationManager.Get("收起中...");
break;
case CarState.opened:
button_CarInteractive.gameObject.SetActive(true);
button_CarInteractive.interactable = true;
text_ButtonCarInter.text = LocalizationManager.Get("收起车辆");
break;
default:
break;
}
}
//点击厂区规划按钮 未完成规划时点击此按钮
public void AreaPlanningButtonClick()
{
if (!areaPlanned)//未完成规划时 检查是否完成
{
if (GameObjectManager.Instance.GetAllAreas().Count == 10)//完成规划时应当具备10个厂区 结束规划逻辑
{
AreaPlanned = true;
GameObjectManager.Instance.DistributionAreaForCars();//再次开启时为车辆梳理厂区归属关系
if (GroupLearnHelper.isMaster)//组长端 结束厂区规划时 开启组员端的车辆控制功能
{
MasterActionProtoBuilder masterActionProtoBuilder = new MasterActionProtoBuilder(MasterActionType.StartSyncOperation);
NetUDPManager.Instance.SendNetMess(masterActionProtoBuilder.GetProto());
}
}
else
prompt_planningButton.SetPrompt(LocalizationManager.Get("未完成所有厂区的规划!"), Color.red, 3);
}
else//完成后点击 再次开启规划功能
{
AreaPlanned = false;
CameraCtrl.Instance.GetComponent<GameObjectPiaker>().enabled = true;
if (GroupLearnHelper.isMaster)//分组训练模式组长端 再次开启厂区规划时 关闭组员端的控制功能
{
MasterActionProtoBuilder masterActionProtoBuilder = new MasterActionProtoBuilder(MasterActionType.PauseSyncOperation);
NetUDPManager.Instance.SendNetMess(masterActionProtoBuilder.GetProto());
}
}
}
//创建一个表示厂区的UI
private void CreatAreaIcon(IBindIcon icon)
{
IconBase newIcon = map.CreatGOIcon(areaIconPrefab, icon);
newIcon.transform.SetSiblingIndex(0);
}
//结束编辑 提交成绩 并返回初始界面
private void EditorOver()
{
if (!Game.isTest)
{
//厂区可以为空
//if (GameObjectManager.Instance.GetAreaAndCars().Count < 9)
//{
// prompt_editorOverButton.SetPrompt("存在未规划车辆的厂区!",Color.red,3);
// return;
//}
List<CarCtrl> carCtrls = GameObjectManager.Instance.GetCarList();
for (int i = 0; i < carCtrls.Count; i++)
{
if (carCtrls[i].CarState != CarState.opened)
{
prompt_editorOverButton.SetPrompt(LocalizationManager.Format("存在未规划的车辆{0}!", carCtrls[i].gameObject.name), Color.red, 3);
return;
}
}
}
EditorAppraiser appraiser = new EditorAppraiser();
//计算应扣除的分数
appraiser.AppraiseRepairArea(GameObjectManager.Instance.GetAreaAndCars());
//if (isContinuity)
//{
// decScore += StudentOperateRecorder.Instance.sub1Score;
//}
//NetResultMsg netResultMsg = new NetResultMsg();
//netResultMsg.score = decScore;
//netResultMsg.errors = StudentOperateRecorder.Instance.GetAllOperate();
NetAnswerSheet resultMsg = StudentOperateRecorder.Instance.GetResultMsg();
TCPManager.Instance.SendNetMsg<NetAnswerSheet>(resultMsg, NetMsgName.AnswerSheet);
if (GroupLearnHelper.isMaster)//分组训练模式组长端 结束训练指令
{
MasterActionProtoBuilder masterActionProtoBuilder = new MasterActionProtoBuilder(MasterActionType.StopSyncOperation);
NetUDPManager.Instance.SendNetMess(masterActionProtoBuilder.GetProto());
}
if (enterVR)//开启VR后结束时 断开VR设备链接
{
VRManager.ShoutDwonVR(ShoutDownResult);
}
//StudentOperateRecorder.Instance.Clear();//设置科目时自动清空
//SceneSystem.Instance.SetScene(new StudentLoginScene(LoadSceneType.Login));
Push(new WaitResultPanel());
}
//测距按钮
private void CeJuButton(bool isOn)
{
GameObjectManager.Instance.ChangeCLState(isOn);
}
/// <summary>
/// 切换模式
/// </summary>
/// <param name="value">0 三维模式 1二维模式</param>
private void ViewStateChanged(int value)
{
map.SetMapActive(value == 1);//二维开启地图 三维关闭地图
}
Transform transform_VRCamera;
//启用/禁用VR 只启用设备和位移功能,不启用与科目相关的交互操作
private void VRToggleChanged(bool value)
{
//VRManager
if (GameObject.FindObjectOfType<VRTK_SDKManager>() == null)
{
VRManager = new VRManager("VRTKSDKManager_Sub2", GameObjectManager.Instance.GetCarList()[0].transform.position + new Vector3(3, 0, 3));
//VRManager.AddLoadedSetupChanged(LoadedSetupChange);
}
if (value)
{
//VRManager.OpenVR(OpenResult);
GameObject.FindObjectOfType<VRTK_SDKManager>().TryLoadSDKSetupFromList();
}
else
{
//尝试断开设备
//VRManager.ShoutDwonVR(ShoutDownResult);
GameObject.FindObjectOfType<VRTK_SDKManager>().UnloadSDKSetup(true);
}
}
//设备启用反馈结果
private void OpenResult(bool result, VRTK_SDKManager.LoadedSetupChangeEventArgs e)
{
if (result)//设备成功启动
{
enterVR = true;
if (areaPlanned)//已经完成厂区规划后启用VR自动开启VR控制
VRManager.SetInteractable(true);//开启VR交互
if (firstOpenVR)//首次启用VR设备 创建面向VRHead的3D字体
{
Debug.Log("CreatVRText");
firstOpenVR = false;
List<CarCtrl> allCars = GameObjectManager.Instance.GetCarList();
for (int i = 0; i < allCars.Count; i++)
{
GameObjectCreater.Crat3DText(allCars[i], new Vector3(0, 4.5f, 0), "VRCamText", e.currentSetup.actualHeadset.transform, LookAtState.LookAtKeepX, 0.2f);
}
}
MyEnviroManager.Instance.ChangeFocus(e.currentSetup.gameObject, e.currentSetup.actualHeadset.GetComponentInChildren<Camera>());
}
else
{
Debug.Log("VR设备连接启动异常");
}
}
private void ShoutDownResult(bool result)
{
if (result)
{
MyEnviroManager.Instance.ChangeFocus(Camera.main.gameObject, Camera.main);
enterVR = false;
}
else
{
Debug.Log("VR设备连接启动异常");
}
}
//退出训练
private void QuitButton()
{
if (GroupLearnHelper.isMaster)//分组训练模式组长端 结束训练指令
{
MasterActionProtoBuilder masterActionProtoBuilder = new MasterActionProtoBuilder(MasterActionType.StopSyncOperation);
NetUDPManager.Instance.SendNetMess(masterActionProtoBuilder.GetProto());
}
if (enterVR)//开启了VR等待关闭后返回初始场景
{
VRManager.ShoutDwonVR((p) => ReturnLoginScene());
}
else
ReturnLoginScene();
//跳转到登陆场景
}
//返回初始场景
private void ReturnLoginScene()
{
SceneSystem.Instance.SetScene(new StudentLoginScene(LoadSceneType.Login));
}
}