【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)

目录

      • Time时间体系
        • timeScale
        • maximumDeltaTime
        • fixedDeltaTime
        • captureDeltaTime
        • deltaTime
        • 整体展示
      • Random随机数
      • Mathf数学运算I
        • Mathf.Round()
        • Mathf.Ceil() Mathf.CeilToInt()
        • Mathf.Sign
        • Mathf.Clamp
      • Mathf数学运算II-曲线变换
        • Lerp 线性插值
        • LerpAngle
        • SmoothDamp
          • 疑问:
        • SmoothStep
        • MoveTowards()
        • MoveTowardsAngle()
        • 波形比较
        • 其他曲线

参考视频:B站Unity3D视频精讲课程

Time时间体系

(红色旗帜:只读静态变量,绿色:可修改静态变量)
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第1张图片

官网手册 important class-Time


通过edit>project settings>time可修改的参数:
fixedDeltaTime、maximumDeltaTime、timeScale

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第2张图片

timeScale

timeScale:The scale at which time passes.
可修改面板参数Time Scale:The speed at which time progresses . Change this value to simulate bullet-time effects . A value of 1 means real-time . A value of .5 means half speed;a value of 2 is double speed.
可模拟子弹时间,跳跃时慢动作

maximumDeltaTime

maximumDeltaTime:The maximum value of Time.deltaTime in any given frame. This is a time in seconds that limits the increase of Time.time between two frames.

可通过面板修改Maximum Allowed Timestep:A framerate-independent interval that caps the worst-case scenario when framerate is low.Physics calculations and Fixedupdate() eventswill not be performed for longer time than specified. 一种与帧速率无关的间隔,当帧速率较低时,它会限制最坏的情况。物理计算和Fixedupdate() 事件的执行时间不会超过指定时间。

fixedDeltaTime

fixedDeltaTime :执行物理和其他固定帧率更新(如 MonoBehaviour 的 FixedUpdate)的时间间隔(以秒为单位)。

可通过面板修改Fixed Timestep值进行修改。Fixed Timestep:A framerate-independent interval that dictates when physics calculations and Fixedupdate() events are performed
一个与帧速率无关的间隔,用于指定何时执行物理计算和Fixedupdate()事件

修改这个值的直观感受:对帧率产生影响
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第3张图片
好吧,也不知道为啥有这么大区别…(注意拉成1其实跟10帧率差不多)

captureDeltaTime

captureDeltaTime:Slows your application’s playback time to allow Unity to save screenshots in between frames.
减缓应用程序的播放时间,使Unity可以在两帧之间保存屏幕截图。

如果此属性具有非零值,则无论实时时间和帧的持续时间如何,Time.Time都会以captureDeltaTime(按Time.timeScale缩放)的间隔增加。如果你想拍摄一部需要恒定帧速率的电影,并且想在两帧之间留出足够的时间来保存屏幕图像,这一点很有用。

【好吧,没听懂,以后再说吧】


下面是只读变量

deltaTime

乘以deltaTime可以达到平滑的效果
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第4张图片

整体展示

    public int framerate;
    // Start is called before the first frame update
    void Start()
    {
        framerate = Time.captureFramerate;
    }

    // Update is called once per frame
    void Update()
    {
        Time.captureFramerate = framerate;
        if(Input.GetKeyDown(KeyCode.Space)){
            Time.timeScale = 0.2f;
            Time.fixedDeltaTime = 0.005f;
        }
        if(Input.GetKeyUp(KeyCode.Space)){
            Time.timeScale = 1f;
            Time.fixedDeltaTime = 0.02f;
        }
    }
    private void OnGUI() {
        GUILayout.TextArea("Game Time:" + Time.time.ToString());
        GUILayout.TextArea("Game timeSinceLevelLoad:" + Time.timeSinceLevelLoad.ToString());
        GUILayout.TextArea("deltaTime:" + Time.deltaTime.ToString());
        GUILayout.TextArea("fixedTime:" + Time.fixedTime.ToString());
        GUILayout.TextArea("smoothDeltaTime:" + Time.smoothDeltaTime.ToString());
        GUILayout.TextArea("frameCount:" + Time.frameCount.ToString());
        GUILayout.TextArea("realtimeSinceStartup:" + Time.realtimeSinceStartup.ToString());
        GUILayout.TextArea("unscaledDeltaTime:" + Time.unscaledDeltaTime.ToString());
        GUILayout.TextArea("unscaledTime:" + Time.unscaledTime.ToString());
    }

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第5张图片
按空格和松开空格实现的效果如下:
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第6张图片
【哇!顺便学习了输入和GUI,哈哈哈哈我好厉害~】

