Unity API常用方法记录

前言:

跟着siki学院的这个课——Unity API常用方法和类详细讲解

来学习Unity脚本,我把一些自己比较陌生的做了记录

 

 

 

 

 


帮助文档

我们可以在Unity上边菜单栏的Help找到Unity Manual ,点击打开,这就跳转到了一个网页,这个就是Unity官方的用户手册网页

同一网站上的Scripting API,就是API文档

在我们学习Unity的过程中,这两个文档会有很大的帮助。

 

 


常见类的方法或属性记录(一)

 

事件方法

我们可以在https://docs.unity3d.com/Manual/ExecutionOrder.html这个网页找到Unity中的事件方法

它的那张长图非常棒,有很多解释(虽然是英文)。

比如 Reset这个方法,它是只在编辑器模式下会被调用(即发布之后不会调用),我们在编辑器模式下,点击一个组件右边齿轮的reset,其实就是调用了这个reset方法,它把组件的属性还原了。

 

Time类

https://docs.unity3d.com/ScriptReference/Time.html

Time类,有很多静态变量

其中比较重要的就是deltatime,即每一帧运行的时间

realtimeSinceStartup 从游戏开始到现在的总时间

time 从程序开始执行到现在的时间

smoothDeltaTime 更加平滑均匀的deltatime

fixedTime  表示FixedUpdate已经执行的时间

FixedUpdate:

固定更新方法,和物理相关的操作代码,都要写在此方法中。

固定更新的时间是0.02s,1秒执行50次,可在Edit—>Project Settings—>Time面板中的Fixed Timestep查看。

timeScale 可以控制时间(为n,则时间是n倍)

设置 Time.timeScale 为 0 将会暂停所有和帧率无关的事情。这些主要是指所有的物理事件和依赖时间的函数、刚体力和速度等,而且 FixedUpdate 会被暂停(不是Update),因为FixedUpdate函数是根据时间来进行更新的。

但是,Update 函数本身的执行是不会受 Time.timeScale 的影响的。Update 是依赖你的机器的,它的调用次数和你的机器渲染一样快慢(一些特殊情况除外);性能高的机器,帧率高,Update 函数执行次数也就多。因此,当使用 Time.timeScale = 0 时,游戏看起来是被冻结了,这是因为所有和时间有关的事情都被暂停了。但是,我们的游戏仍在渲染,也就是说 Update 函数仍在执行。无论 Time.timeScale 等于多少,Update 和 LateUpdate 都会去执行。所有的动画都是基于时间来的,因为Time.timeScale = 0了,所以 Time.time 也就不会在变化了。当 Time.timeScale 为 0 时,Time.deltaTime 将为 0。这意味着,如果你使用 Time.deltaTime 来控制旋转和位移等,那Time.timeScale = 0 也将使这些物体停止运动。

Time.timeScale 还会影响 Time.time 的时间,比如 Time.timeScale = 2 的话,那么 Time.time 的增长速度也会变成 2 倍速度。如果你想取到游戏的实际时间,那么使用Time.timeSinceLevelLoad 就可以,前提是必须在 Awake() 方法以后再取,如果在 Awake() 方法里面取 Time.realtimeSinceStartup 会取出一个错误的值,在 Start 方法里面取的话就正常了。如果游戏暂停以后想在暂停界面上继续播放一些不受 Time.timeScale 影响的动画,那么我们就需要用到 Time.realtimeSinceStartup。

update不受时间冻结影响,例如如下的代码:

    void Start()
    {
        Time.timeScale=0;
    }

    private void FixedUpdate()
    {
        transform.position = new Vector3(transform.position.x+0.01f,
            transform.position.y,
            transform.position.z);
    }

    void Update()
    {
        transform.position = new Vector3(transform.position.x,
                transform.position.y + 0.01f,
                transform.position.z);
    }

物体会往y坐标走

 

GameObject 游戏物体

activeSelf   自身是否是被激活状态

activeInHierarchy 物体在场景中是否被显示(即若这个值为true,则物体以及父物体都是被激活的)

