【Unity】如何优雅地移动物体-8个方法

这篇具有很好参考价值的文章主要介绍了【Unity】如何优雅地移动物体-8个方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在游戏开发中,如何移动物体?是我们需要思考的事情。
Unity 引擎也提供了众多的方法,每个开发者的使用习惯也各不相同,所以往往不是很清楚在这种场景下哪种方式最好的或者最有效的。
那么,这篇文章,我想分享一下移动物体的一些方法和优缺点。

【Unity】如何优雅地移动物体-8个方法

【Unity】如何优雅地移动物体-8个方法

项目地址

仓库地址

如何优雅地移动物体?8个方法

向某个方向移动

Transform.Position

众所周知,我们可以给对象的Transform组件赋予一个坐标来决定其位置。

transform.position = new Vector3(2, 1, 0);

当我们每一帧给对象赋予一个新的坐标,那么看起来,这个物体就是在运动的。

    void Update()
    {
        var dir = new Vector3(0.02f, 0, 0);
        transform.position += dir;
    }

效果如下:
【Unity】如何优雅地移动物体-8个方法

Transform.Translate()

由于直接改变 Position 属性看起来不太优雅。所以 Transform 组件提供了一个更友好的方法:Transform.Translate()

      void Update()
    {
        var dir = new Vector3(0.02f, 0, 0);
        transform.Translate(dir);
    }

其实,他的内部与 Transform.Position无异。

 public void Translate(Vector3 translation, [DefaultValue("Space.Self")] Space relativeTo)
    {
      if (relativeTo == Space.World)
        this.position += translation;
      else
        this.position += this.TransformDirection(translation);
    }

效果与 Transform.Position 一致
【Unity】如何优雅地移动物体-8个方法

但是这种方法产生了一个问题。由于设备之间的差异或者动态数据的变化会导致每一帧之间的间隔是不相等的,因此,如果以帧数来控制物体移动,物体的移动距离就没办法准确把握。
效果如下
【Unity】如何优雅地移动物体-8个方法
所以我们需要在原来的基础上乘以 Time.deltaTime属性的值,从而保证每秒移动的距离是一致的。

void Update() 
{
     var dir = new Vector3(2f, 0, 0)*time;
     transform.Translate(dir);
}

这样不同的帧数移动距离都会一致。
效果如下:
【Unity】如何优雅地移动物体-8个方法

但这还不够优雅。在游戏中,我们经常需要改变物体的速度。为了方便实现,我们通常会使用单位向量来确定方向,增加一个浮点值来控制速度。

public float speed = 2;
void Update()
{
    var dir = new Vector3(2,0,0)
    transform.Translate(dir.normalized * speed * Time.deltaTime);
}

移动到指定位置

移动到指定位置,大概有两种方式。

  1. 速度:物体通过特定速度向目标移动。
  2. 时间:物体在时间内到达目标。

Vector3.MoveTowards():固定速度

以固定的速度移动到目标位置

public Vector3 targetPosition;
public float speed=10;
void Update()
{
    transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}

效果:
【Unity】如何优雅地移动物体-8个方法

Vector3.SmoothDamp():平滑移动

又或者,我们可以用平滑的方式到达目标位置。(平滑:到达位置前提前减速)

public Vector3 targetPosition;
public float smoothTime = 0.5f; 
public float speed = 10;
Vector3 velocity ;
void Update()
{
    transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime, speed);
}

效果:
【Unity】如何优雅地移动物体-8个方法

Vector3.Lerp():线性时间移动

该方法的意思是在调用方法期间,已经过的时间除以总持续时间,得到当前的位移目标。

 // 终点
    public Vector3 targetPosition;
    // 开始位置
    public Vector3 startPosition;
    // 持续时间
    public float lerpDuration = 4;
    // 记录运行时间
    private float _timeElapsed = 0;
    
    void Start()
    {
        startPosition = transform.position;
    }

    void Update()
    {
        // 记录下一个位置
        Vector3 valueToLerp;
        _timeElapsed += Time.deltaTime;
        if (_timeElapsed < lerpDuration)
        {
            valueToLerp  = Vector3.Lerp(startPosition, targetPosition, _timeElapsed / lerpDuration);
        }
        else
        {
            valueToLerp = targetPosition;
        }
        transform.position = valueToLerp;
    }

