1、Event Function:事件函数
- Reset() :被附加脚本时、在游戏物体的组件上按Reset时会触发该事件函数
- Start() :在游戏初始化时会执行一次
- Update() :每一帧都会运行这个方法
- FixedUpdate(): 会在指定帧调用该方法多少次
- LateUpdate(): 晚于Update的运行顺序,但是FPS和Update是一样的
- Awake() Start() : 都是在游戏物体初始化运行一次,但是Awake的运行顺序高于Start的,并且只要脚本中存在Awake方法,则无论是否挂载了该脚本都会执行该方法
- OnEnable(): 当将物体的SetActive设置为true时就会自动调用调用该方法
- OnDestory(): 当关闭游戏则会调用该方法
2、Time时间类函数
- Time.time 表示从游戏开发到现在的时间,会随着游戏的暂停而停止计算。
- Time.timeSinceLevelLoad 表示从当前Scene开始到目前为止的时间,也会随着暂停操作而停止。
- Time.deltaTime 表示从上一帧到当前帧时间,以秒为单位。【一般用来控制角色、动画的运动】
- Time.fixedTime 表示以秒计游戏开始的时间,固定时间以定期间隔更新(相当于fixedDeltaTime)直到达到time属性。
- Time.fixedDeltaTime 表示以秒计间隔,在物理和其他固定帧率进行更新,在Edit->ProjectSettings->Time的Fixed Timestep可以自行设置。
- Time.SmoothDeltaTime 表示一个平稳的deltaTime,根据前 N帧的时间加权平均的值。
- Time.timeScale 时间缩放,默认值为1,若设置<1,表示时间减慢,若设置>1,表示时间加快,可以用来加速和减速游戏,回放等、非常有用。如果游戏中控制运动的都是使用了Time.deltatime的话,则可以通过设置Time.timeScale=0来暂停其运动等。
- Time.frameCount 总帧数
- Time.realtimeSinceStartup 表示自游戏开始后的总时间,即使暂停也会不断的增加。【一般用作性能测试】
- Time.captureFramerate 表示设置每秒的帧率,然后不考虑真实时间。
- Time.unscaledDeltaTime 以秒计算,完成最后一帧的时间 不考虑timescale时候与deltaTime相同,若timescale被设置,则无效。
- Time.unscaledTime 从游戏开始到现在所用的时间 不考虑timescale时候与time相同,若timescale被设置,则无效。
/// <summary>获取秒级别时间戳(10位)</summary>
public static long GetTimestampToSeconds()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds);
}
/// <summary>获取毫秒级别时间戳(13位)</summary>
public static long GetTimeStampToMilliseconds()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalMilliseconds);
}
3、GameObject类
3.1 创建游戏物体的三种方法
- 通过其构造器来创建 GameObject go=new GameObejct("游戏物体名"); //一般是用来创建空的游戏来存放其他东西的。
- Instantiate GameObject.Instantiate(prefab) //根据Prefab或者是另外一个游戏物体来创建(克隆Colon),可以实例粒子、等其他的游戏物体,很是常用的
- CreattePrimitive GameObject.CreatePrimitive(PrimitiveType.**) //创建原始的游戏物体,基本的几何体
- xxx.transform.SetParent(parent)配置父组件
3.2 为游戏物体添加组件
其中组件可以是我们自己自定义的脚本
GameObject.AddComponent<组件名>();
3.3 属性、变量
- GameObject.activeInHierarchy 游戏物体是否处于激活状态,与父类有关,父类被取消激活,则子类也是取消激活的
- GameObject.activeSelf 自身的激活状态,与父类无关,只与自身有关。【控制组件的激活与取消激活则使用.enable=false/true】
- GameObject.tag 游戏物体的tag标签,具体的由程序员自定义设置
- GameObject.SetActive(false/true) 通过参数的控制来设置其游戏物体的激活状态,true为激活状态,反之为取消激活状态。
3.4 UnityEngine.Object中的共有方法与变量
- name: 名字,调用该变量,则无论是通过GameObject还是Component都是返回游戏物体的名字 。gameObj.name
- GameObject.Find() 通过的名字来查找全场一个不是特定的物体,比较消耗性能,不找not active的东西。GameObject target = GameObject.Find("name");//name为所要查找事物的名字
- 如果想要查找隐藏的物体,使用 transform.Find(),只在这个物体的子物体下检索,不递归。
- Destroy() :删除游戏物体,但是不会立马在unity中删除,而是会先进行回收,等确定没对象使用的时候,在进行删除。GameObject.Destroy(gameObj);
- DontDestroyOnLoad() : 当加载新的场景的时候,不删除这个场景中的某个游戏物体。GameObject.DontDestroyOnLoad(gameObj);
- FindObjectOfType<>:通过类型查找 Image tImg = GameObject.FindObjectOfType<Image>();
- FindObjectsOfType<> : t通过类型来进行查找,是进行全局的查找,则就是在整个场景中进行查找。Image[] tImgs = GameObject.FindObjectsOfType<Image>();
- FindGameObjectWithTag :如果查到的是多个,则只返回查找到的第一个。GameObject tGameObj = GameObject.FindGameObjectWithTag("tag");
- FindGameObejctsWithTag 返回查找到的游戏物体集合。GameObject[] tGameObjs = GameObject.FindGameObjectsWithTag("tag");
-
返回gameObj所有的子物体:int tCount = gameObj.transform.childCount; for (int i = 0; i < tCount; i++) Transform tChildTrans = gameObj.transform.GetChild(i);
3.5 消息的发送
- BroadcastMessage() 广播发送消息,Calls the method named
methodName
on every MonoBehaviour in this game object or any of its children。在gameObj上的所有脚本,包括子物体的所有脚本,都执行FunctionName的函数。gameObj.BroadcastMessage("FunctionName","FunctionParam",SendMessageOptions.RequireReceiver); - SendMessage() 发送消息,只会对这个游戏物体中脚本上的方法发送消息。gameObj.SendMessage("FunctionName","FunctionParam",SendMessageOptions.RequireReceiver);
- SendMessageUpwards() 广播发送消息,调用自身的方法,并调用其父物体(gameObj.parent)的方法,并调用其父物体的父物体(gameObj.parent.parent)........所有的父物体。gameObj.SendMessageUpwards("FunctionName","FunctionParam",SendMessageOptions.RequireReceiver);
3.6 游戏组件的查找
- Cube cube = target.GetComponent<Cube>(); 返回一个对应的组件,如果有多个,则只返回第一个
- Cube[]cc= target.GetComponents<Cube>(); 返回该游戏物体上所有符合条件的组件,返回一个组件数组
- Cube[] xx = target.GetComponentsInChildren<Cube>(); 返回该游戏物体组件any of its children using
- Cube[] yy = target.GetComponentsInParent<Cube>(); 返回该游戏物体上的对应组件,同时返回该游戏物体的父物体上对应的组件,target.parent.parent.parent........
4.MonoBehaviours的类
4.1 继承的变量成员
- enabled: 返回该组件是否被激活或者是被禁用,可以通过该变量来进行设置。this.enabled
- isActiveAndEnabled: 只能返回该组件是否激活的标志位,不能设置该变量,为只读的。this.isActiveAndEnabled
- tag :该组件所对应的游戏物体的标签
- name :该组件所对应的游戏物体的名字
4.2 Invoke等方法、变量
- Invoke("方法",float time): 在等待time的时间后调用方法 Invoke("TempFunction",1f);
public void TempFunction()
{
Debug.Log("fdsafads");
}
- bool i= IsInvoking("方法1") 返回bool值,如果方法被添加到队列中,但没有被运行则返回true,如果经过一段时间后该方法被调用了则会返回false;
- InvokeRepeating("方法1",delayTime,repeatTime): 等待time时间后,会重复开始运行方法1,每number秒钟运行1次。 InvokeRepeating("TempFunction",10f,1f);
- CancelInvoke() 会暂停通过Involve/InvokeRepeating的运行,但是一般来说CancelInvoke会和InvokeRepeating组合调用。参数由自己设定
4.3 扩充
在脚本的类前添加[ExecuteInEditMode]:则该脚本不用按游戏运行按钮就会开始编译,只限在编辑模式里面。
在脚本的共有变量前添加[HideInInspector]则该共有变量不会在Inspector面板进行显示。
5.Coroutines:协程:
5.1 定义协程
IEnumerator 方法名()
StartCoroutine(TempFunction());
public IEnumerator TempFunction()
{
Debug.Log("fdsfdssf");
yield return new WaitForSeconds(5.0f); //等待一定时间在运行下面的代码
Debug.Log("222222");
}
5.2 开启与关闭协程
StartCoriutine(参数)、StopCoroutine(参数) 其中的参数要互相对应,如果传递的是方法名,则两个方法中的参数就要是方法名,如果是IEnumerator的返回值,则其中两个方法发的参数就要是IEnumerator的返回值 。
public IEnumerator TempFunction()
{
Debug.Log("fdsfdssf");
yield return new WaitForSeconds(5.0f); //等待一定时间在运行下面的代码
Debug.Log("222222");
}
或者
5.3 StopAllCoroutines() 停止所有的协程,不管你是怎么调用的
6.OnMousexx鼠标触发事件
如果是通过Collider进行触发检测的话,则要在设置中打开允许进行射线检测。
- OnMouseDown(): 当鼠标按下的时候触发,按一次触发一次 private void OnMouseDown(MouseDownEvent evt)
- OnMouseDrag(): 当鼠标按住不放的时候一直触发,是每一帧进行触发 void OnMouseDrag(MouseMoveEvent evt)
- OnMouseUp(): 当鼠标抬起的时候触发,只执行一次 private void OnMouseUp(MouseUpEvent evt)
- OnMouseEnter(): 当鼠标进入的时候触发,进入一次触发一次 public void OnMouseEnter()
- OnMousetOver(): 当鼠标在触发物体的上面时,则一直触发 void OnMouseOver()
- OnMouseExit(): 当鼠标移出的时候触发 public void OnMouseExit()
- OnMouseUpAsButton() 相当于是按钮的功能,当鼠标在同一个游戏物体上按下抬起的时候才会触发,按下与抬起不在同一个物体上的话则不会进行触发。
7.Mathf类:所有的成员均为静态的
- Mathf.Abs() 返回绝对值的
- Mathf.Ceil() 向上取整的,10.1--->11
- Mathf.Clamp(value,min,max) 如果value的值在min--max之间的话就返回value,但是如果value的值小于min,则返回min,如果value的值大于max,则返回max,一般是用在控制角色血量,当玩家的血量减少的时候,不会出现出现低于0和大于100的情况 hp= Mathf.Clamp(hp,0,100);
- Mathf.ClosePowerOfTwo(value): 取得离value的2次方最近的值
- Mathg.DeltaAngke: 取得两个角度之间的最小夹角
- Mathf.Floor 向下取整
- Mathf.Pow(i,j) 取得i的j次方
- Mathf.MoveToWards() 一般用来做移动控制,是匀速的运动,加速度固定的
- Mathf.Lerp() 差值运算,一般是用来控制动画、运动,越往后运行的越慢的。Mathf.Lerp(0.0f, 100.0f,0.5f) = 50.0f
- Mathf.PingPong(t,maxValue) 类似乒乓球的来回运动,起始 值是0,通过t变量来控制值由0向maxValue移动,当t大于maxValue的时候又向0进行移动,然后就这样的来回往复运动,一般t变量用时间Time.deltatime来进行控制的。
8.Input输入类
- GetKey() 按键一直按着时触发
if (Input.GetKey(KeyCode.Space)) { Debug.Log("Shooting a bullet while SpaceBar is held down");}
- GetKeyDown() 按键被按下那一刻进行触发
- GetKeyUp() 按键被按下后抬起时触发
- GetMouseButton(0/1/2) 1:左键 2:右键 3:中键 鼠标一直按着时触发 if(Input.GetMouseButton(0))
Debug.Log("Pressed left click."); - GetMouseButtonDown(0/1/2) 鼠标按下那一刻触发、
- GetMouseButtonUp(0/1/2) 鼠标抬起的那一刻时触发
- GetButtonDown()
- GetButton()
- GetButtonUp() 这三个的参数是用户自定义的虚拟按键进行触发,其他的和上面的一样
- GetAxis("虚拟轴名") 通过按下的虚拟轴来返回-1~1之间的值,开始值是0,然后向-1/1进行渐渐的变化,有一定的加速度。一般用来控制运动的,比如是赛车的加速运动等(GetAxis("Mouse X"),
GetAxis("Mouse Y"),
GetAxis("Mouse ScrollWheel"),
GetAxis("Vertical "),
GetAxis("Horizontal "),
1.Mouse X 鼠标沿着屏幕X移动时触发
2.Mouse Y 鼠标沿着屏幕Y移动时触发
3.Mouse ScrollWheel 当鼠标滚动轮滚动时触发
1.Vertical 对应键盘上面的上下箭头,当按下上或下箭头时触发
2.Horizontal 对应键盘上面的左右箭头,当按下左或右箭头时触发 - GetAxisRaw() 其他的和GetAxis差不多,就是少了渐变效果,返回值只有 0 1 -1三个
- anyKeyDown 当任何按键被按下(包括鼠标按键)时返回true
- anyKey 当任何按键被按着(包括鼠标)时返回true
- mousePosition 返回鼠标在屏幕上的像素坐标,【屏幕坐标】z轴衡为0的Vector2 screenpos = Input.mousePosition;
9.Vector3:三维变量
- Cross() 插乘运算【左手法则】,通过两个向量来获得另一个向量的方向,然后进行相关的判断 Vector3.Cross(Vector3,Vector3):float
- Project() 投影运算
- Reflect() 反射运算
- Slerp() 按照角度进行插值,与lerp的按照位置信息进行插值的,一般用在炮台的旋转,使旋转的更加平滑
- Vector3.Dot(Vector3,Vector3):float 点积
11.Random随机数类
- InitState(): 通过参数指定的种子,然后再调用Range()产生随机数的时候会依据种子来进行生成,则每一次运行所生成的随机数都是一样的,是伪随机数。一般要生成的随机数不同,可以设置参数为System.DataTime.Now.Ticks:通过时间戳来完成 Random.InitState(seek);
- insideUnitFCircle :在单位为1的园内随机生成一个位置信息,如果要在更大的圆中生成,则可以在后面*圆的半径信息。一般用来控制随机生成敌人的位置信息。Vector2 newPosition Vector2 = Random.insideUnitCircle * 5; transform.position.x = newPosition.x; transform.position.y = newPosition.y;
- insideUnitSphere: 在单位为1的球内随机生成一个位置信息,如果要在更大的球中生成,则可以在后面*圆的半径信息。transform.position = Random.insideUnitSphere * 5;
12.四元数 Quaternion:
欧拉角【eylarAngles】与面板中的值对应和四元数【rotation】之间是可以进行转换的,一般欧拉角是用来让用户可以直观的看到的,而四元数是用来控制内部的运算的。
- .eulerAngles 将四元数转变为欧拉角 transform.eulerAngles = new Vector3(10, yRotation, 0);
- Quaternion.Euler() 将欧拉角转变为四元数
Quaternion rotation = Quaternion.Euler(0, 30, 0);
- .LookRotation() 让玩家通过设置四元数来进行望向敌人的旋转,将向量方向转变为四元数 car.rotation = Quaternion.LookRotation(pos2 - pos1);
- Quaternion.Slerp() 做缓慢旋转 player.rotation = Quaternion.Slerp(player.rotation, target, Time.deltaTime); //插值的缓慢旋转
13.Rigidbody:刚体组件,控制角色的移动
- .position: 可以通过刚体来控制运动,在控制运动方面,使用rigibody.positon比transform.porition计算要快的多,相关的物理计算也是在刚体中计算好了,但是不建议使用这个方法来持续的控制物体的运动,不平滑,控制一两次的时候还可以使用MovePosition() 对position的优化,其中利用了插值运算,一般持续运动的则使用这个方法,不出现卡顿的现象.
Vector3 dir = new Vector3(h, 0, v); //刚体移动的特点:物体的位置+方向,太快就方向*一个小数,使之慢一点 mmRigidbody.MovePosition(mmTransform.position + dir * 0.2f);
- rotation:MoveRotation() 用来控制刚体的旋转的,一般不建议使用rotation,比较耗性能,建议使用MoveRotation(),然后配合Quaternion.slerp()进行使用,使其更加的平滑。
Quaternion deltaRotation = Quaternion.Euler(m_EulerAngleVelocity * Time.fixedDeltaTime); m_Rigidbody.MoveRotation(m_Rigidbody.rotation * deltaRotation);
- AddForce() 为刚体添加力,一般可以用在赛车游戏中,当进行短时的加速则可以给以限定时间的AddForce方法
14.Camera;相机组件
Camera.ScreenPointToRay()
当相机的标签是main cream时,可以通过Camer.main来进行主相机scream组件的查找射线,用来检测鼠标在屏幕上的位置信息,以及触碰到什么
Ray ray = cameraMain.ScreenPointToRay(Input.mousePosition); //获得相机到鼠标之间的射线
RaycastHit hit; //用来存放射线检测到的游戏物体的信息的
bool temp = Physics.Raycast(ray, out hit); //进行射线检测
15.Application
- /StreamingAssets: 该文件下的资源不会被压缩,导入是什么类型还是什么类型,【主要是音频、视频资源】
- dataPath: 工程文件路径
m_Path = Application.dataPath;
- Application.streamingAssetsPath(只读): 可以通过文件流来进行读取的文件路径
- Application.persistentDataPath(读写):可以实例的文件路径
- tempporaryCachePath :临时的文件路径
- Application.OpenURL("") 打开指定的网址
- Application.Quit() 退出游戏的运行
- .CapturScreenshot("游戏截图") 用来截图的,字符串为截图fileName
- Application.identifier 标识名
- .companyName 公司名
- productName 产品名
- instalMode 安装包名
- isEditor 是否在编辑器模式
- isFocused 是否在焦点
- isMoliePlatform 是否是移动平台
- isPlaying
- isWebPlayer
- platform 编辑器的平台
- unityVersion unity版本号
- version 项目文件版本号
- runInBackground 是否可以在后台运行
- UnityEditor.EditorApplication.isPlaying=false; //在编辑器模式下退出编辑状态
16.SceneManager场景类
- SceneManager.LoadScene() 加载下一个场景,一般是用在另一个场景不是太大的情况下
- SceneManager.LoadSceneAsync() 异步加载下一个场景,返回AsyncOperation类型,里面包含了加载的信息,加载的进度条等等。可以让用户缓解等待加载场景的时间。
public Slider _progress; void Awake() { _progress = GetComponent<Slider>(); } //使用协程 void Start() { StartCoroutine(LoadScene()); } IEnumerator LoadScene() { //用Slider 展示的数值 int disableProgress = 0; int toProgress = 0; //异步场景切换 AsyncOperation op = SceneManager.LoadSceneAsync("Line"); //不允许有场景切换功能 op.allowSceneActivation = false; //op.progress 只能获取到90%,最后10%获取不到,需要自己处理 while (op.progress < 0.9f) { //获取真实的加载进度 toProgress = (int)(op.progress * 100); while (disableProgress < toProgress) { ++disableProgress; _progress.value = disableProgress / 100.0f;//0.01开始 yield return new WaitForEndOfFrame(); } } //因为op.progress 只能获取到90%,所以后面的值不是实际的场景加载值了 toProgress = 100; while (disableProgress < toProgress) { ++disableProgress; _progress.value = disableProgress / 100.0f; yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; }
- sceneCount 获得当前加载的场景个数
- sceneCountInBuildSettings 在Build面板中加载的场景个数
- GetActiveScene() 获取已经加载的当前场景的信息
- GetSceneAt(index) 加载index索引的场景
- 当加载新的场景的时候会触发下面的事件:SceneManager.activeSceneChanged 当有新场景被加载的时候就会调用这个事件。SceneManager.sceneLoaded 当有新场景加载完成的时候就会触发这个事件。
// += 表示注册这个方法,一旦场景变更,就触发 SceneManager.activeSceneChanged += ChangedActiveScene; //以及 SceneManager.sceneLoaded += OnSceneLoaded; void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Debug.Log("OnSceneLoaded: " + scene.name); Debug.Log(mode); } private void ChangedActiveScene(Scene current, Scene next) { string currentName = current.name; if (currentName == null) { // Scene1 has been removed currentName = "Replaced"; } Debug.Log("Scenes: " + currentName + ", " + next.name); }
- 扩充:事件的注册时通过加方法来进行注册的:SceneManger.activeSceneChanged+=OnAcitiveScenenChanged;
17.射线检测
一般射线检测要在射线检测的范围内,并且被检测物体要有Collider
Ray ray=new Ray(起点,方向);
PaycastHit hit; //hit中存放的是射线检测的碰撞信息
bool temp=Physics.Raycast(ray,out hit); //具体的重载方法边用边查
Ray ray = new Ray(this.transform.position + transform.forward, transform.forward); //创建射线
RaycastHit hit; //存储射线检测到的游戏物体信息
if(Physics.Raycast(ray,out hit)) //通过返回值来判断射线是否检测到相关的物体了
{
Debug.Log(hit.collider.gameObject.name);
}
扩充:
Raycast;检测的是射线碰撞到的第一个物体,不具有穿透性 bool temp = Physics.Raycast(ray,out hit);
RaycastAll:返回的是RaycastHit数组,具有穿透性,可以返回检测到的多个游戏物体。bool temp = Physics.Raycast(ray,out hit);
Ray ray = new Ray();
RaycastHit[] hits = Physics.RaycastAll(ray);
18.代码监听触发事件
- <Button>().onClick.AddListener(方法名); //当触发button组件,则会触发指定的方法名的方法
private void Start() { btn3.GetComponent<Button>().onClick.AddListener(OnClickBtn3); } void OnClickBtn3() { Debug.Log("Click3"); }
通过实现接口来注册监听事件:
- using UnityEgine.EventSystems; 导入命名空间
- IPointerDownHandler 鼠标按下的事件接口,具体的接口参考手册
public class ScrollButton : MonoBehaviour, IPointerDownHandler,IPointerUpHandler, IPointerClickHandler { //实现了这三个接口,就得实现这三个方法 public void OnPointerDown(PointerEventData eventData) { isDown = true; } public void OnPointerUp(PointerEventData eventData) { isDown = false; } public void OnPointerClick(PointerEventData eventData) { if (Time.time - lastUpBtnTime <= DelayTime) { ChangeBarValueByBtn(ClickType.Once); } } }
- Raycast Target: 如果取消面板上这个选项的勾选则不做事件监听了,则无法实现按键检测了。
19.www类,下载
是用来在网络中下载资源的。
public string url = "http://img.taopic.com/uploads/allimg/120727/201995-120HG1030762.jpg";
IEnumerator Start()
{
WWW www = new WWW(url);
yield return www;
Renderer renderer = this.GetComponent<Renderer>();
renderer.material.mainTexture = www.texture;
}
20.Touches触摸事件
Input.touches: 返回放在屏幕上的手指信息,返回数组
Touch touch1=Input.touches[0];
touch1.position;
TouchPhase pahse = touch1.phase //phase 是用来返回手指的状态的
21.Debug.DrawRay(ray.oridin,ray.direction) 绘制射线
第一个参数是原点,第二个是方向
22.CharacterController角色控制器
- .SimpleMove(vector3) 简单移动
- .isGrounded 判断是否到地面上,bool值
- .Move() 与simpleMove()的区别是.Move()要*Time.deltatime、而且simpleMove会使用自带的重力
- OnControllerColliderHit(ControllerColliderHit hit) 当有碰撞到其他的碰撞器的时候会触发这个事件函数【hit保存碰撞到的物体信息】
void OnControllerColliderHit(ControllerColliderHit hit) { }
23.Mesh的设置
material mesh指定人是什么样子的,material指定人的肤色是什么样子的
24.API变更
弃用:Application.LoadLevel();
新的:SceneManager.LoadScene(); 加载新的场景
新的:Scene scene=SceneManager.GetActiveScene(); //获得当前活动场景的信息
SceneManger.LoadScene(scene.buildIndex) //重新加载当前场景
弃用:OnLevelWasLoaded() 当场景被加载的时候调用。
改成事件了:SceneManager.sceneLoaded
25.碰撞体检测体
触发检测:
private void OnTriggerEnter(Collider other)
{
speed = speed * -1;
}
碰撞检测:
void OnCollisionEnter(Collision collision)
{
//在脚本中添加这个函数,如果发生碰撞则执行此函数
}