Unity UI逻辑结构
程序员文章站
2022-05-12 20:04:26
...
目录
1.选择怎么的设计模式去组建你的UI逻辑?
本人在选择用什么方式去组建你的UI逻辑这块经常懊恼,不知道其他同学有没有这个经历,也许是我太菜经验不足才会在选择上比较迷茫。网上有很多关于组建游戏UI的资料。比如:MVC,MVP,MVVM等。这些UI逻辑框架他们各有各的好处,但是他们的目的是一样的解耦,让你的代码看起来更整洁些。因为每个人对不同框架的理解有所不同,所以在实现上都会有差异,但是他们的目的还是一样,解耦。选择一个你觉得方便或者说对你来讲更好的框架去组建你繁琐的UI逻辑。
2.选择自己的设计模式。(仅供参考)
偶有幸的选择了MVP,用接口分离。关于MVC的一些理论我这里就不阐述了,网上关于这款资料挺多的,各位同学可以在网上找找。
这里我们先定义几个通用的接口。
/// <summary>
/// 关闭UI接口
/// </summary>
public interface ICloseUIForm
{
void CloseUIForm();
}
/// <summary>
/// 关闭UI之前需要播放的动画
/// </summary>
public interface ICloseUIFormAnimation
{
void CloseUIFormAnimation();
}
///<summary>
///打开UI播放动画
///</summary>
public interface IOpenUIFormAnimation()
{
void OpenUIFormAnimation();
}
我们来针对这个UI写Demo.
定义一个View的显示和更新接口。
/// <summary>
/// 显示系统设置UI信息接口
/// </summary>
public interface IShowSettingsViewInfo:
ICloseUIFormAnimation,ICloseUIFormAnimation
{
/// <summary>
/// 显示ID
/// </summary>
/// <param name="id"></param>
void ShowID(string id);
/// <summary>
/// 显示更新音乐状态
/// </summary>
/// <param name="state"></param>
void MusicState(bool state);
/// <summary>
/// 显示更新音效状态
/// </summary>
/// <param name="state"></param>
void SoundState(bool state);
}
定义一个Controller操作接口、
/// <summary>
/// 系统设置操作行为接口
/// </summary>
public interface IActionSettingsController:ICloseUIForm
{
/// <summary>
/// 音乐开关
/// </summary>
/// <param name="isState"></param>
void ClickMusicToggle(bool isState);
/// <summary>
/// 音效开关
/// </summary>
/// <param name="isState"></param>
void ClickSoundToggle(bool isState);
}
定义一个ViewBase类
public class ViewBase : MonoBehaviour
{
/// <summary>
/// 关闭按钮
/// </summary>
[SerializeField]
protected Button closeButton = null;
/// <summary>
/// 背景关闭按钮
/// </summary>
[SerializeField]
protected Button bgCloseButton = null;
/// <summary>
/// 是否**按钮
/// </summary>
/// <param name="enabled"></param>
protected void ActiveButton()
{
bgCloseButton.enabled = true;
}
/// <summary>
/// 关闭UI
/// </summary>
protected void Close()
{
gameObject.SetActive(false);
}
}
定义设置面板的视图类SettingsView
/// <summary>
/// 系统设置视图
/// </summary>
public class SettingsView : ViewBase, IShowSettingsViewInfo
{
/// <summary>
/// 唯一id
/// </summary>
[SerializeField]
private Text idText = null;
/// <summary>
/// 音乐开关
/// </summary>
[SerializeField]
private Toggle musicToggle = null;
/// <summary>
/// 音效开关
/// </summary>
[SerializeField]
private Toggle soundToggle = null;
/// <summary>
/// 做补间动画的对象
/// </summary>
[SerializeField]
private Transform transformTarget = null;
private IActionSettingsController iActionSettingsController= null;
private void OnEnable()
{
}
private void Start()
{
iActionSettingsController= this.GetComponent<SettingsForm>();
closeButton.onClick.AddListener(iActionSettingsController.CloseUIFormAnimation);
bgCloseButton.onClick.AddListener(iActionSettingsController.CloseUIFormAnimation);
musicToggle.onValueChanged.AddListener(iActionSettingsController.ClickMusicToggle);
soundToggle.onValueChanged.AddListener(iActionSettingsController.ClickSoundToggle);
}
private void OnDestroy()
{
closeButton.onClick.RemoveListener(iActionSettingsController.CloseUIFormAnimation);
bgCloseButton.onClick.RemoveListener(iActionSettingsController.CloseUIFormAnimation);
musicToggle.onValueChanged.RemoveListener(iActionSettingsController.ClickMusicToggle);
soundToggle.onValueChanged.RemoveListener(iActionSettingsController.ClickSoundToggle);
}
/// <summary>
/// 显示ID
/// </summary>
/// <param name="id"></param>
public void ShowID(string id)
{
idText.text = id;
}
/// <summary>
/// 打开动画
/// </summary>
/// <param name="endValue"></param>
/// <param name="duration"></param>
public void OpenUIFormAnimation(float endValue, float duration)
{
bgCloseButton.enabled = false;
transformTarget.DOScale(endValue, duration).OnComplete(ActiveButton);
}
/// <summary>
/// 关闭动画
/// </summary>
/// <param name="endValue"></param>
/// <param name="duration"></param>
public void CloseUIFormAnimation(float endValue, float duration)
{
transformTarget.DOScale(endValue, duration).OnComplete(Close);
}
/// <summary>
/// 音乐开关
/// </summary>
/// <param name="state"></param>
public void MusicState(bool state)
{
musicToggle.isOn = state;
}
/// <summary>
/// 音效开关
/// </summary>
/// <param name="state"></param>
public void SoundState(bool state)
{
soundToggle.isOn = state;
}
}
定义一个系统设置的控制器类SettingsController
/// <summary>
/// 系统设置
/// </summary>
public class SettingsController: IActionSettingsController
{
private IShowSettingsViewInfo iShowSettingsViewInfo= null;
private void Awake()
{
iShowSettingsViewInfo= this.GetComponent<SettingsView>();
}
private void OnEnable()
{
iShowSettingsViewInfo.OpenUIFormAnimation(1.2f, 0.1f);
iShowSettingsViewInfo.ShowID("1");
}
private void Start()
{
iShowSettingsViewInfo.OpenUIFormAnimation(1.2f, 0.1f);
iShowSettingsViewInfo.ShowID("1");
}
public void ClickMusicToggle(bool isState)
{
Debug.Log("音乐开关状态:" + isState);
if(isState)
{
PlayerPrefs.SetInt(SettingsModel.Instance.musicKey, 1);
SettingsModel.Instance.MusicState = true;
}
else
{
PlayerPrefs.SetInt(SettingsModel.Instance.musicKey, 0);
SettingsModel.Instance.MusicState = false;
}
}
public void ClickSoundToggle(bool isState)
{
Debug.Log("音效开关状态" + isState);
if(isState)
{
PlayerPrefs.SetInt(SettingsModel.Instance.soundKey, 1);
SettingsModel.Instance.SoundState = true;
}
else
{
PlayerPrefs.SetInt(SettingsModel.Instance.soundKey, 0);
SettingsModel.Instance.SoundState = false;
}
}
public void CloseUIForm()
{
iShowSettingsViewInfo.CloseUIFormAnimation(0.1f,0.1f);
}
总结
做好自己的测试UI,复制上面的代码做一些稍微的修改即可运行。上述结构存在三个问题:外部如何调用该界面的数据,外部的操作该界面如何更新,UI如果管理。
该界面应该有自己的一个Model数据类,供外部访问数据。
该工程会有一个事件管理器,外部分发的数据在SettingsController里面监听更新。
该工程会有一个UI管理的结构,比如重复利用UI等。
在这里我只是做了一个游戏UI逻辑组建的思想,之针对UI逻辑,仅供参考。希望各方神仙多提提建议。上面说的三点,Model数据类,事件管理,UI管理,在后续的文章中会更新。