效果如下:
【Unity】如何优雅地移动物体-8个方法

以上的这些方法足以让我们准确且随心的操纵物体移动。
但有一些场景,我们并不希望如此精确或始终如一的运动轨迹,我们想物体的移动受 Unity 的物理引擎影响或者其他物体影响。
同时如果用以上方法移动,在 Unity 的物理引擎下会出现抖动,穿过刚体等奇怪的现象。
【Unity】如何优雅地移动物体-8个方法

那么接下来,我们就需要用到一些涉及到物理引擎的移动方式。

物理引擎移动

Rigidbody.AddForce()

使用这个方法给物体添加一个方向力。在力的作用下,物体将会移动。那么移动速度和位移就会与物理特效有关,比如物体质量,阻力,甚至还有重力。

一般会有两种使用方式。
在初始时给物体一个力,让其顺着物理规律下运动。使用场景一般时跳跃或者碰撞。

    // 赋予200的力
    public float force = 200;
    private Rigidbody2D _rigidbody2D;
    // 移动方向
    private Vector3 dir = Vector3.right;
    
    void Start()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
        _rigidbody2D.AddForce(Vector2.right * force);
    }

为了更好演示刚体的运动,我还给刚体的线性阻力改为1,这样没有持续施加外力的情况下,物体会因为摩擦力的存在而停下。
【Unity】如何优雅地移动物体-8个方法
效果如下:
可以看到物体很快就停下了
【Unity】如何优雅地移动物体-8个方法

第二种,会在每一帧持续给物体施加力,使物体可以持续运动。

 // 赋予2的力
    public float force = 2;
    private Rigidbody2D _rigidbody2D;
    // 移动方向
    private Vector3 dir = Vector3.right;
    void Start()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        _rigidbody2D.AddForce(Vector2.right * force);
    }

效果如下:
【Unity】如何优雅地移动物体-8个方法
从效果可以看到,在持续给外力的作用下,物体移送越来越快,但在阻挡物前会停下。

Rigidbody.Velocity

直接赋予 Velocity 属性一个向量,可以立即改变物体的速度。一般情况下,我们不需要直接修改速度,除非你非常明确需要立即改变物体的速度。

    public float speed = 10;
    private Rigidbody2D _rigidbody2D;
    // 移动方向
    private Vector3 dir = Vector3.right;
    
    void Start()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        _rigidbody2D.velocity = dir * speed;
    }

效果如下:
看到物体一开始就已经有速度,而通过AddForce方法添加力的物体,速度时慢慢提高的。
【Unity】如何优雅地移动物体-8个方法

Rigidbody.MovePosition()

该方法有比较局限的使用场景,当物体的刚体类型是 Kinematic 时,使用Rigidbody.MovePosition() 方法进行移动。
因为 Kinematic 类型下,不会受到重力和AddForce、AddTorque等力相关的函数的影响!!!

	public float speed = 10;
    private Rigidbody2D _rigidbody2D;
    // 移动方向
    private Vector3 dir = Vector3.right;
    
    void Start()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    private void FixedUpdate()
    {
        var positon = dir * (speed * Time.deltaTime);
        _rigidbody2D.MovePosition(transform.position + positon);
    }

效果如下:
【Unity】如何优雅地移动物体-8个方法

刚体类型是 Kinematic 时 ,会对刚体类型为 Dynamic 施加力,而无视 static 类型。

在文末,欢迎在评论区发表你的见解。如果觉得写的不错,可以给我点赞,鼓励一下,谢谢。文章来源地址https://www.toymoban.com/news/detail-406754.html

