示例
工程截图
using System.Collections; using System.Collections.Generic; using UnityEngine; ////// 锚点布局 /// public class AnchorLayout : MonoBehaviour { public Camera camera; public AnchorPoint anchor; public PlayMethod playMethod = PlayMethod.Awake; public Vector3 offset; private Transform target; private Transform cameraTransform; private Vector3 position = Vector3.zero; private void Awake() { target = transform; if (camera == null) camera = Camera.main; if (camera != null) cameraTransform = camera.transform; if (playMethod == PlayMethod.Awake) UpdateLayout(); } private void Start() { if (playMethod == PlayMethod.Start) UpdateLayout(); } private void Update() { if (playMethod == PlayMethod.Update) UpdateLayout(); } private void LateUpdate() { if (playMethod == PlayMethod.LastUpdate) UpdateLayout(); } private void UpdateLayout() { CalculatePosition(); if (target != null && camera != null) { Vector3 pos = target.position; pos.x = cameraTransform.position.x + position.x; pos.y = cameraTransform.position.y + position.y; target.position = pos + offset; } } public void CalculatePosition() { float center_x = 0; float center_y = 0; float half_width = 0; float half_height = 0; if (camera.orthographic) //正交投影 { position.x = position.y = 0; float aspect = camera.aspect;//Width/Height half_height = camera.orthographicSize;//高的一半 half_width = half_height * aspect; } else //透视投影 { //物体在视锥体空间中的z坐标 float frustum_z = target.position.z - cameraTransform.position.z; //计算frustum_z所在截面四个角的坐标(视锥体坐标系) Vector3[] frustumCorners = new Vector3[4]; Vector3[] worldCorners = new Vector3[4]; camera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), frustum_z, Camera.MonoOrStereoscopicEye.Mono, frustumCorners); for (int i = 0; i < 4; i++) { worldCorners[i] = camera.transform.TransformVector(frustumCorners[i]); Debug.DrawRay(camera.transform.position, worldCorners[i], Color.blue); } half_width = frustumCorners[2].x; half_height = frustumCorners[2].y; Vector3 left_bottom_pos = worldCorners[0]; Vector3 right_top_pos = worldCorners[2]; center_x = left_bottom_pos.x + right_top_pos.x; center_y = left_bottom_pos.y + right_top_pos.y; } switch (anchor) { case AnchorPoint.Center: position.x = center_x; position.y = center_y; break; case AnchorPoint.Left: position.x = center_x - half_width; break; case AnchorPoint.Right: position.x = center_x + half_width; break; case AnchorPoint.Top: position.y = center_y + half_height; break; case AnchorPoint.Bottom: position.y = center_y - half_height; break; case AnchorPoint.LeftTop: position.x = center_x - half_width; position.y = center_y + half_height; break; case AnchorPoint.LeftBottom: position.x = center_x - half_width; position.y = center_y - half_height; break; case AnchorPoint.RightTop: position.x = center_x + half_width; position.y = center_y + half_height; break; case AnchorPoint.RightBottom: position.x = center_x + half_width; position.y = center_y - half_height; break; } } public enum AnchorPoint { Top, Center, Bottom, Left, LeftTop, LeftBottom, Right, RightTop, RightBottom } public enum PlayMethod { Awake, Start, Update, LastUpdate } }