今天,结合一个游戏,简单了解一些基础键(QWERT)的用法以及(预制件) Material(材质球) Animator Controller(动画控制器)和 position(位置坐标)、scale(比例)等的用法。
在工具栏的下方,有五个按键。
第一个手的形状的按键对应键盘上的Q,按下Q以后,或者选中图标就可以通过按住鼠标左键(屏幕上的鼠标会变成手掌的样子)来对屏幕进行平板式的拖拽,或者按住鼠标中间的滚轴进行拖拽效果相同。
第二个上下左右箭头组合形状的按键对应键盘上的W,按下W后,或者选中图标在选定操作对象的情况下,就会出现物体的XYZ轴,对应默认显示为红绿蓝,选中某个轴后,选中轴为黄色。我们可以通过拖拽对应的轴来改变物体的坐标。(注意:必须选中轴以后,按轴拖动,否则按住物体拖动会出现xyz同时变化不利于对坐标的准确把握)
第三个箭头环绕状按键对应键盘的E,按下后或者选中图标会像地球的经纬线一样出现三个圆形包裹着球状物体。三个不同色的线同样对应XYZ,可在选中线后使物体绕着选中轴环绕转动。
第四个方框四散箭头的按键对应键盘的R,按下R后或者选中图标就可按照相应轴向拖拽来放大或者缩小物体。
第五个盒子形状按键对应键盘的T,按下或者选中后就会生成对应二维图像,UI做外观时常会用到。
Material(材质球)和Perfab(预制件)
材质球是很常用的。在创建物体时常常需要对外观进行改变,这个时候需要用到材质球。在屏幕下方右键创建一个Material,改变它的颜色。在新建一个Cube(正方体),将新的材质球拖给它,就可以看到变为一个有颜色的正方体。将新的正方体拖到Assect文件下就会生成一个Perfab(预制件)。通常在同一个物体大量被使用的时候,将它做成预制件,可以大量的节省空间同时便于操作。(注意:用预制件拖拽直接生成的新的cube就会和预制件完全相同,改变预制件则所有由预制件生成的物体全部随之改变,改变单的由预制件生成物体时在右边会出现三个按键:Select,Revert,Apply 选择恢复和应用 点击选择会选中生成此物体的预制件,点击恢复会消除对物体所做的改变恢复为和预制件完全相同的样子,点击应用会将对单个物体的改变应用到所有物体包括预制件。)
Animator Controller(动画控制器)
在Assets下创建一个动画控制器,双击打开,将准备好的动画拖进去,显示为黄色条状,表示为默认。将动画对象控制实体制成预制件,再将动画控制器绑给它保存后,将此预制件给相应的脚本来运行,则运行时动画就会显现出来。
简单脚本的书写
在Assets文件下新建一个C#脚本,将脚本拖给想要应用它的物体即可使物体按脚本改变。需要注意的是:不可将同一脚本重复拖给一个物体,将会产生错误。
新建一个脚本打开后,初始会自动生成的Start(实现初始化)和 Update(是一个一秒钟调用24次的事件)
例:代码创建81个cube。
void Start()
{
for (int x = 0; x < 9; x++)
{
for(int y = 0; y < 9;y++ )
{
GameObjectg=GameObject.CreatePrimitive(PrimitiveType.Cube);
g.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
g.transform.position = new Vector3(x, y,0);
}
}
}
代码结束后保存,并拖给一个空的游戏体运行就可以看到会出现81个方块组成一面墙的样子。
通过这个例子,我们可以初步做到用代码控制来生成一些物体,下面将我们刚刚创建好的预制件也应用进来。
给摄像机一个背景色,设置广角,位置,
创建一游戏体命名为Managers 包含两个子游戏体分别命名为为远的和进的管理器
分别创建 音乐 跑步者 背景 天际线文件夹 在天际线内 创建两个材质球 不同颜色 分别给两个cube 形成新的不同预制件 创建一个脚本 挂载给 远和近的管理器 通过脚本 控制生成不同高度 形状的背景墙。
创建一个单独的Cube作为runer。对它进行脚本控制,实现跑步者在高低不同的墙面上奔跑墙面会一直延伸的效果。(原理是占满屏幕的墙面控制个数组成一个队列,每当一个cube离开屏幕立即对它进行大小的改变再将它添加到队尾,模拟成墙面无穷无尽的样子。)
======给墙面的脚本
using UnityEngine;
using System.Collections;
usingSystem.Collections.Generic;//关于队列的命名空间
public classCreateWallScript :MonoBehaviour
{
publicTransform Prefab;//用来接收预制件
publicVector3 StartPosition;//开始位置
Vector3NextPosition;//下一个位置
publicint GameObjectNumber;//创建的物体个数
Queue<Transform> queueObjets;//Transform 类型的队列
publicVector3 Minsize;//最大的大小
publicVector3 MaxSize;//最小大小
voidStart()
{
queueObjets = newQueue<Transform>(GameObjectNumber);//队列长度为总个数的队列实例化
for(int i = 0; i < GameObjectNumber; i++)
{
queueObjets.Enqueue( (Transform)Transform.Instantiate(Prefab));//队列中加入指定预制件
}
NextPosition =StartPosition;//将开始坐标传给下坐标
for(int i = 0; i < GameObjectNumber; i++)
{
Recycle();//重复调用此方法
}
}
void Update()
{
if (objectQueue.Peek().localPosition.x + recycleOffset <CubeMoveScript.distance)
{
recycle();
}
}
privatevoid Recycle()
{
Vector3scale =newVector3(Random.Range(Minsize.x,MaxSize.x),Random.Range(Minsize.y,MaxSize.y),Random.Range(Minsize.z,MaxSize.z));//随机出一个大小
Transformo = queueObjets.Dequeue();//拿出队列D中D的第一个预制件
Vector3Position = NextPosition;//将开始坐标记录
Position.x += scale.x * 0.5f;//修改它的坐标
Position.y += scale.y * 0.5f;
o.localScale = scale;//将随机的大小赋给对象
o.position=Position;
NextPosition.x += scale.x;
queueObjets.Enqueue(o);
}
}
======给Runer的脚本
using UnityEngine;
using System.Collections;
public class RunnerScript : MonoBehaviour
{
public static float distance;
void Update()
{
transform.Translate(5f* Time.deltaTime, 0, 0);
distance = transform.position.x;
}
}
代码书写过程需要注意:
0. 脚本建成时就应该修改为相应的名称,在名称确认后在对其修改后台的代码中文件名不会改变,需要手动复制修改,否则运行将会报错。
1. 自己写代码时应注意方法的首字母应该大写,例如(Start 写为start)程序不会报错,但是代码会无法正常运行。
2. 创建游戏体来接收预制件时GameObject和Transform都可以用,但是若对其进行改变(在代码中将其修改为另一个)时,应注意所拖入的预制件应该重新拖入,否则运行时将会报错。
3. 公开定义的全局变量在前台会进行显示,并且可在前台修改它的值,在第一次定义它得值并在前台成功显示后,若重新打开代码修改它的值这样是无效的,前台的值不会改变,程序运行时会以前台设定的值为准运行。如需要修改值则在前台对应修改即可。
4. 公开定义的静态全局变量在前台是不会显示的。
5. Position和LocalPosition的区别:在没有物体内部嵌套时,两者相同,在有嵌套时,前者表示物体参照世界坐标的真实坐标,后者表示嵌套内部物体相对外部物体的相对坐标。
通过以上部分就能简单实现所需的部分功能了,接下来还有其他更多的功能,明天再来继续完成吧~
今天写脚本过程遇到很多问题,包括对很多东西的理解一时间好像懂了仔细一想又不懂了,确实让人心情烦躁了会儿,但是解决之后总结起来发现也就是这么点东西,并没有特别多,需要自己多理解,弄明白其中每个量的含义就可以清晰准确的写出代码了,遇到错误对现在的我来说也是一件好事,我还在学习,还可以出很多的错,还可以花时间去解决,这样的经验积累会让以后的我在大的项目的制作中更好的避免和解决错误。也欢迎大家给我多多指点~