到了这里,关于【Unity】如何优雅地移动物体-8个方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity 通过键盘鼠标控制物体移动、旋转、缩放的方法

    在Unity中,使用键盘ADWS键控制物体移动,通过鼠标左键控制物体旋转,鼠标中键控制物体缩放是再常见不过的方法。 方法如下:  效果如下:Unity 通过键盘鼠标控制物体移动、旋转、缩放_哔哩哔哩_bilibili

    2024年02月03日
    浏览(51)
  • Unity 语法详解之查找游戏物体的方法(含查找隐藏物体)

    为了更好的看懂,有一个非常基础的知识,如果不知道可以移步去了解一下哦 unity | gameobject和transform的区别和关联通俗解释_gameobject transform_菌菌巧乐兹的博客-CSDN博客 一、前情提要 大写的 GameObject是个类,里面写满了物体有关的代码 小写的 gameObject指的是物体本身 大写的

    2024年02月12日
    浏览(46)
  • [Unity] 使用Mathf函数实现平滑移动物体的7种方法

     Unity中要利用Mathf中的函数实现物体的平滑运动,有以下7种方法: Mathf.SmoothDamp、Mathf.Lerp、Mathf.SmoothStep三个方法非常相似,分别使用三个方法移动同一个物体的效果如图所示: 可以看出,三者均是先快后慢,但SmoothDamp方法会有一些卡顿;SmoothStep与Lerp比较起来,Mathf.Smooth

    2024年02月12日
    浏览(52)
  • 【Unity自制手册】基于Unity中物体移动相关方法和API集锦(动图详解)

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unity每日一记 ⭐相关文章: 线性差值函数以及平滑阻尼的运用和实践(Lerp AND SmoothDamp) ⭐相关文章:基础不牢,地动山摇系列 ------ 软

    2024年01月16日
    浏览(40)
  • 【笔记】Unity2D角色和物体移动的几种方法

    在Unity中对于物体移动有多种方法,这里根据b站up主【鼓励Jun】的视频整理了一些笔记 变量声明: 位移向量var dir=new Vector3(deltax.deltay,deltaz); 移动速度var speed=2; ps:变量声明都在主要都在方法外,实际位移操作则在Update方法中。 #键盘输入,这里举一个只x轴上移动的例子,y轴同

    2023年04月08日
    浏览(58)
  • Unity之获取游戏物体对象或组件的几个方法

    在unity的实际项目开发中,往往都要获取游戏内的各种物体,比如玩家(Player),怪物(Monster),或者其他,那有什么方法可以快速获取呢,下面就来介绍unity获取游戏对象的几个方法 GameObject.Find GameObject.Find 通过游戏物体的名称获取对象 使用方法 缺点: 会遍历当前整个场

    2024年02月01日
    浏览(43)
  • Unity学习笔记--如何优雅简便地利用对象池生成游戏对象(进阶版)LRU + 对象池

    之前写过一篇关于对象池的文章,现在来看写的并不是很好,所以来考虑优化下。 现在来看一年前写的代码,越看越不能入目hhh Unity学习笔记–如何优雅简便地利用对象池生成游戏对象 Unity学习笔记–使用 C# 开发一个 LRU PoolManager.cs BaseFactory.cs 创建 Factory 创建 object 创建 Bu

    2024年02月13日
    浏览(50)
  • Unity之用代码移动物体(平滑移动)

    因为移动的起点和终点都是不确定,所以这里用代码进行实现而不是动画(试过动画,但是发现无法成功添加clip) 物体移动常用的有两个方法,一个是Mathf.MoveTowards,一个是Mathf.Lerp,他们都用于值的平滑过渡 Mathf.MoveTowards          current:起点位置         target:目

    2024年02月07日
    浏览(41)
  • Unity点击物体后,移动到物体所在位置

    脚本挂在被点击的物体上 脚本挂在角色控制器上 改进:使用Raycast中的LayerMask 创建“cube”层 将想要被检测的物体放入该层 3.1、 3D物体事件监听 在相机上挂Physics Raycaster组件 检查是否有EventSystem 将脚本挂在被点击的物体上 添加组件Event Trigger组件 3.2、 世界UI世界监听

    2024年02月07日
    浏览(52)
  • 【Unity】摄像机跟随鼠标移动以物体为中心旋转 物体根据视线方向移动

    描述 实现摄像机根据鼠标移动跟随物体旋转,以摄像机前物体为中心,摄像机围绕物体旋转,并使摄像机时刻指向物体 实现效果 Unity 组件设置 Camera 组件设置 Body 组件设置 实现代码 CameraRotateMove.cs 摄像机跟随和旋转 move_better.cs 物体根据按键移动

    2024年02月08日
    浏览(91)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包