2018-03-23 20:07:47 MadBam_boo 阅读数 774
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity3d实战之Unity3d网络游戏实战篇(13):登录&注册面板

学习书籍《Unity3d网络游戏实战》 罗培羽著 机械工业出版社
本文是作者在学习过程中遇到的认为值得记录的点,因此引用的代码等资源基本出资罗培羽老师的书籍,如有侵权请联系,必删。

 建立好网络模块后,我们可以开始对UI进行编程,实现可视化的登录注册面板。在第二节-代码资源分离的界面系统中,实现了Panel基类,之后的所有面板都会基于该基类并根据需求进行实现。本节给出登录、注册的实例。

 1、登录面板
 根据自己的喜好构建一个登录界面,这里给出一个测试样例:
 这里写图片描述
 注意,其中的Panel和Tips是Canvas下的空物体,用于对各种Panel进行分组,他们拥有的是Rect Transform组件而不是Transform组件。
 LoginPanel本身是Panel类型,以Text为后缀的是Text类型,以Input为后缀的是IntputField类型,以Btn为后缀的是Button类型。记得将LoginPanel拖拽到Resources文件夹中,因为PanelMgr的OpenPanel方法将从Resources文件夹中寻到对应的Panel并实例化。

 根据LoginPanel所示,我们在登录时需要输入用户名、密码、点击登录或者注册。这四个物体使我们所关注的。
 创建C# Script,命名为LoginPanel,声明四个变量:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;   // don't forget it.

public class LoginPanel : PanelBase {
    /*
     * Add a logout listener.
     */
    private InputField idInput;  // InputField of user name 
    private InputField pwInput;  // InputField of password
    private Button loginBtn;     // Button of login
    private Button regBtn;       // Button of register
}

 然后,按照需求重载父类PanelBase的Init()方法和OnShowing()方法:

#region Operation-Cycle
public override void Init (params object[] args)
{
    base.Init (args);
    skinPath = "LoginPanel";
    layer = PanelMgr.PanelLayer.Panel;
}

public override void OnShowing ()
{
    base.OnShowing ();
    Transform skinTrans = skin.transform;
    idInput = skinTrans.Find ("idInput").GetComponent<InputField> ();
    pwInput = skinTrans.Find ("pwInput").GetComponent<InputField> ();
    loginBtn = skinTrans.Find ("loginBtn").GetComponent<Button> ();
    regBtn = skinTrans.Find ("regBtn").GetComponent<Button> ();

    loginBtn.onClick.AddListener (OnLoginButtonClick);
    regBtn.onClick.AddListener (OnRegisterButtonClick);
}
#endregion

 在Init()方法中,将skinPath设置为LoginPanel,这样调用PanelMgr.OpenPanel方法才能在Resource文件夹中找到对应的Panel。
 在OnShowing()方法中,首先,获取到LoginPanel的实例的Transform组件,然后使用Transform.Find(string name).GetComponent<>()来获取需要用到的组件。并给Button添加点击事件。

 当用户点击Login按钮时,Client需要检测用户输入的用户名和密码是否为空,如果为空则输出对应的提示信息(Tips组的Panel,实现方法与LoginPanel的方法相似,读者可尝试自行实现);否则,将用户名和密码打包成消息发送给服务端,并等待服务端的处理结果,根据处理结果决定用户是进入游戏大厅还是输出提示信息。
 当用户点击Register按钮时,跳转到RegisterPanel,关闭LoginPanel。

#region OnButtonClickEvent
void OnLoginButtonClick()
{
    if (idInput.text == "" || pwInput.text == "") {
        //Debug.Log ("[LoginPanel.OnLoginButtonClick] Id and pw can't stay empty.");
        PanelMgr.instance.OpenPanel<TipPanel>("","Id and pw can't stay empty.");
        return;
    }

    if (NetMgr.servConn.status != Connection.Status.Connected) {
        NetMgr.servConn.proto = new ProtocolBytes ();
        if (!NetMgr.servConn.Connect ("127.0.0.1", 1234)) {
            PanelMgr.instance.OpenPanel<TipPanel> ("", "Connect server fail.");
        }
    }

    ProtocolBytes protocol = new ProtocolBytes ();
    protocol.AddString ("Login");
    protocol.AddString (idInput.text);
    protocol.AddString (pwInput.text);
    Debug.Log ("[LoginPanel.OnLoginButtonClick] Send protocol: Login " + idInput.text + "[id] " + pwInput.text + "[pw]");
    NetMgr.servConn.Send (protocol, OnLoginBack);
}