hierarchy:统治集团、层次体系

BroadcastMessage 向GameObject与它的子物体发送消息

SendMessageUpwards 向GameObject与它的子物体发送消息

SendMessage 向GameObject发送消息

这三个发送消息的方法的参数都是别的方法名,当有游戏物体接收到消息,他们就会看自己有没有叫这个方法名的方法,若有,则会调用自身的这个方法

 

 

 

 

 

构造方法

Instantiate 实例化一个对象

CreatePrimitive 创建一个带有基本网格渲染器和相应碰撞器的游戏物体。

//在场景中创建一个平面,球体
GameObject.CreatePrimitive(PrimitiveType.Plane);
GameObject.CreatePrimitive(PrimitiveType.Cube);

 

 

Mathf

Deg2Rad   把角度换成弧度的变量,等价 (PI * 2)/360 。

Infinity 无穷大

Clamp 限制一个值在两个数之间

ClosestPowerOfTwo 返回距离value最近的2的次方数。

Lerp  按照数字t在from到to之间插值。

t是夹在 [0……1]之间,当t = 0时,返回from,当t = 1时,返回to。当t = 0.5 返回from和to的平均数。
注意第三个参数t,不要理解为t时间内从from到to,平时比如移动位移的时候或做旋转的时候,可以把t作为时间单位,但是一定要注意这个t的值是从0到1范围。
搭配好协程就可以有平滑移动的效果
    IEnumerator CameraMove(Vector3 po, Vector3 qua)
    {
        yield return new WaitForSeconds(0.5f);
        Vector3 TargetPosition = po;
        Quaternion TargetRotation = Quaternion.Euler(qua);
        while (MainCamera.transform.position != TargetPosition && Quaternion.Angle(MainCamera.transform.rotation, TargetRotation) >= 1)
        {
            //基于浮点数t返回a到b之间的插值,t限制在0~1之间。当t = 0返回from,当t = 1 返回to。当t = 0.5 返回from和to的平均值。
            MainCamera.transform.position = new Vector3(Mathf.Lerp(MainCamera.transform.position.x, po.x + 0.1f, Time.deltaTime),
                                                    Mathf.Lerp(MainCamera.transform.position.y, po.y + 0.1f, Time.deltaTime),
                                                    Mathf.Lerp(MainCamera.transform.position.z, po.z + 0.1f, Time.deltaTime));
            MainCamera.transform.rotation = Quaternion.Slerp(MainCamera.transform.rotation, TargetRotation, Time.deltaTime);
            yield return 0;
        }
    }

 

LerpAngle 角度的插值,和 lerp 道理一样

MoveTowards 向方向移动

作用是将当前值current移向目标target。(对Vector3是沿两点间直线)
maxDistanceDelta就是每次移动的最大长度。
返回值是当current值加上maxDistanceDelta的值,如果这个值超过了target,返回的就是target的值。

PingPong  乒乓效果,循环往复

Round  四舍五入

SmoothDamp   平滑阻尼

static function SmoothDamp (current : Vector3target : Vector3ref currentVelocity : Vector3smoothTime : float, maxSpeed : float = Mathf.InfinitydeltaTime : float = Time.deltaTime)

各参数含义:

1.current 当前物体位置

2.target 目标物体位置

3.ref currentVelocity 当前速度,这个值由你每次调用这个函数时被修改(注:ref 关键字指参数按引用传递, 按引用传递的效果是,对所调用方法中参数进行的任何更改都反映在调用方法中。)

4.smoothTime 到达目标的时间,较小的值将快速到达目标

5.maxSpeed 所允许的最大速度,默认无穷大

6.deltaTime 自上次调用这个函数的时间,默认为Time.deltaTime

 

Input

GetKey 按下键返回true

GetKeyDown  当用户按下指定名称的按键时的那一帧返回true

GetKeyUp  在用户释放给定名字的按键的那一帧返回true

