ChangeCamera脚本挂在相机上,ScreenMatchEditor脚本放在editor文件夹下,ScreenMatch脚本挂在需要适配的ui上。刘海屏适配的话要简单的感觉就只能做到目前适配机型的最大刘海长度,如果要完美一点的话感觉就要根据机型进行对应适配了。
此脚本不只可以对于刘海屏的适配,用于在长屏手机下其他ui的位移也是同理。
ps.对于不同的锚点,此适配可能会出现不同的效果,一般来说,拉伸适合于锚点居中的ui,centermove适用于锚点为top或者bottom的ui,根据锚点属性选择对应的类型,如果拉伸或者centermove的距离不满意,就可以手动输入对应的offset进行特殊处理,基本上加上一个常数值就可以达到各个分辨率移动合适的距离。而且对于层级复杂的ui来说可以同时加入几个脚本进行适配,比如对于mask遮盖的滚动列表,可以先拉伸mask然后再加上downmove使遮罩范围放大的同时往下移动。
ChangeCamera:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCamera : MonoBehaviour {
public float camInitSize;// 初始化视口大小
public float originalWidth;// 初始化宽
public float originalHeight;//初始化高
private float size;//实际视口大小
private float width;// 实际宽
private float height;//实际高
void Awake()
{
width = Screen.width;
height = Screen.height;
size = (camInitSize * (originalWidth / originalHeight)) / (width / height);
GetComponent<Camera>().orthographicSize = size;
}
}
ScreenMatchEditor:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
/// <summary>
/// 按类型显示需要的变量
/// </summary>
[CustomEditor(typeof(ScreenMatch))]
public class ScreenMatchEditor : Editor {
private ScreenMatch match;
public override void OnInspectorGUI()
{
match = (ScreenMatch)target;
match.uitype = (ScreenMatch.UIType)EditorGUILayout.EnumPopup("Match Type", match.uitype);
match.gameType = (ScreenMatch.GameType)EditorGUILayout.EnumPopup("Game Type", match.gameType);
if (match.uitype == ScreenMatch.UIType.Stretch)
{
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField("stretchOffset");
match.stretchOffset = float.Parse(EditorGUILayout.TextField(match.stretchOffset+""));
GUILayout.EndHorizontal();
}
if (match.uitype == ScreenMatch.UIType.CenterMove)
{
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField("moveOffset");
match.moveOffset = float.Parse(EditorGUILayout.TextField(match.moveOffset + ""));
GUILayout.EndHorizontal();
match.location = (ScreenMatch.Location)EditorGUILayout.EnumPopup("Location",match.location);
}
if (GUI.changed)
{
EditorUtility.SetDirty(target);
}
}
}
ScreenMatch:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 刘海屏适配
/// </summary>
public class ScreenMatch : MonoBehaviour
{
private Camera mainCamera;
private float originalCameraSize = 6.4f;
/// <summary>
/// UI需要的变化
/// </summary>
public enum UIType{
DownMove,//下移
UpMove,//上移
Stretch,//拉伸
LeftMove,//左移
RightMove,//右移
CenterMove,//中间靠拢,适用于正交相机
}
/// <summary>
/// 锚点位置
/// </summary>
public enum Location {
top,
bottom
}
public enum GameType {
Vertical,//竖屏游戏
Horizontal//横屏游戏
}
public Location location;
public GameType gameType;
public UIType uitype;
public float stretchOffset;
public float moveOffset;
private float width;
private float height;
private float maxMoveDistance = 90;//最大刘海长度
private float originalZ = 1280f / 720f;//基础分辨率
private float tempy, tempx, originaly, originalx, originalHeight, originalWidth, tempz, newHeight, newy, newWidth, newx, cameraOffset;
private Vector2 tempv;
private void Start()
{
width = Screen.width;
height = Screen.height;
mainCamera = Camera.main;
Match();
}
public void Match()
{
float z = height / width;
RectTransform t = gameObject.GetComponent<RectTransform>();
if (z > 2)
{
if (gameType == GameType.Vertical)
{
switch (uitype)
{
case UIType.DownMove:
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx, tempy - maxMoveDistance);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
break;
case UIType.Stretch:
originaly = t.anchoredPosition.y;
originalx = t.anchoredPosition.x;
originalHeight = t.rect.height;
originalWidth = t.rect.width;
tempz = Math.Abs(z - originalZ);
if (originalHeight > maxMoveDistance)
{
newHeight = originalHeight + (originalHeight / originalZ) * tempz - maxMoveDistance + stretchOffset;
newy = originaly + (originaly / originalZ) * tempz - maxMoveDistance / 2 + stretchOffset / 2;
}
else
{
newHeight = originalHeight + (originalHeight / originalZ) * tempz + stretchOffset;
newy = originaly + (originaly / originalZ) * tempz + stretchOffset / 2;
}
t.sizeDelta = new Vector2(originalWidth, newHeight);
t.anchoredPosition = new Vector2(originalx, newy);
break;
case UIType.UpMove:
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx, tempy + maxMoveDistance);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
break;
case UIType.LeftMove:
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx - maxMoveDistance, tempy);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
break;
case UIType.RightMove:
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx + maxMoveDistance, tempy);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
break;
case UIType.CenterMove:
if (location == Location.top)
{
cameraOffset = 100 * (mainCamera.orthographicSize - originalCameraSize);
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx, tempy - cameraOffset);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
}
else if (location == Location.bottom)
{
cameraOffset = 100 * (mainCamera.orthographicSize - originalCameraSize);
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx, tempy + cameraOffset);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
}
break;
}
}
else if(gameType == GameType.Horizontal)
{
switch (uitype)
{
case UIType.Stretch:
originaly = t.anchoredPosition.y;
originalx = t.anchoredPosition.x;
originalHeight = t.rect.height;
originalWidth = t.rect.width;
tempz = Math.Abs(z - originalZ);
if (originalHeight > maxMoveDistance)
{
newWidth = originalWidth + (originalWidth / originalZ) * tempz - maxMoveDistance + stretchOffset;
newx = originalx + (originalx / originalZ) * tempz - maxMoveDistance / 2 + stretchOffset / 2;
}
else
{
newWidth = originalWidth + (originalWidth / originalZ) * tempz + stretchOffset;
newx = originalx + (originalx / originalZ) * tempz + stretchOffset / 2;
}
t.sizeDelta = new Vector2(newWidth, originalHeight);
t.anchoredPosition = new Vector2(newx, originaly);
break;
case UIType.LeftMove:
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx - maxMoveDistance, tempy);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
break;
case UIType.RightMove:
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx + maxMoveDistance, tempy);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
break;
case UIType.CenterMove:
if(location == Location.top)
{
cameraOffset = 100 * (mainCamera.orthographicSize - originalCameraSize);
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx - cameraOffset, tempy);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
}
else if(location == Location.bottom)
{
cameraOffset = 100 * (mainCamera.orthographicSize - originalCameraSize);
tempy = t.anchoredPosition.y;
tempx = t.anchoredPosition.x;
tempv = new Vector2(tempx + cameraOffset, tempy);
gameObject.GetComponent<RectTransform>().anchoredPosition = tempv;
}
break;
}
}
}
}
}