物体的坐标
transform.position 世界坐标
transform.localPosition 相对坐标
设置物体的坐标:
this.transform.localPosition = new Vector3(1.5f, 0, 2.0f);
帧更新
Update(),称为帧更新
此方法会被游戏引擎定时调用,已更新游戏的状态
Time.time 游戏启动的时间
Time.deltaTime 距上次帧更新的时间差
Unity不支持固定帧率,但可以设定一个近似帧率
Application.targetFrameRate = 60;
指示Unity尽量以FPS = 60 的帧率更新游戏
移动物体
Vector3 pos = this.transform.localPosition;
pos.x += 0.01f;
this.transform.localPosition = pos;
// 运行游戏,物体沿X轴正向移动
匀速运动
使用deltaTime,让物体匀速运动
float speed = 3;
float distance = speed * Time.deltaTime;
Vector3 pos = this.transform.localPosition;
pos.x += distance;
this.transform.localPosition = pos;
物体的运动
一般使用transform.Translate(),实现相对运动
transform.Translate(dx,dy,dz,......)
其中,dx,dy,dz是坐标增量
Space.World,相对于世界坐标系
Space.Self,相当于本地坐标系(相对父元素)
transform.Translate(dx,dy,dz,Space.World)//沿着世界坐标系移动
运动的方向
1、获取目标物体
GameObject flag = GameObject.Find("红旗");//可以通过名字/路径查找物体
2、转向目标方向
this.transform.LookAt(flag.transform);//是物体的Z轴指向物体
3、向前运动,forward,+Z方向
this.transform.Translate(0,0,dz,Space.Self);
物体的旋转
欧拉角 Euler Angle
设置旋转角度时,一般使用localEulerAngles,而不是rotation
transform.eulerAngles = new Vector3(0,45,0);
transform.localEulerAngles = new Vector3(0,45,0);
在Update()修改角度,持续旋转:
Vector3 angles = transform.localEulerAngles;
angles.y += 0.5f;
transform.localEulerAngles = angles;
优化,使之匀速旋转
float rorareSpeed = 30;// 每秒钟转30度角
Vector3 angles = transform.localEulerAngles;
angles.y += rotateSpeed * Time.detalTime;
transform.localEulerAngles = angles;
相对旋转
Rotate(),旋转一个相对角度
this.transform.Rotate(dx,dy,dz,space.Self);
相当于:
Vector3 angles = transform.localEulerAngles;
angles.y += new Vector(dx,dy,dz);
transform.localEulerAngles = angles;
获取父物体
Transform parent = this.transform.parent;
脚本的运行
1、创建节点:
GameObject node = new GameObject();
2、实例化组件
MeshRenderer comp = new MeshRenderer();
3、实例化脚本组件
SimpleLogic script1 = new SimpleLogic();
4、调用事件函数
初始化 script1.Start();
帧更新 script1.Update();
Unity是一个纯面向对象的框架,对象由框架创建
同一个脚本可以挂在不同节点下多次使用
消息函数
所有的脚本,一般应继承于MonoBehaviour
消息函数,或称事件函数,一些回调函数
常见的消息函数:
- Awake:初始化,仅执行一次,先于Start调用且总是调用,即使组件被禁用
- Start:初始化,仅执行一次,第一次启动时调用
- Update:帧更新,每帧调用一次
- OnEnable:每当组件启用时调用
- OnDisable:每当组件禁用时调用
脚本执行顺序:
消息函数的调用顺序:
第一阶段初始化:
script1.Awake(),script2.Awake(),...
第二阶段初始化:
script1.Start(),script2.Strart(),...
帧更新:
script1.Update(),script2.Update(),...
主控脚本
主控脚本,即游戏的主控逻辑
可以创建一个空节点,为其添加主控脚本
脚本的参数
脚本的参数,用于控制脚本组件的功能
修改RotateY.cs,添加一个参数
public float rotateSpeed = 30f;
参数的用法:
- 参数必须为public,才可以在检查器中显示
- 参数的名称,即变量名:rotateSpeed -> Rotate Speed
- 参数的默认值,即变量的默认值,可以Reset菜单重置
- 参数的工具提示,可以用 [Tooltip()] 指定 : [Tooltip("旋转角速度")]
参数的赋值
当在多个函数内对参数进行赋值,赋值的顺序用伪代码表示为:
- RotateY script = new RotateY()
- script.rotateSpeed = 180f
- script.Awake()
- script.Start()
参数类型
参数的类型,分为值类型、引用类型
值类型:如 int、float、bool......
值类型(struct):如 Vector3、Color......
引用类型(class):如 GameObject、Transform、MeshRenderer......
public 类型 变量名 = 值;
值类型:
- 本身是一个值,可直接赋值
- 若未赋值,则默认为0
- 不能为null
结构体struct,也是值类型
引用类型:
- 节点:GameObject
- 组件:如 Transform、MeshRenderer、AudioSource...
- 资源:如 Material、Texture、AudioClip...
- 数组类型
运行时调试
在运行时可以对参数进行调试更改,但结束运行时更改的数据会重置,可以将运行时调试的数据进行复制和粘贴
运行时调试的数据复制:
运行结束后的数据粘贴:
鼠标键盘输入
游戏的输入,可以来自鼠标、键盘、触摸屏、游戏手柄等
组件的调用
组件Component,代表一个功能
例如:AudioSource可用于播放音乐、音效
其中,Play on Awake表示自动播放
在代码中,也可以用API来使其播放音乐
1、获取AudioSource组件
AudioSource audio = this.GetComponent<AudioSource>();
2、播放
audio.Play();
其中,<>表示泛型,即获取<AudioSource>类型的组件
引用别的组件
在脚本中,也可以引用别的物体下的组件
第一种办法:
public GameObject node;
在unity中可以设置node具体为哪个物体
然后引用组件:
AudioSource audio = node.getComponent<AudioSource>();
第二种办法:
直接引用,在检查中赋值
public AudioSource bgm;
然后直接将该参数赋值为该组件
引用脚本组件
一个脚本里,访问另一个脚本文件(和普通组件一样)
1、API获取
public GameObject node;
FanLogic fan = node.getComponent<FanLogic>();
2、直接引用
public FanLogic fan;
消息调用
消息调用 SendMessage,以“消息”的形式来调用另一个组件
找到目标节点:
public GameObject target;
向目标节点发送“消息”:
target.SendMessage("methodName",value);
在目标节点中定义mothodName方法
public void mothodName(){
}
获取物体
游戏物体 GameObject ,也可以叫 节点
1、按 名称 / 路径 获取(不推荐)
若不重名,可以按名称获取
GameObject node = GameObject.Find("名称“);
最好指定全路径
GameObject node = GameObject.Find("路径“);
不建议使用
- 执行效率低
- 不能自适应变化,当目标节点改名时会出错
2、引用获取
添加一个变量,在检查器引用目标
public GameObject wingNode;
父子物体
场景中的层级关系/父子关系,是由Transfrom维持的
获取父级:
Transfrom parent = this.transfrom.parent;
获取父级节点:
GameObject parentNode = this.transfrom.parent.gameObject;
获取子级:
1、foreach遍历
foreach(Transform child in transform)
{
Debug.Log("子物体:" + child.name);
}
2、GetChild(),按索引获取
例如,获取第0个子项
Transform aa = this.transform.GetChild(0);
3、transfrom.Find(),按名称查找子项
Transfrom aa = this.transfrom.Find("aa");
Transform bb = this.transform.Find("aa/bb");
其中,二级子级应该指定路径,如bb/cc
物体的操作
设置新的父级:
this.transform.SetParent(父级节点);
设为一级节点:
this.transform.SetParent(null);
其中,parent 为 null 表示一级节点(没有父级)
GameObject.setActive(),显示/隐藏
例如
Transform child = this.transform.Find("aa");
if (child.gameObject.activeSelf) //判断是否显示
{
chid.gameObject.SetActive(false);
}
else
{
child.gameObject.SetActive(true);
}
资源的使用
在脚本中,也可以引用一个资源
例如
- AudioClip:音频文件
- Texture:纹理贴图
- Material:材质
资源数组
在脚本中,也可以定义一个数组变量
比如,一个音乐盒,存了多首歌曲
public AudioClip[ ] songs;
定时调用
定时调用 Invoke*,即一般所谓的“定时器”
继承自 MonoBehaviour:
- Invoke( "func" , delay),只调用一次,延迟调用
- InvokeRepeating( "func" , delay , interval),循环调用
- IsInvoking( "func"),是否正在调度中
- CancelInvoke( "func" ),取消调度、从调度队列中移除
定时与线程
InvokeRepeating 定时调用,并没有创建新的线程
Unity引擎的核心的 单线程 的,不用考虑 线程、并发、互斥
获取当前线程号
using System.Threading;
int threadId = Thread.CurrentThread.ManagedThreadId
重复的调用
每次 InvokeRepeating,都会添加一个新的调度
取消调用
- IsInvoking( "func" ),判断 func 是否在 Invoke队列
- CancelInvoke( "func" ),取消 func 的 Invoke调用
- CancelInvoke( "func" ),取消当前脚本的所有 Invoke 调用
在 Invoke 时,一般要避免重复调用,形如
if ( !IsInvoking( func ))
{
InvokeRepeating( func , delay , interval )
}
向量
向量Verctor3,三维向量(x,y,z)
向量,即有方向的量
- 方向
- 长度
向量长度公式:
向量长度API:
Vector3 v =new Vector3(3,0,4);
float len = v.magnitude;
单位向量
单位向量,即长度为1的向量
例如:
Vector3 v1 = new Vector3(1,0,0);
Vector3 v2 = new Vector3(0.6f,0.8f,0);
标准化Normalize:缩放一个向量,使其长度为1
例如:
(3,4,0) -> (0.6,0.8,0)
(2,2,0) -> 0.070,0.070,0)
API:
Vector3 v1 = new Vector3(2,2,0);
Vector3 v2 = v1.normalized;
常用常量:
Vector3.zero 即 (0,0,0)
Vector3.up 即 (0,1,0)
Vector3.right 即 (1,0,0)
Vector3.forward 即 (0,0,1)
向量运算
向量加法,即 x y z三个分量分别相加
向量减法,即 x y z三个分量分别相减
向量乘法:
- 标量乘法 b = a * 2
- 点积 c = Vector3.Dot(a,b)
- 差积 c = Vector3.Cross(a,b)
其中,只要求掌握标量乘法,即对每一个分量相乘
例:
Vector3 a = new Vector3(1,2,0);
Vector3 b = a * 2; // (2,4,0)
向量赋值:
Vector3是值类型,可以直接赋值,但不能设为null
Vector3 a = new Vector3(1,1,0);
Vector3 b = a;
向量测距
用于求两物体间的距离
例如:
Vector3 p1 = this.transform.position; // 自己位置
Vector p2 = target.transform.position; // 目标位置
Vector direction = p2 -p1; // 方向向量
float distance = direction.magnitude; // 距离
API:
Vector3.Distance(a,b) :返回a与b之间的距离,与(a-b).magnitude相同
向量的使用
Vector3可以直接作为脚本的参数
预制体
预制体 Prefab,即预先制作好的物体
使用预制体,可以提高开发效率
预制体的创建
- 制作好一个样本节点
- 拖到Assets窗口,则自动生成一个*.prefab资源
- 原始物体不再需要,可以删除
在导出 prefab资源时,应该将依赖文件一并导出
prefab只是记录了节点的信息
perfab文件中不包含材质、贴图数据,仅包含引用
预制体的实例
Prefab Instance,由预制体创建得到的对象
特征:
- 在 Hierarchy中,节点图标不同
- 在 Hierarchy中,右键菜单 | Prefab
- 在 Hierarchy中,上下文工具 | Prefab
Prefab Instance 和原 Prefab之间存在关联
右键菜单 Prefab | Unpack,则解除关联,成为普通物体
预制体的编辑
*.Prefab相当于是一个模板,可以再次编辑
第一种方式:单独编辑
- 双击Prefab,进入单独编辑模式
- 编辑节点和组件
- 推出,完成编辑
第二种方式:原位编辑
- 选择 Prefab Instance
- 在检查器中Open
- Context显示:Normal / Gray / Hidden
此时,仅选中的物体被编辑,其余物体是陪衬
- 编辑节点
- 退出,完成编辑
第三种方式:覆盖编辑
- 选择Prefab Instance
- 直接在场景中编辑
- 编辑完后
- Overrides | Apply,应用编辑
- Overrides | Revert,取消编辑
多级节点
Prefab中,多级节点/父子关系,也是常见的情况
动态创建实例
创建Prefab之后,用API动态创建实例
API:Object.Instantiate(original,parent)
实例的销毁
Object.Destroy( obj ),用于销毁一个实例
Destroy() 不会立即执行,而是在本轮 Update之后才执行
物理系统
物理系统 Physics,即由物理规律起作用的系统
确切地说,是牛顿运动定律(力,质量,速度)
刚体组件 Rigidbody,物理学中的物体
- 给“物体”添加 Rigidbody组件 Physics | Rigidbody
- 运行游戏,此时,该物体在重力作用下运动
物体碰撞
物理系统也接管了物体的碰撞
碰撞体 Collider,描述了物体的碰撞范围
其中:
Box Collider,长方碰撞体
Sphere Colider,球形碰撞体
碰撞体的范围(可修改)
反弹和摩擦
刚体的反弹与摩擦,也归物理系统负责
1、新建物理材质 Phycici Material
2、设置参数物理材质的参数
3、添加给需要的物体
碰撞检测
检测两个物体是否接触
1 运动学刚体 Rigidbody / Is Kinematic
2 触发器模式 Collider / Is Trigger
3 消息函数 void OnTriggerEnter()
void OnTriggerEnter (Collider other)
{
}
Collider other ,表示对方的碰撞体
other.gameObject ,对方节点
other.name ,对方节点的名字。
天空盒
Skybox,游戏的背景
Window | Rendering | Lighting:光照设置文章来源:https://www.toymoban.com/news/detail-436167.html
Environment | Skybox Meterial:天空盒材质文章来源地址https://www.toymoban.com/news/detail-436167.html
到了这里,关于Unity入门基础语法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!