06按钮,选择支和开始界面

 

本教程由水螅制作,教程内所有提供下载的练习素材皆为水螅制作,只可用于练习,不可用于其他用途。

事实上,选择支就只是按钮而已,和我们在一开始淡入淡出图片用的按钮没有区别(当然随着教程的进展,那些按钮已经被删掉了。)

假设我们想要做一个这样的选择支

在hierarchy里的Canvas上右键create empty建立一个空的gameobject,用来管理我们的选择支按钮,就叫他ui_selectbts好了

我们把它放在显示立绘的rfg1和显示对话框的ui_dialog之间,这样它不会被立绘挡住,而会被对话框挡住,这个位置对我来说是足够的,如果你有其他的需求,根据自己的需求来调整位置即可。

现在ui_selectbts只是一个透明的点,什么都没有,因为我们原本也只是用它来作为放置选择支按钮的容器。考虑到希望选择支能够在画面长宽比变化的时候跟着变化,我们将ui_selectbts的rect transform设置为这样

这个设置让ui_selectbts的尺寸永远和屏幕大小一样,当然因为是透明的其实什么都看不到,但是子gameobject的尺寸时根据父gameobject的尺寸来计算的,这样设置保证了我们的选择支按钮会跟着屏幕长宽比的变化而变化。

如果没有这种需求的话,就用默认设置也没关系啦。

在ui_selectbts上右键添加一个button,起名叫bt1好了,在source image里边选择ui_bg这张图,如果你有自己做好的其他用于选择支的图片,也可以用自己的,我这里直接和对话框使用一张图只是为了省事。

将bt1拖放到自己想要的尺寸

button会自带一个text的子object,如果你的按钮是图片上写死了文字的那种,可以把这个text删掉,但是我们现在是在做选择支,上边的文字必然是由脚本决定的,所以这个text要留着,为了测试效果,我们把它默认的文字改成“吃”

字号也根据选择支按钮的尺寸修改为了感觉合适的大小。

如果你喜欢,也可以改变颜色之类的其他参数。由于是选择支按钮,我们保持它的alignment为左右上下都居中对齐。

因为用了对话框的图片,为了看起来和对话框区分开,我改变了bt1的button里边的颜色,

按钮的变化有四种模式

默认的color tint模式下,是采取一张按钮图片,分别设置按钮普通状态、悬停高亮状态、按下去状态、不可使用状态的图片颜色,通过变色来进行按钮的提示。

如果你是从krkr时代过来的,则可以用sprite swap模式,分别设定四个状态的图片,这是和krkr一样通过切换显示的图片来提示按钮的状态。

animation模式是切换录制的动画,鉴于我们之前多次做过录制动画的部分,如果想要在这里使用应该对于现在的你也是很容易的。可以用来做非常豪华的按钮。

none就是完全没有变化,虽然还是会响应点击事件,但是画面上不会看出来有什么改变。

这次我选择用默认的color tint模式,设置了按钮变化的颜色,能够直接看出来的只有normal的颜色,其他颜色需要在play模式下用鼠标悬停活点击按钮才能看出来效果。

总之请按照自己的爱好来设置颜色吧。

鉴于按钮和文字一起淡入淡出会比较好看,我们点击bt1的inspector的add component,为bt1增加canvas group这个component。

改变这个component的alpha值可以将子物件的alpha一起改变并且没有两张半透明重叠的问题。

bt1已经没什么问题了,我们复制它来做其他的按钮。

选中bt1的情况下ctrl+c然后ctrl+v,复制一个一样的按钮,命名为bt2,把它拖动到你觉得合适的位置,将上边的文字改为“不吃”

这样从静态来,我们预先要达成的效果已经达成了。

但是和对话框一样,我们不可能只是想要个静态的东西。

那么,和对话框一样来录制淡入淡出的动画吧。在选中ui_selectbts后再animation界面新建它的动画进行录制。我就用按钮从左右飞出来这个效果吧。

同样的顺序录制淡出动画,再在animator里进行变量控制,因为不需要动画过渡,所以在所有过渡线那里都设成0

