preface
We did it before“ UGUI panel follow annotation 3D model function ”The effect is as follows:
It is found that if the objects are moved out of the field of view, the prompt will disappear. On the objects that need key prompt, the effect will be better if there is no indication in the field of view. Therefore, the functions realized in this paper are very necessary. The effects are as follows:
Realization idea
To realize the dynamic prompt on the screen, only two important steps need to be realized:
1 calculate the position of the prompt UI in the screen space;
2 calculate the direction of the arrow.
The flow chart is as follows:
Implementation process
This case is developed on the basis of these two articles:
Unity3d C# realizes the function of UGUI panel following and labeling 3D model (including source code)
If you don't understand something, you can go and have a look.
According to the above implementation ideas, we begin to implement.
UI construction
The UI is relatively simple. There is an arrow image on the Internet and a new node as shown in the following figure is added:
Variable definition
[Header("Target point")] public Transform target; [Header("UI canvas")] public Canvas canvas; [Header("Arrow node (up)")] public RectTransform arrow; //Wrong direction of modulation required
The nodes shown in the figure above need to be configured respectively. Just drag them in.
Note that the direction of the arrow in the picture of the arrow should be upward. If the direction is different, change the getarroweeuler function yourself.
Is it in view
Vector2 viewPos = Camera.main.WorldToViewportPoint(target.position); Vector3 dir = (target.position - Camera.main.transform.position).normalized; float dot = Vector3.Dot(Camera.main.transform.forward, dir); if (dot > 0 && viewPos.x > 0 && viewPos.x < 1 && viewPos.y > 0 && viewPos.y < 1) return true; else return false;
Get prompt display location
private Vector2 GetTipPosInRect(Vector2 pos, Rect rect) { return new Vector2(Mathf.Clamp(pos.x, rect.xMin, rect.xMax), Mathf.Clamp(pos.y, rect.yMin, rect.yMax)); } private Rect GetRectInCanvas() { Rect rect = Rect.zero; Vector2 area = canvas.GetComponent<RectTransform>().sizeDelta; rect.xMax = area.x - TipTrans.sizeDelta.x / 2; rect.yMax = area.y - TipTrans.sizeDelta.y / 2; rect.xMin = TipTrans.sizeDelta.x / 2; rect.yMin = TipTrans.sizeDelta.y / 2; return rect; }
Get arrow angle
public Vector3 GetArrowEuler(Vector3 TargetPos) { float dx = TargetPos.x - arrow.transform.position.x; float dy = TargetPos.y - arrow.transform.position.y; float RotZ = Mathf.Atan2(dy, dx) * 180 / Mathf.PI; RotZ -= 90; float DRotZ = RotZ - arrow.eulerAngles.z; if (DRotZ > 180) DRotZ -= 360; return new Vector3(0, 0, arrow.eulerAngles.z + DRotZ); }
Update detection
if (!target) return; if (IsInScreen()) { transform.localScale = Vector3.zero; return; } transform.localScale = Vector3.one; var screenPos = RectTransformUtility.WorldToScreenPoint(Camera.main, target.position); TipTrans.position = GetTipPosInRect(screenPos, GetRectInCanvas()); if (arrow) arrow.eulerAngles = GetArrowEuler(screenPos);
The realization of this step is completely the replication of ideas, which can be placed in FixUpdate or Update.
problem
Look at the picture first:
After rotating to the right, the pink prompt arrow jumps to the upper right corner. This is the bug that the test gave me feedback on the project.
I haven't found any problems at present. If I know something, I can give advice and discuss it.
But I think it should be the normal change of the prompt position after the lens rotates.
expand
Button components can be added to each prompt box. After clicking, use the DOTween plug-in to move the camera and quickly focus on the target object.
Write click script:
public void ClickPink() { Camera.main.transform.DOMove(new Vector3(-19.999157f, 2.20351362f, -0.876300693f), 1); Camera.main.transform.DORotate(new Vector3(32.8f, 0.9f, 0), 1); } public void ClickGreen() { Camera.main.transform.DOMove(new Vector3(0.366873235f, 3.28463149f, -1.07905042f), 1); Camera.main.transform.DORotate(new Vector3(33.6f, 1.1f, 0), 1); }
After binding the button function, click the effect:
Engineering source code
https://download.csdn.net/download/qq_33789001/79832111
If it cannot be opened, it may not pass the audit.