- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg) - LoginPanel: InputField placeholder本地化、字体颜色保持 - HistoryPanel: 用时数据本地化、placeholder本地化 - RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建) - AppraiseWindowBase: 评价等级本地化、操作消息重建 - EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized - StudentOperateRecorder: 新增InjectOperateMsgLocalized方法 - LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选 - 字体切换时保留颜色和verticalOverflow
452 lines
19 KiB
C#
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));
|
|
}
|
|
|
|
}
|