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.jpg,opbt1.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
于是效果如下
那么我们下一篇来加入变量的控制吧。
Created by Hydrozoa.2011
不支持IE7以下浏览器
凯恩插件程序:Hydrozoa 美术:Hydrozoa,红渊