在实际制作UI的时候,为了完成一些排版设计,我们会经常用到Unity的布局(Layout)组件。甚至有些复杂的排版,我会用嵌套布局来实现。 UI美术人经常希望在这些布局上加上一些进场出场动画(甚至包括spacing变动),但布局组件上的数值是没法在动画中修改的,怎么办呢?
方法一 在布局中添加一些空物体或是在布局外面套空物体。然后再使用Tween动画来完成UI美术们想要的那些进出场动画。 美术人不太喜欢的方法,因为有那么一点点不太方便和Animation直接一起预览,但如果整体进出场动画不依赖UnityAnimation且不是很复杂,这种方法完全够用。
方法二 用通过动画控制脚本上的可序列化的数值,再传递到布局组件上。 个人感觉这个方法也还不错,还能支持预览,UI美术更偏向于这一个解决方法。
但是在动画窗口里里看到的curve是锯齿状的,很奇怪。之后还需要看下如何才能像其他属性一样拉正常的曲线。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 using UnityEngine;using UnityEngine.UI;[ExecuteAlways ] public class LayoutGroupTempAnimationParam : MonoBehaviour { [SerializeField ] private LayoutGroup _target; [SerializeField ] private int _left; [SerializeField ] private int _right; [SerializeField ] private int _top; [SerializeField ] private int _bottom; [Header("GridLayout must use GridSpacing" ) ] [SerializeField ] private bool _alsoControlSpacing; [SerializeField ] private int _normalSpacing = 0 ; [SerializeField ] private Vector2 _gridSpacing = Vector2.zero; private RectOffset m_targetPadding; public void OnDidApplyAnimationProperties ( ) { if (_target == null ) { return ; } ApplyPadding(); if (_alsoControlSpacing) { ApplySpacing(); } RectTransform rectTransform = this .transform as RectTransform; LayoutRebuilder.MarkLayoutForRebuild(rectTransform); } private void ApplyPadding ( ) { m_targetPadding = _target.padding; if (m_targetPadding != null ) { m_targetPadding.left = _left; m_targetPadding.right = _right; m_targetPadding.top = _top; m_targetPadding.bottom = _bottom; } } private void ApplySpacing ( ) { if (_target is HorizontalOrVerticalLayoutGroup layoutGroup) { layoutGroup.spacing = _normalSpacing; } else if (_target is GridLayoutGroup gridLayoutGroup) { gridLayoutGroup.spacing = _gridSpacing; } } #if UNITY_EDITOR private void OnValidate ( ) { ApplyPadding(); if (_alsoControlSpacing) { ApplySpacing(); } if (!Application.isPlaying) { RectTransform rectTransform = this .transform as RectTransform; LayoutRebuilder.MarkLayoutForRebuild(rectTransform); } } private void Reset ( ) { _target = this .GetComponent<LayoutGroup>(); m_targetPadding = _target.padding; } #endif }