Random随机数

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第7张图片

Mathf数学运算I

官方API

Mathf.Round()

整数部分为偶数小数为5也舍,整数部分为奇数,小数为5则进。注意unity的不同之处

        Debug.Log("Mathf.Round(10.5f)=" + Mathf.Round(10.5f));//10
        Debug.Log("Mathf.Round(11.5f)=" + Mathf.Round(11.5f));//12
        Debug.Log("Mathf.Round(-10.5f)=" + Mathf.Round(-10.5f));//-10
        Debug.Log("Mathf.Round(-11.5f)=" + Mathf.Round(-11.5f));//-12

Mathf.Ceil() Mathf.CeilToInt()

注意两个打印结果相同,但返回类型不同,其他ToInt方法也类似。

// float Ceil(float f);
Debug.Log(Mathf.Ceil(10.5f));// 11
// int CeilToInt(float f)
Debug.Log(Mathf.CeilToInt(10.5f));// 11

Mathf.Sign

public static float Sign (float f);
返回 f 的符号。
当 f 为正数或零时,返回值为 1,当 f 为负数时,返回值为 -1。

Debug.Log(Mathf.Sign(-10));//-1
Debug.Log(Mathf.Sign(10));//1

Mathf.Clamp

public static float Clamp (float value, float min, float max);
The float result between the minimum and maximum values.
限位函数,value在最大最小值之间,返回原value,否则取最大或者最小值。Note: if the minimum value is is greater than the maximum value, the method returns the minimum value.

Mathf数学运算II-曲线变换

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第8张图片

他们都有一个相似的功能:给定一个初始点,一个target终点,要我们输出的函数从起始点到target点移动,只不过他们实现方法是不同的,效果也有很大的不一样。在我们以后的项目中,利用好这些函数会非常方便且自由地控制例如物体的位移、旋转等。

Lerp 线性插值

public static float Lerp (float a, float b, float t);
在 a 与 b 之间按 t 进行线性插值。参数 t 限制在范围 [0, 1] 内。

当 t = 0 时,返回 a 。
当 t = 1 时,返回 b 。
当 t = 0.5 时,返回 a 和 b 的中点。

    public float minX = 0f;
    public float maxX = 20f;
    float startTime = 2f;
    void Start()
    {
    	// t不在[0,1]范围会被clamp限位
        Debug.Log("Mathf.Lerp(0,5,200)="+Mathf.Lerp(0,5,-1));//0
        Debug.Log("Mathf.Lerp(0,5,200)="+Mathf.Lerp(0,5,200));//5
    }

    // Update is called once per frame
    void Update()
    {
        // 从第2秒开始沿x方向从0匀速移动到5,速度为(maxX-minX)/1
        transform.position = new Vector3(
            Mathf.Lerp(minX,maxX,Time.time-startTime),
            transform.position.y,
             transform.position.z
        );
    }

LerpAngle

public static float LerpAngle (float a, float b, float t);
与 Lerp 相同,但是在值环绕 360 度时确保值正确插入。
参数 t 限制在范围 [0, 1] 内。假设变量 a 和 b 以度为单位。

    public float start = 0f;
    public float end = 90f;
    float startTime = 2f;
    void Update()
    {
        float currentAngle = Mathf.Lerp(start,end,Time.time-startTime);
        transform.eulerAngles = new Vector3(
            transform.eulerAngles.x,
            currentAngle,
            transform.eulerAngles.z
        );
    }

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第9张图片


lerp插值可以也通过类似current = Mathf.Lerp(current,end,Time.deltaTime) 方法刷新初始值,实现非线性运动

public float current = 0f;
    public float end = 5f;
    float startTime = 2f;

    // Update is called once per frame
    void Update()
    {
        if(end - current <0.01f)
            current = end;
        else
            current = Mathf.Lerp(current,end,Time.deltaTime);
        // 从第2秒开始沿x方向从0匀速移动到5,速度为(maxX-minX)/1
        transform.position = new Vector3(
            current,
            transform.position.y,
             transform.position.z
        );
    }

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第10张图片
但可以明显看出移动很不平滑,且代码不简洁,接下来将介绍两个函数能方便实现非线性平滑变换