然后写对应的function,selectfadein()和selectfadeout()


   public void selectfadein(Dictionary<string, string> elm)

    {

        GameObject temp = GameObject.Find("ui_selectbts");

        Animator an = temp.GetComponent<Animator>();

        an.SetInteger("a_num", 1);

    }

    public void selectfadeout()

    {

        GameObject temp = GameObject.Find("ui_selectbts");

        Animator an = temp.GetComponent<Animator>();

        an.SetInteger("a_num", 2);

    }


到此为止,已经可以在脚本里用@selectfadein和@selectfadeout来控制选择选择支的出现和消失了,但是我们还需要可以用脚本定制文字。

@selectfadein text1=吃 text2=不吃

面对这样的脚本,要做的事情和之前一样,将参数传到selectfadein里边然后分别赋值给两个bt下叫做的Text的gameobject的叫做Text的component的text这个属性…………


    public void selectfadein(Dictionary<string, string> elm)

    {

        GameObject temp = GameObject.Find("ui_selectbts");

        temp.transform.Find("bt1/Text").gameObject.GetComponent<Text>().text = elm["text1"];

        temp.transform.Find("bt2/Text").gameObject.GetComponent<Text>().text = elm["text2"];

        Animator an = temp.GetComponent<Animator>();

        an.SetInteger("a_num", 1);

    }


然后我们还需要点击按钮之后能够跳转到想要的标签。姑且就按照krkr的脚本格式来将*开头的行作为标签吧。

我们想要写的脚本应该是这样

@selectfadein text1=吃 text2=不吃 target1=*t1 target2=*t2

对应的function就改成这样


    public void selectfadein(Dictionary<string, string> elm)

    {

        GameObject temp = GameObject.Find("ui_selectbts");

        temp.transform.Find("bt1/Text").gameObject.GetComponent<Text>().text = elm["text1"];

        temp.transform.Find("bt2/Text").gameObject.GetComponent<Text>().text = elm["text2"];

        //获取bt1的button

        Button b1 = temp.transform.Find("bt1").gameObject.GetComponent<Button>();

        //将上边所挂在的事件(如果有的话)全部删掉

        b1.onClick.RemoveAllListeners();

        //挂载新的事件

        b1.onClick.AddListener(delegate ()

        {

        //点击了选择支按钮后就先淡出选择支按钮

selectfadeout();

//然后跳转到传入的target1的标签

            jumpscript1(elm["target1"]);

        });

        b1 = temp.transform.Find("bt2").gameObject.GetComponent<Button>();

        b1.onClick.RemoveAllListeners();

        b1.onClick.AddListener(delegate ()

        {

        selectfadeout();

            jumpscript1(elm["target2"]);

        });

        Animator an = temp.GetComponent<Animator>();

        an.SetInteger("a_num", 1);

    }


这里我们之前没有用过的是Button的相关代码。可以见https://docs.unity3d.com/ScriptReference/UI.Button.html

其中AddListener比较复杂一点,AddListener 我们传进去的是个用delegate指向的无名函数,

delegate ()

        {

        selectfadeout();

            jumpscript1(elm["target2"]);

        }

delegate的用法见https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/delegate

就是说我们每点击一次这个按钮,就会执行一遍这个

()

        {

        selectfadeout();

            jumpscript1(elm["target2"]);

        }

这个无名函数

可以看到我们需要写一个叫做 jumpscript1的funciton用来在选择后跳转到自己想要跳转到的地方,另外也需要将*开头的是标签这件事情告诉我们的脚本解析程序,同时为了能从脚本层直接控制跳转,我们也写一个叫做jumpscript的用于从脚本层接受传过来的字典,再取出字典里指定的标签使用jumpscript1进行跳转。


 bool onscript()

    {

        if(scriptnum>=myscript.Length)

        {

            return false;

        }

        string line = myscript[scriptnum];

        print(line);

        scriptnum++;

        if(line.Length==0)

        {

            //如果这行为空就跳过这行

            return true;

        }

        else if(line.Substring(0,1)=="@")

        {

            //如果行首有@就作为一个function执行

            Dictionary<string, string> elm = new Dictionary<string, string>();

            string[] temparr = Regex.Split(line.Substring(1), " ", RegexOptions.IgnoreCase);

            string macroname = temparr[0];

            if (temparr.Length > 1)

            {

                for (int i = 1; i < temparr.Length; i++)

                {

                    string[] temparr1 = Regex.Split(temparr[i], "=", RegexOptions.IgnoreCase);

                    elm[temparr1[0]] = temparr1[1];

                }

            }

            if (elm.Count > 0)

            {

                SendMessage(macroname,elm);

            }

            else

            {

                SendMessage(macroname);

            }

            return false;

        }

        else if(line.Substring(0, 1) == "*")

        {

            //如果行首是*就视为标签不做任何处理直接执行下一行

            return true;

        }

        else

        {

            //如果行首没有@就把文字赋值给dtext等待对话框里显示

            dtext = line;

            return true;

        }

    }

    void jumpscript(Dictionary<string, string> elm)

    {

        jumpscript1(elm["target"]);

    }

    void jumpscript1(string target)

    {

        if (target != "")

        {

            for (int i = 0; i < myscript.Length; i++)

            {

                string temp = myscript[i];

                if (temp == target)

                {

                    scriptnum = i;

                    startscript();

                    return;

                }

            }

        }

        //如果要求跳转到不存在的标签,那就跳转到第一行

        scriptnum = 0;

        startscript();

    }


