登录注册页面
先写登录页面
1.在Unity的中先创建一个panel_Login ,点击将分辨率调成1280x720,然后中右键UI创建一个panel。然后在panel中添加Text,InputField,Button组件,做一个页面。
同样做出来一个注册页面一个提示页面。
这里是Canve的设置 具体我也不清楚,说是为了克隆出来的页面适1280x720的分辨率,不会因为分辨率出现页面变乱;
2.下面开始为每个页面写脚本。在中右键 选中create-》floder 创建一个Scripts文件夹。在文件夹中创建三个脚本。分别命名为UILogin,UIRegister,UITips,UIManager,GameData脚本。拖动脚本挂在三个页面上,UIManager挂在上,以后管理各个页面的时候 写路径很好写。获取组件的方法比如获取InputField的InputField组件时,直接在UILogin脚本中引用using UnityEngine.UI; public InputField Login; 在start()方法中初始化中Login=transform.Find("InputField").getComponent<InputField>(); 获取输入框的内容,Login.text;
3.登录页面的代码
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.Events;
using LitJson;
//结构定义
public delegate int AddDele(int x, int y);
public class UiLogin : MonoBehaviour
{
public InputField InputUser, InputPassword;
public Button loginBtn;
public Toggle toggle;
// Use this for initialization
void Start()
{
InputPassword = transform.Find("InputField_Pass").GetComponent<InputField>();
InputUser = transform.Find("InputField_User").GetComponent<InputField>();
//UnityAction call = ClickTest2;
//ClickTest1();
//call();
////添加按钮事件
//loginBtn.onClick.AddListener(call);
//loginBtn.onClick.AddListener(ClickTest1);
//loginBtn.onClick.RemoveListener(call);
/*
loginBtn.onClick.AddListener(delegate ()
{
Destroy(gameObject);
});
// 多播 委托
UnityAction call1 = ClickTest2;
call1 += ClickTest1;
call1 -= ClickTest1;
call1 -= ClickTest1;
call1();
//匿名委托
call1 = delegate ()
{
Debug.Log("11111111111");
};
call1();
AddDele add;//null
add = delegate (int a,int b)
{
return a - b;
};
int res = add(10, 20);//30
//lamda 表达式
add = (a, b) => a + b;
call1 = () => Debug.Log("111");
*/
//判断 之前是否记住密码,且帐号密码是啥?读取本地数据
AccountModel last = GameData.Instance.CheckLastAccount();
if (last!=null)
{
InputPassword.text = last.Password;
InputUser.text = last.User;
}
}
public void ClickTest1()
{
Debug.Log("ClickTest1");
}
public void ClickTest2()
{
Debug.Log("ClickTest222");
}
public void ClickLogin()
{
string UserStr = InputUser.text;
string PasswordStr = InputPassword.text;
//和存储的帐号信息进行比对
bool isok =GameData.Instance.CheckAccountOk(UserStr, PasswordStr);
if (isok)
{
UITip tip = UIManager.Instance.CreatePanel<UITip>("Tips");
tip.SetTip("成功!!!!",delegate()
{
UIManager.Instance.CreatePanel("Level");
Destroy(gameObject);
});
//回调函数
}
else
{
UITip tip = UIManager.Instance.CreatePanel<UITip>("Tips");
tip.SetTip("失败!!!!");
return;
}
//判断是否勾选上记住密码,存数据
bool ison = toggle.isOn;
if (ison)
{
AccountModel acc = new AccountModel();
acc.User = UserStr;
acc.Password = PasswordStr;
GameData.Instance.SaveLastAccount(acc);
}
}
public void ClickToRes()
{
UIManager.Instance.CreatePanel("Res");
Destroy(gameObject);
}
}
public void ClickLogin(){};方法 和登录按钮绑定,可以先获取登录按钮的Button组件btn,然后在Start()方法中通过btn.onClick.AddListener();给按钮绑定方法(),AddLister()参数是一个无返回值,无参数的委托。直接填入方法名ClickLogin就行了。
点击登录按钮时,需要开始判断账号密码是否存在,如果存在,登录成功,如果不存在登录失败。要想把账号和密码两个字符串存在一起不好存,如果单个存怎么存。所以创建一个AccountModel类,这个类不需要继承MonoBehaviour。
public class AccountModel {
public string userName;
public string passWord;
}
类中定义了两个字段userName,passWord 用public 关键字修饰,初学Unity,现在对private和public和理解(public可以通过在其他类中通过创建对象的方式来访问,private只能在当前类中访问)。定义完这个类之后就可以就可以把userName和passWord存在AccountModel的对象中。然后在创建一个List<AccountModel>链表来存AccountModel对象。之后需要访问userName和passWord时 ,就可以通过链表,取到AccountModel对象,然后对象.出来字段来访问。
Gamedate类用来处理这些账号信息的存储,比较,和持续性存储。
老师把GameData这个类做成了单例。这样在其他类中调用GameData类中的方法时就不需要创建对象然后再调用了。暂时是这么理解的。在GameData这个类中定义了一个public bool CheckAccountOk(string user,string pass)方法,有两个string类型的参数,返回值类型是bool,
public bool CheckAccountOk(string user,string pass)
{
for (int i = 0; i < accountData.Count; i++)
{
if (user == accountData[i].User && pass == accountData[i].Password)
{
return true;
}
}
return false;
}
//帐号数据 泛型
List<AccountModel> accountData = new List<AccountModel>();
accountData是存储AccountModel类型的链表的对象。这个方法用for循环对accountData链表进行了遍历,读取AccountModel对象,点出来字段和传入的参数进行对比,如果一直,return true; 如果不一致返回false;ps:单例的声明方法,public static GameData Instance; 在void Awake(){};方法中初始化Instance=this;没注册之前,accountData链表是空的,所以登录都是失败。
4.注册页面
第一步还是先获取输入框的引用。注册页面有一个userName输入框,和连个passWord输入框。如果两次输入密码不一致注册失败,提示密码不一致。然后把代码return掉;把代码return掉,把代码return掉。如果两次密码一致,再判断用户名是否重复。如果重复,return掉。如果不重复,则存储账号密码。跳转到登录页面。
public void ClickConfirm()
{
string userNameStr = userName.text;
string passWordStr = passWord.text;
string passWordStr2 = passWord2.text; //1.比对密码是否一致 if (passWordStr!=passWordStr2) { Tips tip = UIManager.Instance.CreatePanel<Tips>("Tips"); tip.SetTip("密码不对"); return; } if (GameData.Instance.CheckAccountRepeat(userNameStr)) { Tips tip = UIManager.Instance.CreatePanel<Tips>("Tips"); tip.SetTip("用户名重复"); return; } //存储账号密码 AccountModel newAccount = new AccountModel(); newAccount.userName = userNameStr; newAccount.passWord = passWordStr; GameData.Instance.AddAccount(newAccount); //4.跳转打登录界面 UIManager.Instance.CreatePanel("Login"); DestroyObject(gameObject); }}存储密码的时候通过单例调用过了Gamedata方法中的AddAccount();方法 public void AddAccount(AccountModel model)
{
accountData.Add(model);
SaveData();
}
public void SaveData()
{
//JsonAPI 对象-》json string
string str = JsonMapper.ToJson(accountData);
//file 持久化
File.WriteAllText(path + "/account.data", str);
}
这个方法传入参数是AccountModel model 一个AccountModel的对象,执行添加到accountData链表中。SaveData方法调用JsonMapper.ToJson()方法,方法参数是一个对象返回值是string,名字是ToJson() 意思也就是把对象装换呈Json字符串。使用JsonMapper之前需要导入LitJson。给我的感觉和创建AccountModel好像,Json字符串也是Json介绍 ,Json在线转换把账号密码一对一对的存储起来。然后读取的时候可以通过JsonMapper.ToObject<List<AccountModel>>(str);来返回一个对象,str是之前通过JsonMapper.ToJson();参数是一个对象,转换来的Json类型的字符串。来得到AccountModel对象。然后再通过对象来获取字段进行比较。之前已经通过JsonMapper.ToJson();参数是一个对象,和File.WriteAllText()参数是一个路径path,和一个string将对象转换的Json字符串存到了本地。但是每次运行的时候,链表都是空的,并不能验证之前是否注册存储过这个账号,所以要在GameData中读取之前存储的账号密码。所以定义了一个LoadData方法。方法中,先用File.ReadAllText(path+"/account.data");读取存储在文件中的Json字符串,然后再用JsonMapper.ToObject<List<AccountModel>>(str)把读取的Json字符串,转换成accountData链表。那么现在accountData就有了初始值。
public void LoadData()
{
/*
AccountModel a = new AccountModel();
a.User = "aaa";
a.Password = "123";
accountData.Add(a);
string path = Application.dataPath + "/Data/aaa.kk";
string contents = a.User +" "+ a.Password;
//写入
File.WriteAllText(path, contents);
//读取
//File.ReadAllText(path);
// a ——> Json格式的字符串
string str = JsonMapper.ToJson(accountData);
// Json格式的字符串 ——> a
List<AccountModel> aaas = JsonMapper.ToObject<List<AccountModel>>(str);
*/
//1.File 读帐号数据
if (File.Exists(path + "/account.data"))//不存在:true
{
string accountJson = File.ReadAllText(path + "/account.data");
//2.使用JsonAPI 转
accountData = JsonMapper.ToObject<List<AccountModel>>(accountJson);
}
//1.File 读关卡数据
if (File.Exists(levelDataPath))//不存在:true
{
string json = File.ReadAllText(levelDataPath);
//2.使用JsonAPI 转
levelData = JsonMapper.ToObject<List<LevelModel>>(json);
}
}
写了3个小时写了这点,还有Tips页面的两句代码没搞懂。还有用Toggle组件,来控制是否记住密码的功能没有实现。