标注生成要求:
1.指定元件生成标注。
2.生成标注出现位置可以设置。
根据标注生成的要求,可以在元件添加脚本时将这些信息读取并进行实现。控制标注生成在元件的位置,生成标注的距离。
public MSwitchParts(int id, string partName, string objName, string details, string inFopostion = "Bottom0", float infoDis = 1, float infoAngle = 45, int pId = 0, List<int> pIds = null)
{
this.Id = id;
this.PartName = partName;
this.ObjName = objName;
this.Details = details;
this.PId = pId;
this.InFopostion = inFopostion;
this.InfoDis = infoDis;
this.InfoAngle = infoAngle;
this.pIds = pIds;
}
在SwitchOperation初始化数据,参数为连接点、距离、角度。
public Vector3 GetEndPointByTrigonometric(float angle, Vector3 StartPoint, float distance)
{
Vector3 EndPoint = Vector3.zero;
//角度转弧度
var radian = (angle * Math.PI) / 180;
Debug.Log(Math.Cos(radian));
//计算新坐标 r 就是两者的距离
EndPoint.x = StartPoint.x + float.Parse((distance * Math.Cos(radian)).ToString());
EndPoint.y = StartPoint.y + float.Parse((distance * Math.Sin(radian)).ToString());
EndPoint.z = StartPoint.z;
return EndPoint;
}
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class MyLine : MonoBehaviour
{
[SerializeField]
private Transform TransformA;
[SerializeField]
public Transform TransformB;
public LineRenderer LineRender;
[System.Obsolete]
void Start()
{
TransformA = this.transform;
LineRender = this.GetComponent<LineRenderer>();
if (LineRender != null)
{
LineRender.sharedMaterial = SwitchOperation.Instance.lineColormaterial;
LineRender.generateLightingData = true;
LineRender.SetWidth(0.008f, 0.008f);
//LineRender.enabled = false;
}
}
void Update()
{
if (LineRender && TransformB)
{
LineRender.SetPosition(0, TransformA.position);
LineRender.SetPosition(1, TransformB.position);
}
}
}
//获取终点坐标
var objPointPostion = GetEndPointByTrigonometric(tempModel.InfoAngle, t.position, tempModel.InfoDis);
var infoRotation = t.rotation;
//生成标注
GameObject infoTemp = Instantiate(infoPrefabs, objPointPostion, infoRotation);
//生成标注 命名
infoTemp.name = "info" + t.name;
//infoTemp.tag = "Info";
var tempText = infoTemp.transform.Find("info").transform.Find("btnInfo").transform.Find("Text").GetComponent<Text>();
tempText.text = tempModel.PartName;
MyLine line = t.gameObject.AddComponent<MyLine>();
if (tempModel.InFopostion != "")
{
line.TransformB = infoTemp.transform.Find(tempModel.InFopostion).transform;
}
else
{
line.TransformB = infoTemp.transform;
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
public class SwitchOperation : MonoBehaviour
{
public static SwitchOperation Instance;
private List<MSwitchParts> list = new List<MSwitchParts>();
[FormerlySerializedAs("infoPrefabs")]
[Tooltip("Prefab of the object. Prefab must have a infoPrefabs component. May be an empty game object or a full avatar.")]
public GameObject infoPrefabs;
public int currentIndex = 0;
public Material lineColormaterial;
private void Awake()
{
Instance = this;
}
// Start is called before the first frame update
void Start()
{
InitData();
}
public List<MSwitchParts> GetSwitchParts()
{
return list;
}
///
/// 初始化数据
///
private void InitData()
{
var dd = new MSwitchParts(1, "真空交流接触器", "zuoduanzhenkongjiaoliuqi2_N", "详细信息比萨饼爸爸", "Bottom1", 1.414f, 90);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(2, "电流互感器", "zuoduandianliuhuganqi1_N", "详细信息222323232", "Right", 0.8f, 180);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(3, "变压器TC", "zuoduanjiaoliuqi1_N", "详细信息222323232", "Top1", 1f, 235);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(4, "千伏级熔断器FU1", "qianfurongduanqi_N", "详细信息222323232", "Top1", 1f, -50);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(5, "中间继电器", "jidianqi2_N", "详细信息222323232", "Left", 1f, 0);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(6, "保护器", "baohuqi1_N", "详细信息222323232", "Right", 1.5f, 180);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(7, "隔离开关QS", "gelizhuanxiangkaiguan003_N", "详细信息222323232", "Bottom1", 1f, 90);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(8, "急停按钮", "jitinganniudizuo2_N", "详细信息222323232", "Right", 1.5f, 135);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
dd = new MSwitchParts(9, "阻容吸收装置", "zhurongxishouqi3_N", "详细信息222323232", "Left", 1f, 35);
dd.setTask(1, "选择卸载" + dd.PartName, 7, "1");
dd.setTask(2, "卸载" + dd.PartName + "的接线柱", 7, "2");
dd.setTask(3, "卸载" + dd.PartName + "的固定螺丝", 7, "3");
dd.setTask(4, "取出" + dd.PartName, 7, "4");
list.Add(dd);
Transform[] allTr = transform.GetComponentsInChildren<Transform>();
int m = 0;
foreach (Transform t in allTr)
{
var tempModel = list.Find(p => p.ObjName == t.name);
if (tempModel != null)
{
Debug.Log(t.name);
SwitchPart part = t.gameObject.AddComponent<SwitchPart>();
part.ownerIndex = m;
m++;
part.mSwitchParts = tempModel;
//获取终点坐标
var objPointPostion = GetEndPointByTrigonometric(tempModel.InfoAngle, t.position, tempModel.InfoDis);
var infoRotation = t.rotation;
//生成标注
GameObject infoTemp = Instantiate(infoPrefabs, objPointPostion, infoRotation);
//生成标注 命名
infoTemp.name = "info" + t.name;
var tempText = infoTemp.transform.Find("info").transform.Find("btnInfo").transform.Find("Text").GetComponent<Text>();
tempText.text = tempModel.PartName;
MyLine line = t.gameObject.AddComponent<MyLine>();
if (tempModel.InFopostion != "")
{
line.TransformB = infoTemp.transform.Find(tempModel.InFopostion).transform;
}
else
{
line.TransformB = infoTemp.transform;
}
}
}
}
public Vector3 GetEndPointByTrigonometric(float angle, Vector3 StartPoint, float distance)
{
Vector3 EndPoint = Vector3.zero;
//角度转弧度
var radian = (angle * Math.PI) / 180;
Debug.Log(Math.Cos(radian));
//计算新坐标 r 就是两者的距离
EndPoint.x = StartPoint.x + float.Parse((distance * Math.Cos(radian)).ToString());
EndPoint.y = StartPoint.y + float.Parse((distance * Math.Sin(radian)).ToString());
EndPoint.z = StartPoint.z;
return EndPoint;
}
public void SetCurrentIndex(int opeIndex)
{
if (opeIndex > list.Count)
{
currentIndex = list.Count;
}
else
{
currentIndex = opeIndex;
}
}
public void SetCurrentInfo()
{
list[currentIndex].OperaStatus = "N";
}
public void SetCurrentFinishInfo()
{
list[currentIndex].OperaStatus = "T";
}
public GameObject GetCurrentSwitchObj()
{
print("GetCurrentSwitchObj:" + currentIndex);
var name = list[currentIndex].ObjName;
print("GetCurrentSwitchObj:" + name);
var obj = UHelper.FindTheChild(this.gameObject, name).gameObject;
return obj;
}
public MSwitchParts GetCurrentSwitchInfo()
{
return list[currentIndex];
}
}
标注显示效果不理想。这时我们在添加一个脚本使得标注总是看向主摄像机。
添加脚本LookCamera。
using UnityEngine;
public class LookCamera : MonoBehaviour
{
Transform m_Camera;
public Camera myCamera;
void Start()
{
if (myCamera != null)
{
m_Camera = myCamera.transform;
}
else
{
m_Camera = Camera.main.transform;
}
}
// Update is called once per frame
void LateUpdate()
{
// 这里我的角色朝向和UI朝向是相反的,如果直接用LookAt()还需要把每个UI元素旋转过来。
// 为了简单,用了下面这个方法。它实际上是一个反向旋转,可以简单理解为“负负得正”吧
transform.rotation = Quaternion.LookRotation(transform.position - m_Camera.position);
}
}
最终效果