GetAxis 参数为Horizontal 则按下左右箭头分别返回-1、1,不按则返回0;Vertical对应上下箭头

 

Random

Range 返回一个在最大最小之间的随机数(包括最大最小)

 

 

Camera

main 静态属性,第一个标签是MainCamera的物体

ScreenToWorldPoint:从屏幕空间到世界空间的变化位置。屏幕空间以像素定义。屏幕的左下为(0,0);右上是(pixelWidth,pixelHeight),Z的位置是以世界单位衡量的到相机的距离。

WorldToScreenPoint:从世界空间到屏幕空间变换位置。屏幕空间以像素定义,屏幕左下为(0,0),右上是(pixelWidth,pixelHeight),Z的位置是以世界单位衡量的到相机的距离。

 

 

Application

dataPath 数据路径(比如我windows下:F:/Unity3D/test/Assets)

CaptureScreenshot  截图

更多Application的路径变量

 

 

SceneManager

LoadScene 加载场景通过Build Settings里的名字或者变量

LoadSceneAsync 异步加载场景(一般大场景会用到)

sync:同步

async:异步

1、AsyncOperation 在你不主动设置AllowSceneActivation = false的情况下,isDown会随着progress的增长(从0增长到1)自动变成true,所以会自动跳转场景;

2、如果你不想让场景进行自动跳转,你就需要在异步加载时设置allowSceneActivation = false,这会使场景不进行自动跳转,原因是isDown在allowSceneActivation = false 的情况下 永远不会为true,并且此时的aysncOperation.progress也最多可以加载到0.9(90%),当你允许你的场景跳转时(设置allowSceneActivation = true),progress加载最后的10%,直到progress = 1, isDown此时自动变为true,异步加载完成,实现场景跳转。

跟多可以看这里——异步跳转场景

另外在编辑器中进度条不会显示中间过程,这是因为 编辑器下只能同步加载,虽然调用的异步的接口,所以进度条会从0到100

 

 

Vector2

vactor是一个结构体,不是一个类

官网参考

down 下的意思,对应坐标(0,-1)

其他上、右、左都是一样的道理

magnitude 向量长度

normalized 单位向量(方向不变,长度变成1)

x x坐标

我们知道在transform.position.x中,不能对x属性直接复制,position是一个Vector2类型的属性,Vctor2是一个结构体,所以position是一个结构体,结构体是一个值类型,值类型在方法传递的时只传递值的副本

Normalize  自身单位化,将自身变成单位向量

 


常见API以及Unity技巧补充

监听UGUI的事件

  • 直接给按钮等UGUI控件拖拽添加注册响应方法即可
  • 通过代码实现UGUI控件的事件监听

通过给button组件添加监听器来实现点击组件会触发方法,示例代码如下:

    private void Start()
    {
        button.GetComponent<Button>().onClick.AddListener(this.buttonOnClick);            
    }

    void buttonOnClick() {
        print("Button on click!");
    }
  • 通过实现接口

实现接口这个方法不像前两种方法那么自由了,官方文档奉上

这些就是我们可以实现的接口,每一个接口都对应了一个事件

上图的pointer代表鼠标指针

示例。我们给一个UI图片添加了一个脚本文件,内容如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventManager : MonoBehaviour, IPointerDownHandler
{
    public void OnPointerDown(PointerEventData eventData)
    {
        print("IPointerDown");
    }
}

然后在Scene中点击这个UI图片,就出现了命令行提示

另外注意,一定要保证UI身上的Raycast Target 是勾选上的。

 

实现UI拖拽

还是上面的那个官方网页,那些接口中有一些比较牛逼的东西,就是Drag接口,可以实现UI的拖拽

下面给出UI拖拽的示例代码:

