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

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

【学习笔记】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数学运算)

官网手册 important class-Time


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

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

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数学运算)
好吧,也不知道为啥有这么大区别…(注意拉成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可以达到平滑的效果
在这里插入图片描述

整体展示

    public int framerate;// Start is called before the first frame updatevoid Start(){framerate = Time.captureFramerate;}// Update is called once per framevoid 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数学运算)
按空格和松开空格实现的效果如下:
在这里插入图片描述
【哇!顺便学习了输入和GUI,哈哈哈哈我好厉害~】

Random随机数

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

Mathf数学运算I

官方API

Mathf.Round()

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

        Debug.Log("Mathf.Round(10.5f)=" + Mathf.Round(10.5f));//10Debug.Log("Mathf.Round(11.5f)=" + Mathf.Round(11.5f));//12Debug.Log("Mathf.Round(-10.5f)=" + Mathf.Round(-10.5f));//-10Debug.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数学运算)

他们都有一个相似的功能:给定一个初始点,一个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));//0Debug.Log("Mathf.Lerp(0,5,200)="+Mathf.Lerp(0,5,200));//5}// Update is called once per framevoid Update(){// 从第2秒开始沿x方向从0匀速移动到5,速度为(maxX-minX)/1transform.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);}

在这里插入图片描述


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

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

在这里插入图片描述
但可以明显看出移动很不平滑,且代码不简洁,接下来将介绍两个函数能方便实现非线性平滑变换

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 framevoid Update(){transform.position = new Vector3(Mathf.SmoothDamp(transform.position.x,target,ref velocity,5f,maxSpeed),transform.position.y,transform.position.z);}

在这里插入图片描述

疑问:
  • 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 framevoid Update(){transform.position = new Vector3(Mathf.SmoothStep(0,target,Time.time/5),transform.position.y,transform.position.z);}

三者比较
在这里插入图片描述

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 framevoid 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数学运算)
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 之间递增和递减。

在这里插入图片描述
要想实现往复运动,比如对前面的Time.time取repeat 或者pingpong就能实现往复运动
在这里插入图片描述

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数学运算)


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

  • 随机颜色过渡

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

钢筋切割