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