IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【Unity步步升】各类移动逻辑的区别,如刚体速度、平滑阻尼、线性插值等... -> 正文阅读

[游戏开发]【Unity步步升】各类移动逻辑的区别,如刚体速度、平滑阻尼、线性插值等...

目录

一、非物理类移动

二、物理类移动


(以下内容涉及示例图内容受GIF帧率影响,不代表真实观感)

一、非物理类移动

①Transform变换相关

  • transform.Translate()是非物理移动使用的比较频繁的一种方式,无论是2d还是3d适用范围都比较广,我们根据官方给出的函数结合Input类函数实现前后左右:

public void?Translate?(Vector3?translation,?Space?relativeTo= Space.Self);


    /// <summary>
    /// 变换移动-V3.?
    /// </summary>
    void transMove1() {
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(Vector3.forward * speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(Vector3.back * speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.A))
        {
            transform.Translate(Vector3.left * speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.D))
        {
            transform.Translate(Vector3.right * speed * Time.deltaTime);
        }    
}

图1-1 GetKey与Translate

缺点:?

整体移动观感较为僵硬,设置Key键代码重复率高,输入受帧率影响

优点:

8向移动较为平滑,I/O反馈及时手感还不错(个人觉得算优点)


  • 同样为transform.Translate()方法,不过是将Input.GetKey()改为GetAxis(),官方给出的示例:

public static float?GetAxis?(string?axisName);

如果将轴映射到鼠标,该值会有所不同,并且不会在 -1...1 的范围内。此时,该值为当前鼠标增量乘以轴灵敏度。通常,正值表示鼠标向右/向下移动,负值表示鼠标向左/向上移动。该值与帧率无关;使用该值时,您无需担心帧率变化问题。


    /// <summary>
    /// 变换移动-V3+Translate
    /// </summary>
    void transMove2() {
        float h = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
        float v = Input.GetAxis("Vertical") * speed * Time.deltaTime;

        Vector3 thisVec = new Vector3(h, 0, v);
        transform.Translate(thisVec);
    }

图1-2 ?GetAxis与Translate

缺点:?

优点:

有一定的惯性感,同样8向平滑,因为输入方法不受帧率影响手感更好


  • transform.position与transform.localPosition的加减
    /// <summary>
    /// 变换移动-V3+position加减法
    /// </summary>
    void transMove3(){
        if (Input.GetKey(KeyCode.W)) {
            transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, transform.localPosition.z + speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.D))
        {
            transform.localPosition = new Vector3(transform.localPosition.x + speed * Time.deltaTime, transform.localPosition.y, transform.localPosition.z);
        }

        if (Input.GetKey(KeyCode.S))
        {
            transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, transform.localPosition.z - speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.A))
        {
            transform.localPosition = new Vector3(transform.localPosition.x - speed * Time.deltaTime, transform.localPosition.y, transform.localPosition.z);
        }
    }

?图1-3 position与localPosition

缺点:?

同第一种较为僵硬,代码量较大

优点:

8向移动较为平滑,相比第一种要更顺畅一些


②Vector向量相关

  • SmoothDamp()平滑阻尼的方式,所涉及的参数较多,但效果很好。随时间推移将一个向量逐渐改变为所需目标。向量通过某个类似于弹簧-阻尼的函数(它从不超过目标)进行平滑。 最常见的用法是用于平滑跟随摄像机。其中官方给出的示例:

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

其中参数从左到右分别是:当前位置,目标位置,当前速度,到达目的的时间近似值,最大速度,函数调用时间

    /// <summary>
    /// v3移动-平滑阻尼
    /// </summary>
    void v3Move1() {
    //vt我设置的是private Vector3 vt = Vector3.zero;
    //smoothTime为5
        //mousePosition = Input.mousePosition;
        transform.position = Vector3.SmoothDamp(transform.position, target, ref vt, smoothTime);
    }

?图2-1 SmoothDamp下的摄像机

缺点:?

参数较多,且涉及当前速度参数设置时候较为麻烦

优点:

代码量极少,效果很好,很适合制作摄像机运镜或跟随摄像机的平滑过渡,也可以联系鼠标输入做moba类游戏


  • Lerp()线性插值,同样涉及参数较多,且想要好的使用效果需要计算。在两个点之间进行线性插值。使用插值?t?在点?a?和?b?之间进行插值。参数?t?限制在范围 [0, 1] 内。这最常用于查找占两个终端之间距离特定百分比的点(例如,以便在这些点之间逐步移动对象),官方给出的示例:

public static?Vector3?Lerp?(Vector3?a,?Vector3?b, float?t);

其中参数从左到右分别是:起始位置,目标位置,当前插值(0~1)。若不理解插值的含义,可以简单参考若插值为0则返回的是V3 a,1则是V3 b,0.5则是V3 (a+b)/2

    public Transform startMarker;
    public Transform endMarker;
    private float startTime;
    private float journeyLength; //两点距离
        
    void Start()
    {
        startTime = Time.time;
        journeyLength = Vector3.Distance(startMarker.position, endMarker.position);
    }

    /// <summary>
    /// v3移动-线性插值Lerp
    /// </summary>
    void v3Move2() {
        float distCovered = (Time.time - startTime) * speed; //两点间移动所需要的时间
        float fractionOfJourney = distCovered / journeyLength; //帧率与时间换算的百分比值
        transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fractionOfJourney);
    }

