- 官网文档 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); }}