公共弹窗一般即用即生成,不在UIMgr
中缓存,生成公共弹窗时正好生成在Canvas的最前面,销毁时也是在Canvas内直接Destroy。
Prefab设计

Content下面挂载Text组件和ContentSizeFitter组件以及Layout Element组件,Horizontal Fit和Vertical Fit都设置成preferred size,Preferred Width设为550。
Content里面显示的文字有多有少,我们需要把它设置成自适应的,挂载ContentSizeFitter组件能够保证文字的Rect数据随着文字的内容动态变化,从而方便计算。注意,我们不能打开Text组件的Best Fit来自适应,那样会消耗很多性能。挂载Layout Element组件能让文本自动换行。文本宽度超过550时自动换行。
Buttons和One、Two都是横向Stretch模式,PosY和Height都可以设置

在自适应计算的过程中,我们以Content的CenterTop锚点为基准点。

挂载Layout Element组件时会强制修改Rect的宽度,我们需要在代码中设置Layout Element的Preferred Width。如果文本长度超过550再打开它。
DialogView
在View文件夹内新建DialogView
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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
| using UnityEngine; using UnityEngine.UI; using System; using System.Collections;
[BindPrefab(Pathes.DIALOG_VIEW,Consts.BIND_PREFAB_PRIORITY_VIEW)] public class DialogView : MonoBehaviour, IView { private UIUtil _uiUtil;
private readonly string _onePath = "Frame/Buttons/One"; private readonly string _twoPath = "Frame/Buttons/Two"; private readonly string _yesBtn = "Yes"; private readonly string _noBtn = "No"; private readonly float _upAndDown = 40; private readonly float _leftAndRight = 60; private readonly float _offset = 40; private readonly float _maxWidth = 550; private readonly float _minWidth = 330; public void InitDialog(string content, Action trueAction = null, Action falseAction = null) { if(_uiUtil == null) { _uiUtil = gameObject.AddComponent<UIUtil>(); _uiUtil.Init(); } UpdateContent(content); AddAction(trueAction, falseAction); CoroutineMgr.Instance.ExecuteOnce(ChangeSize()); } private void UpdateContent(string content) { transform.Find("Frame/Content").GetComponent<Text>().text = content; } #region 动态改变弹窗大小 private IEnumerator ChangeSize() { yield return null; var contentRectTrans = _uiUtil.Get("Frame/Content").RectTransform; var buttonsRectTrans = _uiUtil.Get("Frame/Buttons").RectTransform; var frameRectTrans = _uiUtil.Get("Frame").RectTransform; SetWidth(contentRectTrans,frameRectTrans); yield return null; SetHeight(contentRectTrans, buttonsRectTrans, frameRectTrans); } private void SetWidth(RectTransform contentRectTrans, RectTransform frameRectTrans) { float width = _leftAndRight * 2 + contentRectTrans.rect.width;
float result = 0; if (width <= _minWidth) { result = _minWidth; } else if(width > _maxWidth) { result = _maxWidth + _leftAndRight * 2; contentRectTrans.gameObject.GetComponent<LayoutElement>().preferredWidth = _maxWidth; } else { result = width; } frameRectTrans.sizeDelta = new Vector2(result, frameRectTrans.sizeDelta.y); } private void SetHeight(RectTransform contentRectTrans, RectTransform buttonsRectTrans, RectTransform frameRectTrans) { SetContentY(contentRectTrans); SetButtonsY(contentRectTrans, buttonsRectTrans); SetFrameHeight(contentRectTrans, buttonsRectTrans,frameRectTrans); } private void SetContentY(RectTransform contentRectTrans) { float y = contentRectTrans.rect.height * 0.5f + _upAndDown; SetAnchorPosY(contentRectTrans, y); } private void SetButtonsY(RectTransform contentRectTrans, RectTransform buttonsRectTrans) { float offset = _upAndDown + contentRectTrans.rect.height + _offset; float y = buttonsRectTrans.rect.height * 0.5f + offset;
SetAnchorPosY(buttonsRectTrans, y); } private void SetAnchorPosY(RectTransform rectTrans, float y) { var pos = rectTrans.anchoredPosition; pos.y = -y; rectTrans.anchoredPosition = pos; } private void SetFrameHeight(RectTransform contentRectTrans, RectTransform buttonsRectTrans, RectTransform frameRectTrans) { float height = contentRectTrans.rect.height + buttonsRectTrans.rect.height + _upAndDown * 2 + _offset; var size = frameRectTrans.sizeDelta; size.y = height; frameRectTrans.sizeDelta = size; } #endregion private void AddAction(Action trueAction, Action falseAction) { if (trueAction == null && falseAction == null) { SetButtonState(true); AddOneListener(trueAction); } else if (trueAction == null && falseAction != null) { Debug.LogError("弹框中的取消按钮不为空时确认按扭不能为空"); AddOneListener(null); } else if (trueAction != null && falseAction == null) { SetButtonState(true); AddOneListener(trueAction); } else { SetButtonState(false); AddTwoListener(trueAction, falseAction); } } private void SetButtonState(bool isOne) { transform.Find(_onePath).gameObject.SetActive(isOne); transform.Find(_twoPath).gameObject.SetActive(!isOne); } private void AddOneListener(Action trueAction) { if (trueAction == null) { transform.ButtonAction(_onePath + "/" + _yesBtn, UIMgr.Instance.Back); } else { transform.ButtonAction(_onePath + "/" + _yesBtn, trueAction); } } private void AddTwoListener(Action trueAction, Action falseAction) { transform.ButtonAction(_twoPath + "/" + _yesBtn, trueAction); transform.ButtonAction(_twoPath + "/" + _noBtn, falseAction); }
public Transform GetTrans() { return transform; }
public void UpdateFun() { }
public void Init() { }
public void Show() { }
public void Hide() { Destroy(gameObject); } }
|
UIMgr
在UIMgr
中写明公共弹窗的调用逻辑。
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
| private IView _dialog;
public DialogView ShowDialog(string content, Action trueAction = null, Action falseAction = null) { var dialogGo = LoadMgr.Instance.LoadPrefab(Pathes.DIALOG_VIEW, Canvas.transform); AddTypeComponent(dialogGo, Pathes.DIALOG_VIEW);
DialogView dialogView = dialogGo.GetComponent<DialogView>(); if (dialogView != null) { dialogView.InitDialog(content, trueAction, falseAction); } _dialog = dialogView; return dialogView; }
public void Back() { if(uiStack.Count <=1) { return; } if (_dialog == null) { string name = uiStack.Pop(); HideAll(viewsDic[name]);
name = uiStack.Peek(); ShowAll(viewsDic[name]); } else { _dialog.Hide(); _dialog = null; var name = uiStack.Peek(); ShowAll(viewsDic[name]); } }
|
补全强化界面逻辑
StrengthenController
补全强化时钻石不够的弹窗。
1 2 3 4 5 6 7 8 9 10 11 12 13
| private void Upgrades() {
if (money >= cost && GameStateModel.Instance.Level < levelMax) { } else { UIMgr.Instance.ShowDialog("钻石不足!"); } }
|
PropertyItemController
补全星星不够的弹窗
1 2 3 4 5 6 7 8 9 10 11 12 13
| private void AddAction() {
if (cost <= money) { ChangeData(); } else { UIMgr.Instance.ShowDialog("星星不足!"); } }
|