Unity中如何创建符合要求的自适应2D屏幕布局?
Unity 2D指定屏幕布局实现方案
一、划分屏幕固定比例区域
- 创建Canvas,设置Render Mode为
Screen Space - Overlay,确保布局随屏幕尺寸自适应。 - 在Canvas下创建三个空物体:
TopContainer、MiddleContainer、BottomContainer,分别对应顶部、中间、底部区域。 - 给每个容器的Rect Transform设置锚点与拉伸规则:
- TopContainer:锚点左=0、右=1、上=1、下=0.75,自动占据屏幕顶部25%高度。
- MiddleContainer:锚点左=0、右=1、上=0.75、下=0.25,自动占据中间50%高度。
- BottomContainer:锚点左=0、右=1、上=0.25、下=0,自动占据底部25%高度。
二、中间容器:按物体比例自动缩放
给MiddleContainer挂载以下C#脚本,调用脚本方法添加物体时会自动按规则适配:
using UnityEngine; public class MiddleContainerScaler : MonoBehaviour { private RectTransform containerRect; void Awake() { containerRect = GetComponent<RectTransform>(); } // 外部调用此方法添加适配后的物体 public void AddFittedObject(GameObject objPrefab) { GameObject newObj = Instantiate(objPrefab, transform); RectTransform objRect = newObj.GetComponent<RectTransform>(); if (objRect == null) return; float containerWidth = containerRect.rect.width; float containerHeight = containerRect.rect.height; float objRatio = objRect.rect.width / objRect.rect.height; float targetWidth, targetHeight; // 区分高型/宽型物体 if (objRatio < 1) { targetHeight = containerHeight * 0.8f; targetWidth = targetHeight * objRatio; } else { targetWidth = containerWidth * 0.75f; targetHeight = targetWidth / objRatio; } // 设置尺寸并居中 objRect.sizeDelta = new Vector2(targetWidth, targetHeight); objRect.anchorMin = objRect.anchorMax = new Vector2(0.5f, 0.5f); objRect.pivot = new Vector2(0.5f, 0.5f); objRect.anchoredPosition = Vector2.zero; } }
三、底部容器:4个物体等间距排列+按高度缩放
- 给
BottomContainer添加Horizontal Layout Group组件,配置:- Child Alignment:
Middle Center - Control Child Size:勾选
Width和Height - Child Force Expand:取消
Width和Height的勾选
- Child Alignment:
- 挂载以下脚本,调用方法即可添加符合要求的子物体:
using UnityEngine; using UnityEngine.UI; public class BottomContainerManager : MonoBehaviour { private RectTransform containerRect; private HorizontalLayoutGroup layoutGroup; void Awake() { containerRect = GetComponent<RectTransform>(); layoutGroup = GetComponent<HorizontalLayoutGroup>(); } // 外部调用添加4个等间距适配物体 public void Add4FittedObjects(GameObject objPrefab) { // 清空原有子物体 foreach (Transform child in transform) Destroy(child.gameObject); float itemHeight = containerRect.rect.height * 0.85f; // 计算等间距(左右留空,物体间间距均匀) float totalAvailableWidth = containerRect.rect.width - (itemHeight * 4); layoutGroup.spacing = totalAvailableWidth / 5; for (int i = 0; i < 4; i++) { GameObject newObj = Instantiate(objPrefab, transform); RectTransform objRect = newObj.GetComponent<RectTransform>(); LayoutElement layoutEle = newObj.GetComponent<LayoutElement>() ?? newObj.AddComponent<LayoutElement>(); // 按容器高度85%缩放,保持物体原始比例 float objRatio = objRect.rect.width / objRect.rect.height; layoutEle.preferredHeight = itemHeight; layoutEle.preferredWidth = itemHeight * objRatio; } } }
关于之前Layout Group无效的说明
你之前用Horizontal/Vertical Layout Group没效果,大概率是没配合以下设置:
- 子物体未添加Layout Element组件来控制尺寸优先级
- 容器或子物体的Rect Transform锚点设置错误,导致布局拉伸逻辑失效
- 未取消
Child Force Expand的勾选,导致子物体强制占满容器空间
内容的提问来源于stack exchange,提问作者soleil
相关产品推荐
相关产品推荐