void OnRegisterButtonClick()
{
    PanelMgr.instance.OpenPanel<RegisterPanel> ("");
    Close ();
}
#endregion

 在Register的点击事件中,我们先对用户输入进行判空处理,然后对用户的网络连接进行检测,之后再打包用户输入的用户名和密码,发送给服务端并等待处理结果。在事件结尾我们使用了NetMgr.servConn.Send (protocol, OnLoginBack);,(详情传送门走起)当接收到服务端返回的处理结果后,Client将调用OnLoginBack方法,根据结果执行不同的逻辑。

#region OnBackEvent
void OnLoginBack(ProtocolBase protoBase)
{
    ProtocolBytes protocolRec = (ProtocolBytes)protoBase;
    int start = 0;
    string protoName = protocolRec.GetString (start, ref start);
    int result = protocolRec.GetInt (start, ref start);
    if (result == 0) {
        //Debug.Log ("[LoginPanel.OnLoginBack] Login success. ");
        PanelMgr.instance.OpenPanel<TipPanel>("","Login success. ");
        PanelMgr.instance.OpenPanel<LobbyPanel> ("");
        Close ();
    }else{
        //Debug.Log ("[LoginPanel.OnLoginBack] Login fail. ");
        PanelMgr.instance.OpenPanel<TipPanel>("","Login fail. Please check your username and password.");
    }
}
#endregion

 如果用户密码正确,进入大厅,否则弹出错误提示。

 2、注册面板
 测试样例:
 这里写图片描述
 需要用到的UI跟LoginPanel相差不大,只是多了一个确认密码的UI而已。其他部分改改Text、改改位置即可。
 在RegisterPanel中,增加了一个Repaet UI,用于用户密码的二次确认。其他部分跟LoginPanel类似,因此,RegisterPanel脚本跟LoginPanel脚本不同的地方就在于对用户的输入的密码增加一个二次确认的判断,其余部分相差不大,读者可自行体会:
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class RegisterPanel : PanelBase {

    private InputField idInput;
    private InputField pwInput;
    private InputField rpInput;
    private Button regBtn;
    private Button closeBtn;

    #region Operation-Cycle
    public override void Init (params object[] args)
    {
        base.Init (args);
        skinPath = "RegisterPanel";
        layer = PanelMgr.PanelLayer.Panel;
    }

    public override void OnShowing ()
    {
        base.OnShowing ();
        Transform skinTrans = skin.transform;
        idInput = skinTrans.Find ("idInput").GetComponent<InputField> ();
        pwInput = skinTrans.Find ("pwInput").GetComponent<InputField> ();
        rpwInput = skinTrans.Find ("rpInput").GetComponent<InputField> ();
        regBtn = skinTrans.Find ("regBtn").GetComponent<Button> ();
        closeBtn = skinTrans.Find ("closeBtn").GetComponent<Button> ();

        regBtn.onClick.AddListener (OnRegisterButtonClick);
        closeBtn.onClick.AddListener (OnCloseButtonClick);
    }
    #endregion

    #region OnButtonClickEvent
    void OnRegisterButtonClick()
    {
        // check empty input.
        if (idInput.text == "" || pwInput.text == "" || rpInput.text == "") {
            //Debug.Log ("[RegisterPanel.OnRegisterButtonClick] Id and pw and check pw can't stay empty.");
            PanelMgr.instance.OpenPanel<TipPanel>("","Id and pw and check pw can't stay empty.");
            return;
        }

        // check if the password correct.
        if (pwInput.text != rpInput.text) {
            //Debug.Log ("[RegisterPanel.OnRegisterButtonClick] Two password are different.");
            PanelMgr.instance.OpenPanel<TipPanel>("","Two password are different.");
            return;
        }

        // check the connection status
        if (NetMgr.servConn.status != Connection.Status.Connected) {
            NetMgr.servConn.clientProtocol= new ProtocolBytes ();
            if (!NetMgr.servConn.Connect ("127.0.0.1", 1234)) {
                PanelMgr.instance.OpenPanel<TipPanel> ("", "Connect server fail.");
            }
        }

        // send message
        ProtocolBytes protocol = new ProtocolBytes ();
        protocol.AddString ("Register");
        protocol.AddString (idInput.text);
        protocol.AddString (pwInput.text);
        Debug.Log ("[LoginPanel.OnRegisterButtonClick] Send protocol: Register " + idInput.text + "[id] " + pwInput.text + "[pw]");
        NetMgr.servConn.Send (protocol, OnRegisterBack);     // wait for result.
    }

    void OnCloseButtonClick()
    {
        PanelMgr.instance.OpenPanel<LoginPanel> ("");
        Close ();
    }
    #endregion

    #region OnBackEvent
    void OnRegisterBack(ProtocolBase protoBase)
    {
        ProtocolBytes protocol = (ProtocolBytes)protoBase;
        int start = 0;
        string protoName = protocol.GetString (start, ref start);
        int result = protocol.GetInt (start, ref start);
        //  if ok, open login panel, else print out tips panel.
        if (result == 0) {
            //Debug.Log ("[RegisterPanel.OnRegisterBack] Register success.");
            PanelMgr.instance.OpenPanel<TipPanel>("","Register success.");
            PanelMgr.instance.OpenPanel<LoginPanel> ("");
            Close ();
        } else {
            //Debug.Log ("[RegisterPanel.OnRegisterBack] Register fail.");
            PanelMgr.instance.OpenPanel<TipPanel>("","Register fail. Please use another id.");
        }
    }
    #endregion
}

 本节只举了LoginPanel和RegisterPanel两个例子,其他的面板实现方式都是类似的,如果有认真读懂这两个脚本的话,自己设计其他面板是没有太大的问题的。如果想要UI好看点,可以研究一下Unity3d的Aniimation。
 官方教程传送门-Unity3d Animation Tutorial