SmoothDamp

public static float SmoothDamp (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed= Mathf.Infinity, float deltaTime= Time.deltaTime);

  • current 当前位置。(下面代码用transform.position.x,注意和lerp smoothStep区别)
  • currentVelocity 当前速度,此值由函数在每次调用时进行修改。(这个值初始值为0即可,不需要管)
  • smoothTime 达到目标所需的近似时间。值越小,达到目标的速度越快。
    public float target = 5f;
    float velocity = 0f;
    public float maxSpeed;

    // Update is called once per frame
    void Update()
    {
        transform.position = new Vector3(
            Mathf.SmoothDamp(transform.position.x,target,ref velocity,5f,maxSpeed),
            transform.position.y,
            transform.position.z);
    }

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第11张图片

疑问:
  • smoothTime 非常不准确
    参考:Mathf.SmoothDamp takes longer than it should inside a coroutine

SmoothStep

public static float SmoothStep (float from, float to, float t);

在 min 与 max 之间进行插值,在限制处进行平滑。

此函数采用与 Lerp 相似的方式在 min 与 max 之间进行插值。 但是,插值会从起点逐渐加速,然后朝着终点减慢。 这可用于创建表现十分自然的动画、淡化和其他过渡。

    public float target = 5f;
    float velocity = 0f;
    public float maxSpeed;

    // Update is called once per frame
    void Update()
    {
        transform.position = new Vector3(
            Mathf.SmoothStep(0,target,Time.time/5),
            transform.position.y,
            transform.position.z);
    }

三者比较
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第12张图片

MoveTowards()

public static float MoveTowards (float current, float target, float maxDelta);
将值 current 向 target 靠近。

这本质上与 Mathf.Lerp 相同,但是该函数确保速度不超过 maxDelta。 maxDelta 为负值时将值推离 /target/。

public float target = 5f;
    float speed = 1f;

    // Update is called once per frame
    void Update()
    {
        transform.position = new Vector3(
            Mathf.MoveTowards(transform.position.x,target,Time.deltaTime*speed),
            transform.position.y,
            transform.position.z);
    }

MoveTowardsAngle()

与 MoveTowards 相同,但是在值环绕 360 度时确保值正确插入。

波形比较

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第13张图片
lerp是定义好时间,moveTowards是定义好速度

脚本中加入变量public AnimationCurve a;即可调出曲线

其他曲线

InverseLerp:Determines where a value lies between two points.


Repeat 对值 t 进行循环,使它不会大于长度,并且不会小于 0。(AnimationCurve 中就是Loop)
public static float Repeat (float t, float length);

这类似于取模运算符,但是它适用于浮点数。例如,将 3.0 用于 t 并将 2.5 用于 length,结果是 0.5。而当 t = 5 并且 length = 2.5 时,结果是 0.0。但是请注意,与取模运算符一样,没有为负数定义行为。


PingPong PingPong 返回一个值,该值将在值 0 与 length 之间递增和递减。

【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第14张图片
要想实现往复运动,比如对前面的Time.time取repeat 或者pingpong就能实现往复运动
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第15张图片

transform.position = new Vector3(
            Mathf.Lerp(minX,maxX,Mathf.PingPong(Time.time,1)),
            transform.position.y,
             transform.position.z
        );

LinearToGammaSpace 将给定值从线性转换为伽马 (sRGB) 颜色空间。
GammaToLinearSpace 将给定值从伽马 (sRGB) 转换为线性颜色空间。
大概意思就是伽马图视觉效果比线性的好,但不好计算,所以一般转换成linear计算完在转回gamma值。
官方手册
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第16张图片


PerlinNoise 生成 2D 柏林噪声。
柏林噪声是在 2D 平面上生成的浮点值的伪随机图案(虽然 该方法普及到三维或更高维,不过未在 Unity 中实现)。 该噪声不包含每个点处的完全随机值,而是由 “波”组成,其值在图案中逐渐增大和减小。该噪声可以 用作纹理特效的基础,以及用于动画、生成地形高度贴图 和许多其他内容。
【学习笔记】unity脚本学习(二)(Time时间体系、Random随机数、Mathf数学运算)_第17张图片
作用:

  • 随机颜色过渡

啊,终于将这小节搞完了…又花了好几天

你可能感兴趣的:(unity,unity,学习)