共计 6581 个字符,预计需要花费 17 分钟才能阅读完成。
- 官网文档 unity.cn/ 中文文档
- 本地门路 Editor/Data/Documentation/en/Manual/index.html
-
设置脚本默认打开方式:Edit/Preferences/External Tools/ Exteral Script Editor
Helloworld
-
增加一个脚本
- 右键 Create/C# Script
- 文件名必须标准,文件名即类名 如 SimpleLogic
- 双击在 vs 中关上脚本,查看类名与文件名是否统一
-
在 vs 中编辑代码
- 增加一行打印输出
void Start(){Debug.Log("Hello World") }
- 其中 Debug 是 Unity API 中的一个工具类
- Ctrl+S 保留代码,敞开 vs
-
编译
- 保留会主动编译
-
挂载脚本
- 点 Add Component,选 Scripts/Simple Logic
- 或者,间接将脚本拖到 Inspector 窗口的最下方
-
运行游戏
- 点 play 按钮,运行
帧
- Frame 一个游戏帧
- FrameRate 帧率 | 刷新率
- FPS Frames Per Second 每秒更新多少帧
Update() 帧更 -
新此办法会被游戏引擎定时调用,以更新游戏的状态
帧更新
- Time.time 游戏工夫
- Time.deltaTime 间隔上次更新的时间差
- 显然,帧率是不固定的,Unity 会尽量较快地更新
Unity 不反对固定的帧率,但能够设定一个近似帧率
-
Application.targetFameRate=60
其中,批示 Unity 尽量以 FPS=60 的帧率更新游戏物体
根本属性
- this 以后脚本组件
- this.gameObject 以后物体
- this.gameObjecet.name 以后物体的名字
- this.gameObject.transform 以后物体下的 transform 组件
-
为了简化书写 也可写作 this.transform 成果雷同
GameObject obj = this.gameObject; string name = obj.name; Transform tr = obj.transform;
API 中的大部分类型,来自于 UnityEngine
using UnityEngine;
- 基类 MonoBehaviour
- 游戏物体 GameObject
- 变换组件 Transform
-
三维向量 Vector3
坐标
物体的坐标
- transform.position 世界坐标
-
transform.localPosition 本地坐标
个别用 localPosition 与 Inspector 窗口中的统一Vector3 pos = tr.position; Vector3 pos1 = tr.localPosition; tr.localPosition = new Vector3(1.2f, 1.2f, 1.2f);
挪动
float speed = 3; float distance=speed * Time.deltaTime; Vector3 pos=this.transform.localPosotion; pos.x+=distance; this.transform.localPosotion=pos;
相对运动
个别应用
trasform.Translate(dx,dy,dz,space)
实现相对运动
其中 dx,dy,dz 是坐标增量
- 例如
transform.Translate(0,0,distance)
Z 方向减少 distance
float speed = 3;
float distance=speed * Time.deltaTime;
this.transform.Translate(0,0,distance);
其 space:
- Space.World 绝对于世界坐标系
- Space.Self 绝对于本身坐标系(本地坐标系)
静止方向
-
获取指标物体(依据名字 | 门路来查找物体)
- GameObject flag=GameObject.Find(“ 红旗 ”)
-
转向指标(使物体的 z 轴指向物体)
- this.trnsform.LookAt(flag.transform);
-
向前静止,forward,+ z 方向(沿物体本身坐标系的轴向静止)
- this.transform.Translate(0,0,dz,Space.Self)
- 若指标在地面,则物体也向地面静止
-
向量测距
- p1= 火车.transform.position
- p2= 红旗.transform.position
- p=p1-p2
- distance=p.magnitude
play 时察看追随
旋转
给物体转一个旋转角度
-
Quanternion 四元组(x,y,z,w)
- transform.rotaion=… 不便操作,官网不倡议应用
-
欧拉角 Euler Angle
- transform.eulerAngles=new Vector3(0,45,0);
- transform.localEulerAngles=new Vector(0,45,0); 个别应用这个
float rotateSpeed=30;
Vector3 angles=this.transform.localEulerAngles;
angles.y+=rotateSpeed*Time.deltaTime;
this.transform.localEulerAngles=angles;
绝对旋转
Rotate() 旋转一个绝对的角度transform.Rotate(dx,dy,dz,space)
float rotateSpeed=30;
this.transform.Rotate(0,rotateSpeed*Time.deltaTime,0.Space.Self);
当父物体转动时,带动子物体一并旋转。
生命周期
常见的生命周期音讯函数
- Awake 初始化,仅仅执行一次
- Start 初始化,仅仅执行一次(script 被禁用则不触发)
- Update 帧更新,每帧调用一次
- OnEnable 每当组件启用时调用
- OnDisable 每当组件禁用时调用
-
脚本生命周期流程图
优先级
默认单个周期内物体没有优先级,都是 0
-
Awake
- script1.Awake(),scirpt2.Awake()
-
Start
- script1.Start(),scirpt2.Start()
-
Update
- script1.Update(),scirpt2.Update()
优先级设定:
- 选中一个物体,关上 Execution Order
- 点 +, 增加一个脚本
-
指定优先级,值越小,优先级越高
- 或者间接拖动调节程序
主控脚本
游戏的主控逻辑
增加 MainLogic.cs 到新建的空物体上,设置优先级
脚本参数
- 参数必须为 public, 才能够在查看器中显示
-
参数的名称,即变量名
- rotateSpeed->Roate Speed
-
参数的默认值 | 初始值,即变量的默认值
- 能够 Reset 菜单重置
-
参数的工具提醒,能够用 Tooltip()指定
[Tooltip("旋转角速度")]
脚本参数的赋值(以下按工夫程序)
-
定义默认值
- Public float rotateSpeed=30f
-
在查看器中赋值
- script.rotateSpeed=180f // 由 unity 框架对参数赋值
- 在 awake 中初始化
-
在 start 中初始化
值类型
参数的类型,分为值类型、援用类型
-
值类型(struct):如 Vector3,Color
- 自身是一个值,可间接复制
- 若为赋值,则默认 0
- 不能为 null
-
援用类型(class): 如 GameObject,Transform,MeshRenderer
- 节点 GameObject
- 组件 Transform,MeshRenderer,AudioSource
- 资源 Material, Texture, AudioClip
- 数组类型
其实在 c# 外面 int float 实质也是 struct 类型
String 原则上属于 class 类型参数的保留
- 在 Play Mode 下,组件 Copy Component
-
在 Edit Mode 下,组件 Pate Component Values
鼠标键盘输入
if(Input.GetMouseButtonDown(0)){// 点击鼠标左键} if(Input.GetKeyDown(KeyCode.W)){// 按 W 键} if(Input.GetKeyDown(KeyCode.Space)){// 按空格}
音乐播放
- Play On Wake
-
代码
-
获取 AudioSource 组件
AudioSource audio = this.GetComponent<AudioSource>();
-
播放
- audio.Play();
void PlayMusic(){AudioSource audio = this.GetComponent<AudioSource>(); if(audio.isPlaying){audio.Stop(); //audio.loop //audio.mute }else{audio.Play(); } }
-
-
组件参数
- AudioClip 音频资源
- Mute 是否静音
- Loop 是否循环播放
- Volume 音量
援用别的组件
-
第一种
public GameObject node;
AudioSource audio = node.getComponent<AudioSource>();
-
第二种
public AudioSource bgm
音讯调用
SendMessage 以‘音讯’的模式来调用另一个组件
// 找到指标节点 public GameObject target; // 向指标节点发送音讯 target.SendMessage(methodName,value);
SendMessage 外部执行(反射)
- 找到 target 下所有组件
-
在组件下寻找 methodName 函数
- 若存在,则调用
- 若无奈匹配,则报错获
取物体
-
按名称、门路获取(不举荐)
- GameObject flag=GameObject.Find(“ 旋翼 ”)
- 最好指定全门路 ” 无人机 / 旋翼 ”
-
援用获取
- 增加一个变量,在查看器援用指标
- public GameObject node;
父子物体
获取父
Transform parent=this.transform.parent;
-
获取父节点
GameObject parentNode=this.transform.parent.gameObject;
获取子
foreach(Transform child in transform{Debug.Log(chid.name); }
Transform child= this.transform.GetChild(0);
Transform chikld=this.transform.Find("aa"); Transform chikld=this.transform.Find("bb/cc"); Transform chikld=this.transform.Find("/dd");// 示意根下
设置父
- this.transform.SetParent(other)
设为一级节点 - this.transform.SetParent(null);
-
其中,parent 为 null 示意一级节点(没父)
显示暗藏
-
child.gameObject.SetActive(false)
资源应用
脚本中应用资源
- 增加变量 public AudioClip audioSuccess
- 援用音频资源
AudioSource audioSource=GetComponent<AudioSource>();
-
应用 audioSource.PlayOneShot(audioSuccess) 播放
资源数组
public AudioClip[] songs; songs.Length; Random.Range(min,max);// 用于在 [min,max) 中随机抽取一个数,不含 max
public class SimpleLogic:MonoBeHaviour{public Material[] colors; int m_index=0; void Start(){} void Update(){if(Input.GetMouseButtonDown(0)){ChangeColor(); } } private void ChangeColor(){ m_index+=1; if(m_index>=this.colros.Length){m_index=0;} Material selected = this.colors[m_index]; MeshRenderer rd=GetComponent<MeshRenderer>(); rd.material=selected; } }
定时调用
定时调用 Invoke*, 即定时器
继承自 MonoBehaviour:
- Invoke(func,delay)在 delay 之后执行,只调用一次
- InvokeRepeating(func,delay,interval)在 delay 之后执行,每 interval 执行一次
- IsInvoking(func)是否正在调度中
- CancelInvoke(func)勾销调用、从调度队列中移除
Unity 引擎外围是单线程的 -
获取以后线程号
using System.Threading; int threadId=Thread.CurrentThread.ManagedThreadId
向量
Vector3 (x,y,z)
- 单位向量: 长度为 1
-
标准化 Normalize: 缩放一个向量,使其长度为 1
Vector3 v1=new Vector3(2,2,0); Vector3 v2=v1.normalized; Debug.log(v2.ToString("f3"));
几个常量
- Vector3.zero (0,0,0)
- Vector3.up (0,1,0)
- Vector3.right (1,0,0)
- Vector3.forward (0,0,1)
向量运算: - 加法 a+b
- 减法 a-b
- 标量乘法 b=a*2
- 点积 c=Vector3.Dot(a,b)
- 差积 c=Vector3.Cross(a,b)
-
不能设 null, 默认是(0,0,0)
向量测距:Vector3.Distance(a,b) 轴心点间隔Vector3 p1=this.transform.position; Vector3 p2=target.transform.position; Vector3 direction=p2-p1; float distance=direction.magnitude
预制体
Prefab, 事后制作好的物体,能够进步开发效率
创立
- 先制作好一个样本节点
- 做好后间接拖到 Assets 窗口,则主动生成一个 prefab 资源
-
原始物体不再须要,可删
导出
实例
Prefab Instance 和原始 Prefab 之间存在关联
特色: - 在层级窗口中,节点图标不同
- 在层级窗口中,右键菜单 /Prefab
- 在查看窗口中,上下文工具 /Prefab
解除关联: -
在层级窗口中,右键菜单 Prefab/Unpack
编辑
prefab 相当于一个模板,能够再次编辑
独自编辑:
- 双击 Prefab 进入独自编辑模式
- 编辑节点和组件
- 退出,实现编辑
原位编辑 - 抉择 Prefab Instance
- 在查看器中 Open
-
Content 显示 Normal/Gray/Hidden
- 此时,仅选中的物体被编辑,其余物体是陪衬
- 编辑节点
-
退出,实现编辑
动态创建实例
Object.Instantiate(original,parent)
演示: - 筹备 prefab,增加脚本
- 增加变量 public GameObject bulletPrefab;
-
克隆实例
GameObject node= Instantiate(bulletPrefab,null); node.transform.position = Vector3.zero; node.transform.localEulerAngles = Vector3.zero;
初始化
创立 Prefab Instance 之后,应做初始化:
- Parent 父节点
- position/localPosition 地位
- eulerAngles/localEulerAngles 旋转
-
Script 自带的管制脚本
销毁
object.Destroy(obj)用于销毁一个实例
对于子弹来说
- 当飞出屏幕时,销毁
- 按射程 / 航行工夫
-
当击中目标时,销毁
碰撞检测
private void OnTriggerEnter(Collider other){if(other.name.StartsWith("xxx"){Destory(this.gameObject);
Destory(other.gameObject);
}
}