如果想要在打开面板前后加入动画或者其他逻辑,可以重载OnShowing和OnShowed方法;
如果想要在关闭面板前后加入动画或者其他逻辑,可以重载OnClosing和OnClosed方法。

 以上。

2017-11-05 15:20:45 eazey_wj 阅读数 470
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

【前言】

最近在做毕设项目,目前正在自己写整个登陆注册逻辑,使用 UGUI 来开发用户界面。在做的过程中“账号”这一模块既出现在“注册”界面,又出现在“登陆”界面,而“账号”模块输入验证的某些逻辑在两个界面中是有重合(在我的功能需求设计中)的,而我将事件代码完全的耦合在相应界面的脚本中,这就导致相同的逻辑我要在两个脚本出现相同的情况。

【解决】

目前一可行解决的办法是,将事件函数公开,利用 UGUI 提供的事件系统手动为各个 UI 响应控件指定事件,减少代码的重复度。

【结论】

UGUI 系统公开的事件函数的目的不单单让整个事件挂载变得可视化,我个人理解更深一步的,是共同的事件逻辑封装成可视化工具提供给各个需要此事件逻辑不同的对象。

【分析】

第一,将少量的相同逻辑封装成一个脚本,在较大的项目中较为不可取,因为增加了脚本数量而脚本中的代码较少。第二,在共同逻辑代码较少时我个人还是倾向中大型项目不使用编辑器的方式来指定,不管是个人开发还是多人开发(当然如果架构清晰,每个人负责功能模块比较小使用也无妨),因为编辑器的方式在管理起来还是不够清晰,一个界面一个主要的管理脚本还是我个人比较推崇的。

2018-01-04 19:40:57 Quest_sec 阅读数 1400
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

1.上午先拷贝安装包 注册账号 登入主界面 1h
然后学习一个函数OnGUI,三个模块Label,Button,RepeatButton,
体会按钮用法,点击按钮出现一张图片,点击第二个按钮 图片消失
2.做一个计时器
3.下午丰富计时器,条件语句,循环语句,做一个登陆界面,老师强调美观,可以自己改变字体以及颜色
4.今天的课后题
简述基于unity3d开发游戏的优势,以及热门游戏?炉石传说,王者荣耀,新仙剑OL等..
5.干货:
如果报错一直在增加? 说明没有赋初值。。
你容易错的是判断等于 == 双!
如果下面if(按某个键),它上面几行就不用声明这个键GUI.Button(new Rect(70,100,50,30),”exit”);了

GUI Style 图形用户界面样式 - Unity圣典
http://www.ceeger.com/Components/class-GUIStyle.html

Unity开发基础——类型转换学习笔记
http://blog.csdn.net/sinat_35761779/article/details/52170536

int string 类型转换

        GUI.Label (new Rect (10, 50, 512, 225),frametime.ToString());

以下是未经测试的360问答
比如 public int num=0; num++;
e.gameObject.name=(我的物体名字想要为num);
随后我又要获取 e.gameObject.name的名字 再转为int型该如何实现?
e.gameObject.name=num.ToString();
num=int.Parse(e.gameObject.name);

任务一:体会按钮控制图片展现或者消失

