推荐一款男人都懂得app,洛阳搜索引擎优化,外贸独立站是什么,摄影网站模板前言
在项目上线前期#xff0c;这边根据需求制作了一套QA测试工具。主要分为以下四个模块的测试**图1**
**数值测试#xff1a;**主要包括了角色的等级变更、游戏里货币的变更、#xff08;目前已制作的#xff09;游戏道具的数量变更。这些可能归一为一类测试模型**动画…
前言
在项目上线前期这边根据需求制作了一套QA测试工具。主要分为以下四个模块的测试**图1**
**数值测试**主要包括了角色的等级变更、游戏里货币的变更、目前已制作的游戏道具的数量变更。这些可能归一为一类测试模型**动画测试**包括角色的控制系统的所有Animation资源的播放状态【目前无测试需求】**流程测试**比如是否需要快速胜利、跳过新手指引、指定比赛胜利类型胜负、平局等等一系列流程。**自定测试**笔者目前没有想到的可能出现的其他需要测试的分类。
工具架构 主菜单顶部横栏
如图1所示主菜单是横向布局静态显示的。
using System.Collections.Generic;
using JetBrains.Annotations;
using QAModule;
using UnityEngine;
using UnityEngine.UI;
using TEngine;namespace GameLogic.UI
{[Window(UILayer.UI)]public class QAMainPageUI : UIWindow{//缓存池对象private QAOptionPanel _optionPanelInBuffer;private ListTestOption _optionsList;//菜单选项条目private DictionaryTestType, string[] _menuDictionary; #region 脚本工具生成的代码private Image m_imgBg;private GameObject m_goOptionPanel;private GameObject m_goTestNameRoot;private Button m_btnNumericalTest;private Button m_btnAnimationTest;private Button m_btnProcessTest;private Button m_btnBack;public override void ScriptGenerator(){m_imgBg FindChildComponentImage(m_imgBg);m_goOptionPanel FindChild(m_goOptionPanel).gameObject;m_goTestNameRoot FindChild(m_goTestNameRoot).gameObject;m_btnBack FindChildComponentButton(m_btnBack);m_btnNumericalTest FindChildComponentButton(m_goTestNameRoot/m_btnNumericalTest);m_btnAnimationTest FindChildComponentButton(m_goTestNameRoot/m_btnAnimationTest);m_btnProcessTest FindChildComponentButton(m_goTestNameRoot/m_btnProcessTest);m_btnBack.onClick.AddListener(OnClickBackBtn);m_btnNumericalTest.onClick.AddListener(OnClickNumericalTestBtn);m_btnAnimationTest.onClick.AddListener(OnClickAnimationTestBtn);m_btnProcessTest.onClick.AddListener(OnClickProcessTestBtn);}#endregionpublic override void OnCreate(){base.OnCreate();Initialize();}private void Initialize(){_optionsList new ListTestOption();_menuDictionary new DictionaryTestType, string[]();QAInitDataTable dataTable new QAInitDataTable();_menuDictionary dataTable.MenuDictionary;}/// summary/// 根据选项展开面板/// /summary/// param nameindex/paramprivate void OpenPanel(TestType type){int index (int)type;m_goOptionPanel.SetActive(true);m_imgBg.enabled false;//对应属性高亮int indexCounts m_goTestNameRoot.transform.childCount;ListTransform childrenTrans m_goTestNameRoot.transform.GetAllChildren();for (int i 0; i indexCounts; i){var select childrenTrans[i].Find(Selected).gameObject;if (select ! null){if (index i){select.SetActive(true);}else{if (select.activeInHierarchy){select.SetActive(false);}}}}//创建面板_optionPanelInBuffer ?? CreateWidgetByPathQAOptionPanel(m_goOptionPanel.transform, QAOptionPanel);//读取缓存池刷新选项内容_optionPanelInBuffer.Init(_optionsList,type,_menuDictionary[type]);}/// summary/// 数值类型测试/// /summaryprivate void OnClickNumericalTestBtn(){OpenPanel(TestType.NumericalType);}/// summary/// 动画类型测试/// /summaryprivate void OnClickAnimationTestBtn(){OpenPanel(TestType.AnimationType);}/// summary/// 流程类型测试/// /summaryprivate void OnClickProcessTestBtn(){OpenPanel(TestType.ProcessType);}private void OnClickBackBtn(){if (m_goOptionPanel.activeInHierarchy){m_goOptionPanel.SetActive(false);m_imgBg.enabled true;}else{GameModule.UI.CloseWindowQAMainPageUI();}}}
}背包面板
点击顶部菜单按钮提示展开二级选择面板。根据考虑我选择了类似背包面板的展示模式。在面板中通过网格布局创建需要的测试条目。面板切换时使用了一个缓存池做优化。首次创建时选项的预制体加入缓存池如果切换面板只需更新UI、更换打开的工作流即可。
缓存池 /// summary/// 创建面板里的选项/// /summary/// 根据TestType类型创建条目每个条目已经绑定了打开的显示逻辑public void Init(ListTestOption optionList,TestType type,string[] optionType){int typeCounts optionType.Length;int bufferCounts optionList.Count;//缓存池中数量小于需创建的数量重复部分刷新值多余部分创建并入池子。if (bufferCounts typeCounts){for (int index 0; index typeCounts; index){if (index bufferCounts){if (!optionList[index].gameObject.activeInHierarchy){optionList[index].gameObject.SetActive(true);}optionList[index].Initialize(index,type,optionType[index]); }else{var testOption CreateWidgetByPathTestOption(m_goContent.transform, TestOption);testOption.Initialize(index,type,optionType[index]);optionList.Add(testOption);}}}//缓存池中数量大于等于需创建的数量读取池子刷新内容多余部分隐藏。else{for (int i 0; i bufferCounts; i){if (i typeCounts){optionList[i].Initialize(i,type,optionType[i]); if (!optionList[i].gameObject.activeInHierarchy){optionList[i].gameObject.SetActive(true);}}else{optionList[i].gameObject.SetActive(false);} }}} 具体测试面板
点击进入具体测试面板时对于面板笔者是这么规划的。
数据类
既然测试的大类型分为了四类那么自然每个类型都应该有不同的初始化数据图2在面板中红框的部分是**派生的预制体持有的**剩余部分应该是每种类型都应该显示的了那就是标题以数值类型测试为例数据脚本如下
namespace QAModule
{//基础数据类型存储结构public class QABaseData{public string TestType{get _testType;set _testType value;}private string _testType;}
}namespace QAModule
{/// summary/// 数值类型字段存储结构/// /summarypublic class QANumericalData : QABaseData{public string InitDisplayValue{get _initDisplayValue;set _initDisplayValue value;}public float IncrementRate{get _incrementRate;set _incrementRate value;}public float DecrementRate{get _decrementRate;set _decrementRate value;}private string _initDisplayValue;private float _incrementRate;private float _decrementRate;}
}物体脚本
那么实现的脚本至少有两层
using GameLogic.UI.QAEvent;
using UnityEngine.UI;
using TEngine;
using QAModule;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI)]public class QAPanelBaseT :UIWindow where T : QAPanelBaseT{//需要记忆存储的参数protected static string _testType;#region 脚本工具生成的代码protected Text m_textType;private Button m_btnBack;public override void ScriptGenerator(){m_textType FindChildComponentText(Title/m_textType);m_btnBack FindChildComponentButton(m_btnBack);m_btnBack.onClick.AddListener(OnClickBackBtn);}#endregionpublic override void RegisterEvent(){base.RegisterEvent();AddUIEventQABaseData(QAEventDefine.StartWorkflow,OnStartWorkflow);}protected virtual void InitData(QABaseData data){}private void CreateWorkflow() //确定工作流软件模型瀑布模型{ReadDataFromMemory();//1.AddListener();InitPanel();}protected virtual void ReadDataFromMemory(){}protected virtual void AddListener(){}protected virtual void InitPanel(){}#region 事件private void OnStartWorkflow(QABaseData data){InitData(data);CreateWorkflow();}protected virtual void OnClickBackBtn(){//打开主界面Debug.Log(back from base);GameModule.UI.ShowUIQAMainPageUI();}#endregion }
}using QAModule;
using UnityEngine;
using UnityEngine.UI;
using TEngine;namespace GameLogic.UI
{[Window(UILayer.UI)]public class QAPanelNumerical : QAPanelBaseQAPanelNumerical{protected QANumericalData _numericalData;//需要记忆存储的参数protected static float _increment;protected static float _decrement;protected static float _incrementRate;protected static float _decrementRate;// _increment _incrementRate * _addSliderValueprivate static float _incrementSliderValue;private static float _decrementSliderValue;private static string _displayValue;#region 脚本工具生成的代码protected GameObject m_goAdd;protected GameObject m_goMinus;private Text m_textDisplayType;private Text m_textDisplayValue;protected InputField m_inputAddInputField;private Text m_textIncrement;protected Slider m_sliderAddValues;private Button m_btnAddValues;protected InputField m_inputMinusInputField ;private Text m_textDecrement;protected Slider m_sliderMinusValues ;private Button m_btnMinusValues;public override void ScriptGenerator(){base.ScriptGenerator();m_goAdd FindChild(ControlZone/m_goAdd).gameObject;m_goMinus FindChild(ControlZone/m_goMinus).gameObject;m_textDisplayType FindChildComponentText(DisplayZone/DisplayBg/m_textDisplayType);m_textDisplayValue FindChildComponentText(DisplayZone/DisplayBorder/m_textDisplayValue);m_inputAddInputField FindChildComponentInputField(ControlZone/m_goAdd/m_inputAddInputField);m_textIncrement FindChildComponentText(ControlZone/m_goAdd/m_inputAddInputField/m_textIncrement);m_sliderAddValues FindChildComponentSlider(ControlZone/m_goAdd/m_sliderAddValues);m_btnAddValues FindChildComponentButton(ControlZone/m_goAdd/m_btnAddValues);m_inputMinusInputField FindChildComponentInputField(ControlZone/m_goMinus/m_inputMinusInputField );m_textDecrement FindChildComponentText(ControlZone/m_goMinus/m_inputMinusInputField /m_textDecrement);m_sliderMinusValues FindChildComponentSlider(ControlZone/m_goMinus/m_sliderMinusValues );m_btnMinusValues FindChildComponentButton(ControlZone/m_goMinus/m_btnMinusValues);m_sliderAddValues.onValueChanged.AddListener(OnSliderAddValuesChange);m_btnAddValues.onClick.AddListener(OnClickAddValuesBtn);m_sliderMinusValues .onValueChanged.AddListener(OnSliderMinusValuesChange);m_btnMinusValues.onClick.AddListener(OnClickMinusValuesBtn);}#endregionprotected override void InitData(QABaseData data){base.InitData(data);_numericalData data as QANumericalData;m_textType.text Test - _numericalData?.TestType;_displayValue _numericalData?.InitDisplayValue;if (_numericalData ! null) _incrementRate _numericalData.IncrementRate;if (_numericalData ! null) _decrementRate _numericalData.DecrementRate;}protected override void ReadDataFromMemory(){m_sliderAddValues.value _incrementSliderValue 0 ? 1 : _incrementSliderValue;m_sliderMinusValues.value _decrementSliderValue 0 ? 1 : _decrementSliderValue;}protected override void AddListener(){m_inputAddInputField.onValueChanged.AddListener(OnInputAddField);m_inputMinusInputField.onValueChanged.AddListener(OnInputMinusField);}protected override void InitPanel(){//是否是初始数据。是表中获取。否用上次设过值的if (_incrementRate 0 _decrementRate 0){if (_numericalData ! null){_incrementRate _numericalData.IncrementRate;_decrementRate _numericalData.DecrementRate;}}_increment _incrementRate * m_sliderAddValues.value;_decrement _decrementRate * m_sliderMinusValues.value;//初始化面板显示m_textDisplayType.text Current _testType;m_textIncrement.text $Increment:{_increment};m_textDecrement.text $Decrement:{_decrement};if (_displayValue null){_displayValue _numericalData?.InitDisplayValue;m_textDisplayValue.text _numericalData?.InitDisplayValue; }else{m_textDisplayValue.text _displayValue;}}#region 事件/// summary/// 设置参数倍率/// /summary/// param namevalue/paramprivate void OnSliderAddValuesChange(float value){_increment value * _incrementRate;m_textIncrement.text $Increment:{_increment};_incrementSliderValue value;}protected virtual void OnClickAddValuesBtn(){//Change Panelfloat curValue float.Parse(m_textDisplayValue.text);curValue _increment ;m_textDisplayValue.text curValue.ToString();_displayValue curValue.ToString();//Test Function}private void OnSliderMinusValuesChange(float value){_decrement value * _decrementRate;m_textDecrement.text string.Format(Decrement:{0}, _decrement);_decrementSliderValue value;}protected virtual void OnClickMinusValuesBtn(){//Change Panel表现float curValue float.Parse(m_textDisplayValue.text);curValue - _decrement ;m_textDisplayValue.text curValue.ToString();_displayValue curValue.ToString();//Test Function//.....}/// summary/// 通过输入框自定义参数值/// /summaryprivate void OnInputMinusField(string inputParma){//更新倍率_decrementRate float.Parse(inputParma);//更新面板m_sliderMinusValues.value 1;_decrement _decrementRate * m_sliderMinusValues.value;m_textDecrement.text string.Format(Decrement:{0}, _decrement);}private void OnInputAddField(string inputParma){_incrementRate float.Parse(inputParma);m_sliderAddValues.value 1;_increment _incrementRate * m_sliderAddValues.value;m_textIncrement.text string.Format(Increment:{0}, _increment);}#endregion}
}
数值类型的面板如上图2为了便于控制一次加减的值我做了4档可输入计算器。可以根据倍率准确定位数值做到对大小数值的便捷测试。
// _increment _incrementRate * _addSliderValue
//实际值 倍率 * 滑动条的档数数据和表现分离
所以以上两层继承完成了通过点击面板完成UI界面数值的更替。现在需要把相关更替的数值注入到指定的数据集中【即做出实际的测试功能】那么只需要再让具体的XX测试 继承数值测试然后读取相应字段重写 -按钮的回调函数跟据读取的数值做相应功能就行了。
using TEngine;
using GameLogic.DKSystem.Soical;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI,QAPanelNumerical)]public class QAPanelGold : QAPanelNumerical{protected override void OnClickAddValuesBtn(){//数据base.OnClickAddValuesBtn();var gold (int)_increment ;PlayerService.AddGold(gold);Debug.Log(string.Format({0} {1} success., _testType, gold));}protected override void OnClickMinusValuesBtn(){base.OnClickMinusValuesBtn();var gold (int)_decrement;PlayerService.AddGold(-gold);Debug.Log(string.Format({0} - {1} success., _testType, gold));}protected override void OnClickBackBtn(){base.OnClickBackBtn();GameModule.UI.CloseWindowQAPanelGold();}}
}using TEngine;
using GameLogic.DKSystem.Soical;
using QAModule;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI,QAPanelNumerical)]public class QAPanelExp : QAPanelNumerical{protected override void InitPanel(){base.InitPanel();m_goMinus.SetActive(false);}protected override void OnClickAddValuesBtn(){//数据base.OnClickAddValuesBtn();var exp (int)_increment ;PlayerService.AddExp(exp);Debug.Log(string.Format({0} {1} success., _testType, exp));}protected override void OnClickMinusValuesBtn(){base.OnClickMinusValuesBtn();var exp (int)_decrement;PlayerService.AddExp(-exp);Debug.Log(string.Format({0} - {1} success., _testType, exp));}protected override void OnClickBackBtn(){base.OnClickBackBtn();GameModule.UI.CloseWindowQAPanelExp();}}
}using GameLogic.DKSystem;
using TEngine;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI,QAPanelNumerical)]public class QAPanelStar : QAPanelNumerical{protected override void InitPanel(){base.InitPanel();m_inputAddInputField.gameObject.SetActive(false);m_inputMinusInputField.gameObject.SetActive(false);m_sliderAddValues.gameObject.SetActive(false);m_sliderMinusValues.gameObject.SetActive(false);}protected override void OnClickAddValuesBtn(){base.OnClickAddValuesBtn();AnswerRankService.PostSta(new StaData(){season_id WikipediaQuizSystem.Instance.SeasonId,is_victory 3},null);Debug.Log(增加1个星星);}protected override void OnClickMinusValuesBtn(){base.OnClickMinusValuesBtn();AnswerRankService.PostSta(new StaData(){season_id WikipediaQuizSystem.Instance.SeasonId,is_victory 1},null);Debug.Log(减少1个星星);}protected override void OnClickBackBtn(){base.OnClickBackBtn();GameModule.UI.CloseWindowQAPanelStar();}}
}面板
using UnityEngine;
using UnityEngine.UI;
using TEngine;
using QAModule;namespace GameLogic.UI
{[Window(UILayer.UI)]public class TestOption : UIWidget{private TestType _type;private int _optionIndex;private Button m_btnTestOption;#region 脚本工具生成的代码private Image m_imgBg;private Text m_textTestOption;public override void ScriptGenerator(){m_imgBg FindChildComponentImage(m_imgBg);m_textTestOption FindChildComponentText(m_textTestOption);}#endregion/// summary/// 根据index查找对应测试的名称类型/// /summary/// param nameindex/param/// param nametype/param/// param namedescription/parampublic void Initialize(int index,TestType type,string description){m_btnTestOption gameObject.GetComponentButton();m_btnTestOption.onClick.AddListener(OnClickTestOptionBtn);_optionIndex index;m_textTestOption.text description;m_imgBg.color Color.cyan;}private void InitWorkflow(int index,TestType type){TestProcessManager.Instance.CurTestType type;TestProcessManager.Instance.SelectTestProcess(index);}#region 事件private void OnClickTestOptionBtn(){InitWorkflow(_optionIndex,_type);}#endregion}
}打开并创建界面的核心是 创建工作流、先初始化再创建。方法在工作流管理器调用
单例的工作流管理器
using Aliyun.OSS;
using GameBase;
using UnityEngine;
using UnityEngine.UI;
using TEngine;
using QAModule;namespace GameLogic.UI
{/// summary/// 测试项目的种类/// /summarypublic enum TestType{NumericalType 0, //数值类型测试AnimationType 1, //动画类型测试ProcessType 2, // 流程类型测试ElseType 3 //自定义测试类型}public class TestProcessManager : SingletonTestProcessManager{public TestType CurTestType;public void SelectTestProcess(int index){switch (CurTestType){case TestType.NumericalType:NumericalProcessFlow numericalProcessFlow new NumericalProcessFlow(index);numericalProcessFlow.CreateTestPanel();break;case TestType.AnimationType:break;case TestType.ProcessType:break;}}protected override void Initialize(){}protected override void UnInitialize(){}}}