unityzgy/Assets/Scripts/UIScripts/ThisProjectPublic/PlanningPlaneCtrl.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

310 lines
13 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using XFramework.Objects;
using XFramework;
using UnityEngine.UI;
public class PlanningPlaneCtrl : MonoBehaviour, IPointerDownHandler
{
public GameObject wayPointIcon;
public GameObject line;
public Transform wayPointParentTrans;//与地图大小完全一致的Panel 作为所有路点路径的父物体 便于管理
Dictionary<WayType, List<GameObject>> wayPointIcons = new Dictionary<WayType, List<GameObject>>();//线路路点图标
Dictionary<WayType, List<GameObject>> lineIcons = new Dictionary<WayType, List<GameObject>>();//线路路径图标
bool drawLine;
WayType currentEditorLine;
Color arriveColor;
Color unArriveColor;
NavMeshManager navMeshManager;
// Start is called before the first frame update
void Start()
{
navMeshManager = FindObjectOfType<NavMeshManager>();
// StartDrawLine("首选", Color.green, Color.red);
}
//绘制路径 根据屏幕坐标
private void DrawPathFromScreenPoint(Vector2 point,Color lineColor)
{
Vector2 UIPos = Vector2.zero;
RectTransformUtility.ScreenPointToLocalPointInRectangle(this.GetComponent<RectTransform>(), point, null, out UIPos);//将点击时鼠标的屏幕坐标转换为UI锚点坐标
GameObject newPoint = ObjectPool.Instance.Instantiate(wayPointIcon, wayPointParentTrans);//直接在点击的位置生成路点
//newPoint.transform.SetParent(wayPointParentTrans);
newPoint.GetComponent<RectTransform>().anchoredPosition = UIPos;
newPoint.GetComponent<Image>().color = lineColor;
if (wayPointIcons[currentEditorLine].Count > 0)//非首个路点生成路径线
{
newPoint.gameObject.SetActive(true);
newPoint.transform.localScale = this.transform.localScale * (1 / this.transform.localScale.x);
Vector2 lastPointUIPos = wayPointIcons[currentEditorLine][wayPointIcons[currentEditorLine].Count - 1].GetComponent<RectTransform>().anchoredPosition;
float angle = Vector2.SignedAngle(UIPos - lastPointUIPos, Vector2.left);
if (-angle > 90 || -angle < -90)
angle += 180;
Vector2 lineUIPos = (UIPos + lastPointUIPos) / 2;
GameObject newLine = ObjectPool.Instance.Instantiate(line,Vector2.zero, Quaternion.AngleAxis(-angle, Vector3.forward), wayPointParentTrans);//生成路径
newLine.transform.localScale = Vector3.one /** (1 / this.transform.localScale.x)*/;
newLine.GetComponent<RectTransform>().anchoredPosition = lineUIPos;
newLine.GetComponent<Image>().color = lineColor;
float screenDistance = Vector2.Distance(UIPos, lastPointUIPos);
//float mapPixel = screenDistance* this.transform.localScale.x;
newLine.GetComponent<RectTransform>().sizeDelta = new Vector2(screenDistance, 3 /** this.transform.localScale.x*/);
lineIcons[currentEditorLine].Add(newLine);
}
else//首路点不显示
{
newPoint.gameObject.SetActive(false);
//navMeshManager.SetStartPos(new Vector3(worldPos.x, Terrain.activeTerrain.SampleHeight(worldPos), worldPos.y));
}
wayPointIcons[currentEditorLine].Add(newPoint);
}
/// <summary>
/// 学员端开启路径规划功能 并设置默认颜色
/// </summary>
/// <param name="arriveColor">可达路点的颜色</param>
/// <param name="unArriveColor">不可达路点的颜色</param>
public void StartDrawLine(WayType wayType,Color arriveColor,Color unArriveColor)
{
if (navMeshManager == null)
{
GameObject navGameObject = new GameObject("NavMesh");
navMeshManager = navGameObject.transform.GetOrAddComponent<NavMeshManager>();
}
currentEditorLine = wayType;
this.arriveColor = arriveColor;
this.unArriveColor = unArriveColor;
if (!wayPointIcons.ContainsKey(wayType))
{
wayPointIcons.Add(wayType, new List<GameObject>());
lineIcons.Add(wayType, new List<GameObject>());
}
else if(wayPointIcons[wayType].Count>0)//再次开始编辑某一线路时 若该线路已经有路点 则将最后一个点位设置为寻路组件的起点
{
Vector3 lastPointIconAnchoredPos = wayPointIcons[wayType][wayPointIcons[wayType].Count - 1].GetComponent<RectTransform>().anchoredPosition;
Vector3 worldPos = MapHelper.GetWorldPosFromAnchPos(lastPointIconAnchoredPos);
navMeshManager.SetStartPos(worldPos);
}
drawLine = true;
}
//结束绘制
public void StopDrawLine()
{
drawLine = false;
}
//点击设置路点 当前所有路点均由鼠标确定 后续完善成由地形确定
public void OnPointerDown(PointerEventData eventData)
{
if (!drawLine) return;
if (eventData.button == PointerEventData.InputButton.Left)
{
Vector2 pointIconLocaPostion = Vector2.zero;
RectTransformUtility.ScreenPointToLocalPointInRectangle(wayPointParentTrans.GetComponent<RectTransform>(), eventData.position, null, out pointIconLocaPostion);
Vector3 worldPos = MapHelper.GetWorldPosFromAnchPos(pointIconLocaPostion);
if (wayPointIcons[currentEditorLine].Count <= 0)//首个路点执行
{
SetFirstPoint(eventData.position, worldPos);
}
else
{
CheckNewPointAndDraw(eventData.position, worldPos);
}
}
else if (eventData.button == PointerEventData.InputButton.Right)
{
RemoveLastPoint();
}
}
//检查路点可达性 并绘制线路 后续可完善为按照返回的路点绘制详细线路
private void CheckNewPointAndDraw(Vector2 mousePostion, Vector3 worldPos)
{
Vector3[] wayPoints = navMeshManager.SetTargetPointPostion(worldPos);
//Debug.Log("wayPoints:"+wayPoints.Length);
if (wayPoints == null)
{
DrawPathFromScreenPoint(mousePostion, unArriveColor);
GameObject gameObject = new GameObject("unArrivePoint");
gameObject.transform.position = worldPos;
}
else //if (wayPoints.Length <= 200)//只返回两个路点时 无需增加中间点 暂不实现
{
DrawPathFromScreenPoint(mousePostion, arriveColor);
}
//else
//{
// for (int i = 1; i < wayPoints.Length-1; i++)
// {
// Vector2 anchoredPos = new Vector2(wayPoints[i].x, wayPoints[i].z) / mapScale - new Vector2(4096, 4096);
// Debug.Log("计算出的锚点坐标:"+anchoredPos);
// DrawPathFromLoaclAnchoredPoint(anchoredPos, arriveColor);
// //Vector2 V2fromInScreen = RectTransformUtility.WorldToScreenPoint(Camera.main, from.transform.position);
// }
//}
}
//设置首个路点 默认首个路点一定可达 无需检测可达性
private void SetFirstPoint(Vector2 mousePostion, Vector3 worldPos)
{
navMeshManager.SetStartPos(worldPos);
navMeshManager.transform.position = worldPos;
DrawPathFromScreenPoint(mousePostion, arriveColor);
}
bool hasDefultPoint;
//将首车位置设置为所有线路的默认起始位置点
public void SetDefultFirstPoint(Vector2 anchoredPostion)
{
Debug.Log(anchoredPostion);
GameObject newPoint = ObjectPool.Instance.Instantiate(wayPointIcon, wayPointParentTrans);
newPoint.GetComponent<RectTransform>().anchoredPosition = anchoredPostion;
newPoint.gameObject.SetActive(false);
wayPointIcons.Add(WayType., new List<GameObject>());
wayPointIcons[WayType.].Add(newPoint);
lineIcons.Add(WayType., new List<GameObject>());
wayPointIcons.Add(WayType., new List<GameObject>());
wayPointIcons[WayType.].Add(newPoint);
lineIcons.Add(WayType., new List<GameObject>());
hasDefultPoint = true;
}
//移除最后一个路点和对应的路径
private void RemoveLastPoint()
{
int lastPointIndex = 0;
if (hasDefultPoint)//有默认起始点时保留起始点位 需要清除默认点位时 另行开启接口
lastPointIndex = 1;
if (wayPointIcons[currentEditorLine].Count > lastPointIndex)
{
ObjectPool.Instance.Destroy(wayPointIcons[currentEditorLine][wayPointIcons[currentEditorLine].Count - 1]);
wayPointIcons[currentEditorLine].RemoveAt(wayPointIcons[currentEditorLine].Count - 1);
}
if (lineIcons[currentEditorLine].Count > 0)
{
ObjectPool.Instance.Destroy(lineIcons[currentEditorLine][lineIcons[currentEditorLine].Count - 1]);
lineIcons[currentEditorLine].RemoveAt(lineIcons[currentEditorLine].Count - 1);
Vector2 lastPointPos = wayPointIcons[currentEditorLine][wayPointIcons[currentEditorLine].Count - 1].GetComponent<RectTransform>().anchoredPosition;//移除路径时更新路点位置
Debug.Log(lastPointPos);
navMeshManager.SetStartPos(MapHelper.GetWorldPosFromAnchPos(lastPointPos));
}
}
/// <summary>
/// 获取规划路径点世界坐标
/// </summary>
/// <returns></returns>
public List<Vector3> GetPlaneWayPoints(WayType wayType, out string wayPointError)
{
List<Vector3> wayPointsWorldPostion = new List<Vector3>();
for (int i = 0; i < wayPointIcons[wayType].Count; i++)
{
wayPointsWorldPostion.Add(MapHelper.GetWorldPosFromAnchPos(wayPointIcons[wayType][i].GetComponent<RectTransform>().anchoredPosition));
}
if (wayPointsWorldPostion.Count > 0)
wayPointError = null;
else
wayPointError = LocalizationManager.Format("未规划{0}线路", LocalizationManager.DisplayName(wayType.ToString()));
return wayPointsWorldPostion;
}
/// <summary>
/// 检查两条线路是否规划完毕
/// </summary>
/// <returns></returns>
public string CheckPlanningFinished()
{
string error="";
if (!lineIcons.ContainsKey(WayType.)|| lineIcons[WayType.].Count < 0)
error = LocalizationManager.Get("未规划首选线路");
if (!lineIcons.ContainsKey(WayType.) || lineIcons[WayType.].Count < 0)
error = LocalizationManager.Get("未规划备选线路");
return error;
}
/// <summary>
/// 获取当前规划的所有路径物体
/// </summary>
/// <returns></returns>
public Dictionary<WayType, List<GameObject>> GetLines()
{
return lineIcons;
}
/// <summary>
/// 教员端根据导调初始化数据绘制路径
/// </summary>
/// <param name="lines">key 路径类型 value.item.x y代表 某段线路锚点位置 z代表该段线路长度</param>
public void DrawLine(Dictionary<WayType, List<LineTransData>> lines)
{
foreach (var item in lines)
{
Color lineColor;
if (item.Key == WayType.)
lineColor = Color.green;
else
lineColor = Color.yellow;
if (!lineIcons.ContainsKey(item.Key))
lineIcons.Add(item.Key, new List<GameObject>());
for (int i = 0; i < item.Value.Count; i++)
{
GameObject newLine = ObjectPool.Instance.Instantiate(line, wayPointParentTrans);//生成路径
RectTransform rectTransform = newLine.GetComponent<RectTransform>();
rectTransform.anchoredPosition = item.Value[i].anchorPos.GetVector2();
rectTransform.localEulerAngles = new Vector3(0, 0, item.Value[i].angleZ);
rectTransform.sizeDelta = new Vector2(item.Value[i].sizeX,3);//高度保持3个像素 长度以学员端传回的实际像素值为准
rectTransform.localScale = Vector3.one;
newLine.GetComponent<Image>().color = lineColor;
lineIcons[item.Key].Add(newLine);
}
}
}
/// <summary>
/// 清空已经绘制的线路
/// </summary>
public void Clear()
{
foreach (var item in wayPointIcons)
{
for (int i = 0; i < item.Value.Count; i++)
{
ObjectPool.Instance.Destroy(item.Value[i]);
}
}
wayPointIcons.Clear();
foreach (var item in lineIcons)
{
for (int i = 0; i < item.Value.Count; i++)
{
ObjectPool.Instance.Destroy(item.Value[i]);
}
}
lineIcons.Clear();
}
}
//路径类型
public enum WayType
{
,
,
}