?图2-2 Lerp()线性插值

缺点:?

同样参数较多,且需要计算,用帧率和时间换算的插值较难理解

优点:

比较灵活,可以通过其他条件控制实现一些建议AI或特殊武器的效果


  • SLerp()球形插值,涉及参数较多,且想要好的使用效果需要计算。在两个向量之间进行球形插值。在?a?和?b?之间按大小?t?进行插值。 球形插值与线性插值(也称为“lerp”)的区别在于, 向量被视为方向而不是空间中的点。返回的向量的方向通过角度进行插值, 其?magnitude?在?from?和?to?的大小之间进行插值。官方给出的示例:

public static?Vector3?Slerp?(Vector3?a,?Vector3?b, float?t);其参数设置与线性插值一样

    /// <summary>
    /// v3移动-球型插值SLerp
    /// </summary>
    void v3Move3() {
        Vector3 center = (startMarker.position + endMarker.position) * 0.5F; //圆弧中心点 (a+b)/2
        center -= new Vector3(0, 1, 0); //将圆弧中心下移,使弧垂直

        //相对于中心点在圆弧上插值
        Vector3 riseRelCenter = startMarker.position - center;
        Vector3 setRelCenter = endMarker.position - center;

        float fracComplete = (Time.time - startTime) / journeyLength; //所需时间除以所经时间得t[0,1]

        transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);
        transform.position += center;
    }

图2-3 SLerp()球形插值

缺点:?

同样参数较多,且需要计算,同时无法修改移动速度,因其插值和两点挂钩

优点:

可以制作一些星球起落或导弹轨迹的效果

二、物理类移动

①刚体力相关

  • rigidbody.AddForce(),添加力的方式推动物体。向?Rigidbody?添加力。沿?force?矢量的方向连续施加力。可以指定?ForceMode?/mode/,以将力的类型更改为Acceleration、Impulse 或 Velocity Change。施加的力在?FixedUpdate?中计算,或通过显式调用?Physics.Simulate?方法来计算。官方给出的示例:

public void?AddForce?(Vector3?force,?ForceMode?mode= ForceMode.Force);

    /// <summary>
    /// 刚体移动-AddForce()
    /// </summary>
    void rbMove1() {
        float h = Input.GetAxis("Horizontal") * speed; //充当force力
        float v = Input.GetAxis("Vertical") * speed;

        rb.AddForce(new Vector3(h, 0, v));
    }

图3-1 AddForce()移动

缺点:?

若想要好的效果,还需要外加对速度和力的控制条件,且与重量、角速挂钩

优点:

手感观感上都更加真实,参数细节调的好的话体验会非常不错


②刚体速度相关

  • rigidbody.Velocity,为刚体添加方向的速度。刚体的速度矢量。它表示刚体位置的变化率。官方给出的示例:

rb.velocity = new Vector3(0, 10, 0);?

isMoving = true;

    /// <summary>
    /// 刚体移动-Velocity
    /// </summary>
    void rbMove3()
    {
        //在大多数情况下,不应该直接修改速度,因为这可能导致行为失真 - 改用 AddForce 请勿在每个物理步骤中设置对象的速度,这将导致不真实的物理模拟。
        //需要更改速度的一个典型用法是第一人称射击游戏中的跳跃动作设计,因为此时需要立即更改速度。rb.velocity = new Vector3(0, 10, 0);
        Vector3 maxVelocity = new Vector3(30,0,0);
        if (Input.GetKeyDown(KeyCode.W)) {
            rb.velocity += new Vector3(10, 0, 0); //速度会不断增加,根据需要设置顶峰或停滞

            //若等于最大值
            if (rb.velocity.Equals(maxVelocity)) {      
                rb.velocity = new Vector3(0,0,0);
                rb.Sleep();
            }
        }
    }?

?图3-2 Velocity模拟赛车加速

缺点:?

同上,需要外加控制

优点:

手感观感上都更加真实,速度变化更舒适可以做赛车竞速类游戏


②刚体方法相关

    /// <summary>
    /// 刚体移动-MovePosition()
    /// </summary>
    void rbMove2() 
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        rb.MovePosition(transform.position + new Vector3(h, 0, v) * speed * Time.deltaTime);
    }

?图3-3 MoveToPosition()移动

缺点:?

无(我认为最好用的一个)

优点:

既涉及到质量速度等因素,又可以有很高的帧率,且代码量极少,不断反复还可以明显感受到动态变化的过程


好了如果觉得对你有帮助的话不如给个点赞加关注,如果有问题也欢迎评论或私聊我解决哦。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:54:10  更:2022-03-24 00:54:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 21:37:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码