public class NewBehaviourScript : MonoBehaviour {

    public Texture img;
    public Texture img0;
    public Texture img1;
    void OnGUI()// to show 
    {

        GUI.Label (new Rect(10,150,100,100),img0);
        if (GUI.Button(new Rect(10,30,200,50),"yes"))
            img0 = img;
        if (GUI.Button(new Rect(260,30,200,50),"no"))
            img0 = img1;

    }

任务二:最简单的计时器:在点击下增加/减

public class NewBehaviourScript : MonoBehaviour {

    private int frametime;
    void OnGUI()// to show 
    {

        GUI.Label (new Rect(10,100,100,100),"time is "+frametime);
        if (GUI.Button(new Rect(10,30,200,50),"计时"))
            frametime++;


    }


    void Start () 
    {
        frametime = 0;

    }

任务三:点击一下开始自己增加/减

//无非是加循环啦然而???为什么用while它会直接从0变成100,增加一个变量一个循环 就可以依次增加了???

public class NewBehaviourScript : MonoBehaviour {

    private int frametime;
    private bool start;
    void OnGUI()
    {

        GUI.Label (new Rect (10, 50, 512, 225),"time is "+frametime);
        if (GUI.RepeatButton (new Rect (10, 10, 100, 40), "计时"))
        {
            start = true;
        //这个位置
        }
        if(start) //这个循环如果放在上句位置,就是鼠标按住的时候一直增,放开则停。而现在位置是一开始点击依一次,就一直增了。
        {
            frametime++;
        }
    }

    void Start () 
    {
        start = false;
        frametime = 0;
    }

任务四:在任务三基础上实现点击“暂停”按钮;并且解决减少到0后继续负数的问题;当然还可以实现到达0(截止)时跳出来一张图片(仿游戏某步)


public class NewBehaviourScript : MonoBehaviour {

    private int frametime;
    private bool start;
    public Texture img;
    public Texture img0;
    void OnGUI()
    {

        GUI.Label (new Rect (10, 50, 512, 225),"time is "+frametime);
        GUI.Label (new Rect (10, 100, 512, 225),img0);
        if (GUI.RepeatButton (new Rect (10, 10, 100, 40), "倒计时"))
        {
            start = true;

        }
        if (GUI.RepeatButton (new Rect (180, 10, 100, 40), "暂停"))
        {
            start = false;
        }
        if(start && frametime >0)
        {
            frametime--;
            if (frametime == 0) //当然while也行。//当这个条件语句放在下面位置为什么就不会出现图片了?
            {
                img0 = img;
            }
        }
        //没错这个位置(也就是两个条件语句不再嵌套而是同级)噢。。好像也是可以的
    }

    void Start () 
    {
        start = false;
        frametime = 1000;
    }

任务五:最终计时器可以提交咯

任务六:登录界面(没有数据库的情况下,用户名密码匹配采取硬匹配,进一步:那么多组资料 怎么办?)”最笨的打完;switch;还有?”

//单个用户的情况
using UnityEngine;
using System.Collections;


public class NewBehaviourScript : MonoBehaviour {

    private string userName;
    private string passWord;
    private string info;
    void OnGUI()
    {


    //  GUI.Button(new Rect(70,100,50,30),"Log in");
    //  GUI.Button(new Rect(130,100,50,30),"Empty");
        GUI.Label(new Rect(10,10,150,25),"用户名 ");
        GUI.Label(new Rect(10,50,150,25),"密码 ");
        GUI.Label(new Rect(70,150,200,30),info);
        GUI.Label(new Rect(70,150,200,30),info);
        userName = GUI.TextField(new Rect(60,10,150,25), userName,20);
        passWord = GUI.PasswordField (new Rect(60,50,150,25),passWord,'*',15);
        if (GUI.Button(new Rect(70,100,50,30),"Log in"))
        {
            if (userName == "admin" && passWord == "123456")
                info = "登录成功!";
            else
                info = "登录失败!请重新登录!";
        }
        if (GUI.Button(new Rect(130,100,50,30),"Empty"))
        {
            userName = "";
            passWord = "";
            info = "";
        }
    }
    void Start () 
    {
        userName = "";
        passWord = "";
    }

    void Update () 
    {       
    }
}

任务七:怎么美观文字啥的?

        string aa = "我们都很好";
        GUIStyle bb=new GUIStyle();
        bb.normal.background = null;    //这是设置背景填充的
        bb.normal.textColor=new Color(1,0,0);   //设置字体颜色的
        bb.fontSize = 40;       //当然,这是字体颜色
        GUI.Label(new Rect(0, 0, 200, 200), aa,bb);
2014-12-30 20:55:46 ti1an123 阅读数 417
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