全部的脚本应该是这样


@bg1fadein storage=bg1

@fg1fadein storage=fg1 n=0

@dialogfadein

你吃不吃包子?

@textfadein

@selectfadein text1=吃 text2=不吃 target1=*t1 target2=*t2

*t1

@textfadeout

那就分你一半。

@jumpscript target=*c1

*t2

@textfadeout

不吃饱会长不高的。

*c1

@textfadein

@textfadeout

@dialogfadeout

@fg1fadeout

@bg1fadeout


那么点一下play,差不多就是这种感觉

但是我们发现,如果多次使用selectfadein后第一次选中的按钮之后会一直高亮着,解决方法是把所有按钮的navigation改成none,因为之前默认的是自动就会有默认高亮的行为。

那么,介绍了按钮的用法后,我们已经可以利用学到的东西来制作一个这样的游戏封面

因为存档读档之类的功能还没有说到,所以这里的封面就只有开始游戏和结束游戏两个按钮

那么这里需要的东西就是op1.jpgopbt1.png,opbt2.png

后边的花纹只是一张背景,我们可以直接用fadeinbg和fadeoutbg来控制,开始游戏和结束游戏的按钮则和选择支按钮组一样处理即可。为它们单独录制淡入淡出动画,写淡入淡出的function并给按钮附上事件(opbtfadein和opbefadeout)。


void opbtfadein()

    {

        GameObject temp = GameObject.Find("ui_opbts");

        Animator an = temp.GetComponent<Animator>();

        an.SetInteger("a_num", 1);

        //给开始游戏按钮挂载事件

        Button b1 = temp.transform.Find("bt1").gameObject.GetComponent<Button>();

        b1.onClick.RemoveAllListeners();

        b1.onClick.AddListener(delegate ()

        {

            //把开始界面按钮组淡出

            opbtfadeout();

            //把背景淡出,执行下一行

            bg1fadeout();

        });

        //给结束游戏按钮挂载事件

        b1 = temp.transform.Find("bt2").gameObject.GetComponent<Button>();

        b1.onClick.RemoveAllListeners();

        b1.onClick.AddListener(delegate ()

        {

            //结束游戏,游戏打包后才会生效,目前在测试模式下是无效的

            Application.Quit();

        });

    }

    void opbtfadeout()

    {

        GameObject temp = GameObject.Find("ui_opbts");

        Animator an = temp.GetComponent<Animator>();

        an.SetInteger("a_num", 2);

    }


Application是UnityEngine的class,具体功能见https://docs.unity3d.com/ScriptReference/Application.html

脚本部分加入开始界面的显示


@bg1fadein storage=op1

@opbtfadein

@bg1fadein storage=bg1

@fg1fadein storage=fg1

@dialogfadein

你吃不吃包子?

@textfadein

@selectfadein text1=吃 text2=不吃 target1=*t1 target2=*t2

*t1

@textfadeout

那就分你一半。

@jumpscript target=*c1

*t2

@textfadeout

不吃饱会长不高的。

*c1

@textfadein

@selectfadein text1=吃 text2=不吃 target1=*t1 target2=*t2

@textfadeout

@dialogfadeout

@fg1fadeout

@bg1fadeout


于是效果如下

那么我们下一篇来加入变量的控制吧。



TOP

访客数: 3382504
aa