一、先看表现形式
主要形式:
- 1、标签跟随光标移动
- 2、pointer enter时,显示部件信息
- 3、pointer exit时,隐藏标签
二、数据的组织
[Serializable]
public class PartsInfo
{
[Header("部件名字")]
[SerializeField]
public string partsName;
[Header("部件root:用于绑定高亮脚本")]
[SerializeField]
public Transform partsRoot;
[Header("部件的子物体:物体进入该零件,显示所属部件名字")]
[SerializeField]
public List<GameObject> parts;
}
[Serializable]
public class House
{
[Header("房屋名字")]
[SerializeField]
public string houseName;
[Header("房屋部件信息")]
[SerializeField]
public List<PartsInfo> partsInfos;
}
[Header("房屋信息")]
[SerializeField]
public List<House> houses;
三、交互时的注意事项
- 基本组件【EventTrigger】、【MeshCollider】(注意不是【BoxCollider】)
if (obj.GetComponent<EventTrigger>() == null)
{
obj.gameObject.AddComponent<EventTrigger>();
}
if (obj.GetComponent<Collider>() == null)
{
obj.gameObject.AddComponent<MeshCollider>();
}
obj.GetComponent<EventTrigger>().AddListener(EventTriggerType.PointerEnter, (PointerEventData eventData) =>
{
Debug.Log($"进入物体:{partName} {obj.name} {currentPart} {Time.realtimeSinceStartup}");
pi.partsRoot.GetComponent<Highlighter>().tween = true;
ShowTag.ShowNameTag(partName, true);
});
obj.GetComponent<EventTrigger>().AddListener(EventTriggerType.PointerExit, (PointerEventData eventData) =>
{
Debug.Log($"退出物体:{partName} {obj.name} {currentPart} {Time.realtimeSinceStartup}");
pi.partsRoot.GetComponent<Highlighter>().tween = false;
ShowTag.ShowNameTag(partName, false);
});
public class ShowTag : MonoBehaviour
{
[Header("标签图片包含Text组件 ")]
[SerializeField]
public GameObject image;
private bool dragOn;
public static Action<string, bool> ShowNameTag;
private void Start()
{
ShowNameTag = (name, onOff) =>
{
dragOn = onOff;
image.GetComponentInChildren<Text>().text = name;
image.SetActive(onOff);
};
}
void Update()
{
if (dragOn)
{
Drag2dObjectViaMouse(image);
}
}
#if UNITY_EDITOR
[ContextMenu("测试")]
#endif
async void Test5()
{
ShowNameTag("赵四", true);
await UniTask.Delay(TimeSpan.FromSeconds(5f));
ShowNameTag("刘能", true);
await UniTask.Delay(TimeSpan.FromSeconds(5f));
ShowNameTag("", false);
}
}
四、总结
- 1、规划好底层的数据:本例中关键数据为【部件:GameObject -> 名字:string】
- 2、交互式的组件配置:
-
- (1)主相机:Physics Raycaster,Highlighting Renderer
-
- (2)物体:EventTrigger + PointerEnter + PointerExit,MeshCollider,Highlighter
-
- (3)跟随光标的图片:切记需要把【RayCast Target】取消勾选,不然会挡住射线
- 3、在Start()中动态绑定:
void Start()
{
#region =============================普通初始化=============================
currentPart = "";
#endregion =============================普通初始化=============================end
#region =============================事件绑定=============================
houses.ForEach(house =>
{
house.partsInfos.ForEach(pi =>
{
var partName = pi.partsName;
if(pi.partsRoot.gameObject.GetComponent<Highlighter>() == null)
{
pi.partsRoot.gameObject.AddComponent<Highlighter>();
}
pi.parts.ForEach(obj =>
{
if (obj.GetComponent<EventTrigger>() == null)
{
obj.gameObject.AddComponent<EventTrigger>();
}
if (obj.GetComponent<Collider>() == null)
{
obj.gameObject.AddComponent<MeshCollider>();
}
obj.GetComponent<EventTrigger>().AddListener(EventTriggerType.PointerEnter, (PointerEventData eventData) =>
{
Debug.Log($"进入物体:{partName} {obj.name} {currentPart} {Time.realtimeSinceStartup}");
pi.partsRoot.GetComponent<Highlighter>().tween = true;
ShowTag.ShowNameTag(partName, true);
});
obj.GetComponent<EventTrigger>().AddListener(EventTriggerType.PointerExit, (PointerEventData eventData) =>
{
Debug.Log($"退出物体:{partName} {obj.name} {currentPart} {Time.realtimeSinceStartup}");
pi.partsRoot.GetComponent<Highlighter>().tween = false;
ShowTag.ShowNameTag(partName, false);
});
});
});
});
#endregion =============================事件绑定=============================end
}
|