  今天我们学习了unity的GUI的登陆注册
          
       先是登录,用GUI的Box方法,把它的边框给显示出来,登录账号用TextField方法来显示,用字符串来接受,密码用PasswordField方法来显示,用字符串来接受。
       然后登录和取消用GUI的 Buttom方法来先显示。在点击登录时,可以跳转到游戏界面。点击取消时,字符串为“”;
      
       登录
string str = "请输入账号";
string str1 = "";
void OnGUI()
{
GUI.Box(new Rect(100, 20, 150, 30), "欢迎登录");
GUI.Box(new Rect(20, 60, 60, 30), "姓名");
GUI.Box(new Rect(20, 100, 60, 30), "密码");
str = GUI.TextField(new Rect(100, 60, 150, 30), str);
str1 = GUI.PasswordField(new Rect(100, 100, 150, 30), str1, '*');

if (GUI.Button(new Rect(80, 140, 60, 30), "登录"))
{
Application.LoadLevel(2);
}
if (GUI.Button(new Rect(160, 140, 60, 30), "取消"))
{
str = "";
str1 = "";
}
}

        然后是注册 和登录差不多。
        
        
        string str = "请输入账号";
        string str1 = "";
        string str2 = "请输入年龄";
        string str3 = "请输入简介";
        public Texture2D img;

       void OnGUI()
       {

      GUI.Box(new Rect(100, 20, 150, 30), "欢迎注册");
      GUI.Box(new Rect(20, 60, 60, 30), "姓名");
      GUI.Box(new Rect(20, 100, 60, 30), "密码");
      GUI.Box(new Rect(20, 140, 60, 30), "年龄");
      GUI.Box(new Rect(20, 180, 60, 30), "简介");
      GUI.Box(new Rect(20, 290, 60, 30), "头像");
      str = GUI.TextField(new Rect(100, 60, 150, 30), str);
      str1 = GUI.PasswordField(new Rect(100, 100, 150, 30), str1, '*');
      str2 = GUI.TextField(new Rect(100, 140, 150, 30), str2);
      str3 = GUI.TextArea(new Rect(100, 180, 150, 100), str3);
      GUI.Label(new Rect(100, 290, img.width, img.height), img);

      if (GUI.Button(new Rect(80, 450, 60, 30), "注册"))
      {
      Application.LoadLevel(2);
       }
      if (GUI.Button(new Rect(160, 450, 60, 30), "取消"))
      {
        str = "";
        str1 = "";
        str3 = "";
        str2 = "";
      }
      }
      
        Application.LoadLevel()是跳转用的方法,()可以直接跟字符串(你所要调用的项目的名称),也可以跟(Application.loadedLevelName),但是后者只能调用本身,不能调用其他的项目。

2015-01-12 22:15:42 jingjingcrystal 阅读数 15213
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

unity学习,希望我的博客能给喜欢unity的朋友带来帮助


准备了几天的项目今天开始做了,我今天主要的任务就是做登陆注册界面,登陆注册界面要想好看点就要有背景图片,在unity中添加背景图片有两种方法,一种是通过代码来完成,还有一种是手动添加,我们都来看看吧。

       通过代码完成

  1. //声明一张图片
  2. public Texture2D img;

  3. //通过OnGUI方法执行下面操作
  4. void OnGUI()
  5. {
  6.         string aa = "";
  7.         
  8.         //构造一个空的GUIStyle
  9.         GUIStyle bb = new GUIStyle();
  10.         
  11.         //设置bb正常显示时是背景图片
  12.         bb.normal.background = img;
  13.         GUI.Label(new Rect(0, 0, 1370, 780), aa, bb);
  14. }

       手动添加:

              1、先创建一个新的摄像机,命名为Background Camera;

              2、新建一个GUI Texture,命名为Background Image;

              3、Background ImageInspector面板中点击Layer下拉窗口,选择“Add Layer添加一个新的层名称为“Background Image”;

       4、选中Background Image,做如下操作:

                     


               5、GameObjectLayer值设置为之前你添加的Background Image;

               6、选中Background Camera,进行如下操作:

                      

                7、选中主摄像机,Clear Flags设置为“Depth Only”,设置Culling Mask,取消选择“Background Image

    这样就完成了背景图片的设置。

    更多精彩请关注:http://unity.gopedu.com/


unity学习之在续NGUI

阅读数 456

没有更多推荐了,返回首页