public class Scence2Task2DragControl : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{
    private RectTransform rectTransform;
    private void Start()
    {
        rectTransform = GetComponent<RectTransform>();
    }
    public void OnBeginDrag(UnityEngine.EventSystems.PointerEventData eventData)
    {
        print("开始拖拽" + GetComponent<Text>().text);
    }
    public void OnDrag(UnityEngine.EventSystems.PointerEventData eventData)
    {
        Vector3 pos;
        //鼠标屏幕位置转换世界位置
        RectTransformUtility.ScreenPointToWorldPointInRectangle(
            rectTransform, eventData.position,
            eventData.enterEventCamera, out pos);
        rectTransform.position = pos;

        print(eventData.pointerPressRaycast.gameObject.name);
    }
    public void OnEndDrag(UnityEngine.EventSystems.PointerEventData eventData)
    {
        print("结束拖拽" + GetComponent<Text>().text);
    }
}

如果你要检测拖拽指针位置是否在某UI上,建议使用如下代码,IPointerEnterHandler 亲测不好用……

//鼠标在某rect范围内
if (RectTransformUtility.RectangleContainsScreenPoint(_transform, Input.mousePosition))

 

 

 

UnityWebRequest

这个类是代替以前的WWW类,可以访问网络资源(Unity爬虫?)

官方文档奉上

下面有一个爬取图片的示例

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using UnityEngine.UI;

public class UIEventManager : MonoBehaviour {

    public Image image;

    void Start() {
        StartCoroutine(GetText());
    }
    IEnumerator GetText() {
        using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture("https://马赛克.com/gp=0.jpg")) {
            yield return uwr.SendWebRequest();
            if (uwr.isNetworkError || uwr.isHttpError) {
                Debug.Log(uwr.error);
            } else {
                // Get downloaded asset bundle 
                image.material.mainTexture = DownloadHandlerTexture.GetContent(uwr);
            }
        }
    }
}

更多使用请参考Unity2019对于弃用WWW加载方式后的新替代的API的UnityWebRequest的使用

触摸事件

这些事件主要值针对于移动端

通过touch对象来操纵,这个我们以后学安卓再深究

官方文档奉上

 

 

 


 

这些先记录这么多吧,后续会不断更新

 

 

商业转载 请联系作者获得授权,非商业转载 请标明出处,谢谢

 

13 thoughts on “Unity API常用方法记录

  • 头像
    2020年3月31日 at 下午11:42
    Permalink

    Just desire to say your article is as astounding. The clarity in your post is simply excellent and i could assume you are an expert on this subject. Well with your permission allow me to grab your feed to keep up to date with forthcoming post. Thanks a million and please keep up the rewarding work.|

  • 头像
    2020年4月1日 at 下午1:16
    Permalink

    I’m really loving the theme/design of your blog. Do you ever run into any browser compatibility issues? A small number of my blog audience have complained about my site not operating correctly in Explorer but looks great in Safari. Do you have any solutions to help fix this problem?|

    • 头像
      2020年4月1日 at 下午4:18
      Permalink

      I’m sorry I can’t help you, because I’m not an expert in website construction, I just use the built-in theme of WordPress. Thank you for your praise and good luck!

  • 头像
    2020年4月3日 at 下午12:20
    Permalink

    Hi friends, how is everything, and what you want to say about this post, in my view its genuinely remarkable in support of me.|

  • 头像
    2020年4月5日 at 上午5:34
    Permalink

    Fantastic goods from you, man. I have understand your stuff previous to and you are just extremely fantastic. I actually like what you’ve acquired here, certainly like what you are stating and the way in which you say it. You make it entertaining and you still take care of to keep it wise. I can not wait to read much more from you. This is actually a terrific site.|

  • 头像
    2020年4月7日 at 下午7:38
    Permalink

    I’d like to thank you for the efforts you have put in penning this site. I am hoping to check out the same high-grade blog posts by you later on as well. In fact, your creative writing abilities has inspired me to get my very own blog now ;)|

  • 头像
    2020年4月8日 at 下午12:00
    Permalink

    I read this piece of writing fully regarding the difference of latest and earlier technologies, it’s remarkable article.|

  • 头像
    2020年4月10日 at 下午12:13
    Permalink

    I quite like reading through a post that will make men and women think. Also, many thanks for allowing me to comment!|

发表评论