鸟语天空
适配不同分辨率(AnchorLayout)
post by:追风剑情 2019-10-16 11:32

示例

工程截图

0000.png00011.png


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
    }
}


运行测试
1111.png2222.png333.png444.png555.png666.png777.png8888.png9999.png

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容