Unity面向新手,如何使物体移动,让物体自由的动起来。几种移动方案讲解

这篇具有很好参考价值的文章主要介绍了Unity面向新手,如何使物体移动,让物体自由的动起来。几种移动方案讲解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

在大部分的Unity游戏开发中,移动是极其重要的一部分,移动的手感决定着游戏的成败,一个优秀的移动手感无疑可以给游戏带来非常舒服的体验。而Unity中有多种移动方法,使用Transform,使用刚体Rigidbody,使用CharacterController,使用NavMesh导航系统等等等等。当然,对于新手来说,最常见的莫过于使用Transform和Rigidbody这两种组件的移动方案。所以,这篇文章将就这两种移动方案进行分析讲解。

注意!!!以下代码均为2D场景,3D同理

二、Transform

Transform组件是GameObject的变换组件,可以操纵GameObject的位置(Position),大小(Scale),旋转(Rotation)等等。所以,使用Transform组件进行物体移动是一个非常不错的选择,以下是通过Transform组件实现的几种移动方式,以及对应的场景。

1.Translate

使用Transform的Translate函数可以在GameObject的本地坐标系下进行平移。可以传入一个位移向量作为参数,指定平移的方向和距离。

[SerializeField] private float moveSpeed;
    private void Update()
    {
        //自动向右移动
        transform.Translate(Vector2.right * moveSpeed * Time.deltaTime);
    }
//物体沿向量指向方向移动
//Vector2.right 向右移动向量,也可以写成自己定义的
//moveSpeed 移动速度,通常为float型

Translate方法在游戏中可以用作物体移动,适用简单的移动方式,例如箱子在平面上自动移动等等。

2.MoveTowards

使用Transform的MoveTowards函数可以实现直线移动到目标位置。可以传入当前位置、目标位置和移动速度来控制移动的速度和到达目标位置。

MoveTowards函数对应的三个参数分别为(当前位置,目标位置,移动速度),前两个为Vector类型,最后一个为float类型,也可以写成整型等。

例如:将物体移动到(5,5)的位置

    [SerializeField] private float moveSpeed;
    private void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position,new Vector2(5,5),moveSpeed);
    }

3.Lerp

使用Transform的Lerp函数可以实现平滑插值移动。可以传入起始位置、目标位置和插值比例来控制移动的过渡效果。

Lerp函数对应的三个参数分别为(当前位置,目标位置,插值比例),前两个为Vector类型,最后一个为float型=类型,插值比例范围是[0,1],当lerp取0时,物体不移动,lerp取1时,物体直接移动到目标位置,lerp取值越大,物体移动越快。

例如:将物体移动到(5,5)

[SerializeField] private float moveSpeed;
[SerializeField] private float lerp;
private void Update()
{
    transform.position = Vector3.Lerp(transform.position, new Vector2(5,5), lerp); 
}

接下来,将讲解一下Lerp函数的移动原理:

插值系数lerp本质上是物体每次移动距离与物体当前位置到目标位置的比值,物体每次移动后,都会重新重置下一步移动距离,但是比例不变,也就是说,物体朝目标点移动,每次移动的距离都会变短。听起来非常绕口对吧,下面我们用一幅图来讲解一下这个原理。

unity 移动,Unity开发面向新手,unity,游戏引擎,游戏程序,游戏

 红色竖线为第一次移动到的位置,那么它的移动距离L1=S1*lerp,蓝色竖线第二次移动到的位置,那么第二次移动的距离L2=S2*lerp,同理,L3=S3*lerp。由图可知,物体每次移动的距离都在缩短,但是,它们每次移动的距离与当前位置到目标位置的距离的比值不变。并且,我们也可以发现,lerp值越大,单次移动距离越大,即速度越快,相反,lerp越小,单词移动距离也就越小。最后,我们不难发现,在Lerp函数中,物体移动的距离永远是当前位置到目标位置的距离*lerp,也就是说,物体永远不可能到达目标位置,只会无限接近目标位置。所以,为了使物体可以到达目标位置,我们可以添加一个if条件,当物体的目标位置的距离小于某一值时,物体位置变为目标位置。

if (Vector2.Distance(transform.position, new Vector2(5, 5))<0.1f)
{
     transform.position = new Vector2(5, 5);
}

以上便是使用Transform移动物体的几种方案,当然使用Transform组件移动物体的方案有很多种形式,具体可以自行探索。

当然,使用Transform组件移动物体有时会出现一个小小的bug,我们将在Rigidbody中说明。

三、Rigidbody

Rigidbody,刚体组件,在这个组件中,我们可以使用物理学的定义进行物体移动等操作。并且,这也是最经常用的操控玩家移动的组件,。当然刚体组件不仅仅只用来移动GameObject,还有很多操作,在这里,我们只讲移动方面的使用。

上文说了,Transform有一个小小的bug,那就是会引起穿模,也就是说,物体在进行移动时,碰到障碍物继续移动,会导致穿过障碍物,这是一个致命的bug。但是,刚体组件就可以很好的解决这个bug。在这里,我查阅了一些资料,大致便是,Transform组件是位置的改变,也就是一次一次的发生位置变化,也就是相当于每次移动都是一段瞬移闪现,第一时间在一个位置,下一时间又瞬移到下一个位置,这样的话,在和障碍物进行挤压时,就极其容易导致物体和障碍物发生交叉,导致碰撞体检测出现异常,从而导致穿模,而刚体组件相当于拉着物体移动,就不存在这样的bug。对这方面感兴趣可以查阅相关资料。

下面继续讲解Rigidbody组件控制GameObject移动。

1.AddForce

使用AddForce函数给刚体施加力来移动物体,想要朝哪个方向移动,就在哪个方向添加力。

AddForce函数的参数为AddForce(方向向量 * 力的大小);

[SerializeField] private float force;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //向上施加一个大小为force的力
    rigidbody2D.AddForce(Vector2.up * force);
}

2.MovePosition

MovePosition函数可以直接设置物体的位置。

MovePosition函数的参数为MovePosition(位置(例如tramsform.position))

下面的代码是物体每次向右闪现/瞬移speed的长度,注意,这个方法也有可能导致穿模

[SerializeField] private float speed;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //向右移动,2D中为向右/前,X轴正方向
    rigidbody2D.MovePosition(transform.position + Vector3.right * speed * Time.deltaTime);
}

当然,也可以直接只填入目标位置,使得物体闪现到指定目标位置

[SerializeField] private Transform targetTransform;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //传送到targetTransform的位置
    rigidbody2D.MovePosition(targetTransform.position);
}

3.velocity

首先说明的是velocity不是函数,而是一个参数,也就是物体的速度。

所以我们通过对物体将要移动的方向上添加速度,也就可使物体超指定方向以固定的速度进行移动。

[SerializeField] private float moveSpeed_X;
[SerializeField] private float moveSpeed_Y;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //水平方向
    float horizontal = Input.GetAxis("Horizontal");
    //竖直方向
    float vertical = Input.GetAxis("Vertical");
    rigidbody2D.velocity=new Vector2 (horizontal*moveSpeed_X*Time.deltaTime, vertical* moveSpeed_Y * Time.deltaTime);
    //也可以只改变x或y的值
    rigidbody2D.velocity = new Vector2(horizontal * moveSpeed_X * Time.deltaTime, rigidbody2D.velocity.y);
    rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, vertical * moveSpeed_Y * Time.deltaTime);
}

四、结尾

以上便是几种简单的物体移动方式,当然使物体移动的方法有很多种,这里只列举了几种,感兴趣的小伙伴可以深究一下。文章来源地址https://www.toymoban.com/news/detail-713853.html

到了这里,关于Unity面向新手,如何使物体移动,让物体自由的动起来。几种移动方案讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 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)
  • Unity 控制物体移动

    目录 1、通过改变物体的位置使物体移动 2、通过给物体施加力使物体移动 3、移动characterController以及碰撞检测 一、相关代码展示 1、通过改变物体的位置使物体移动 2、通过给物体施加力使物体移动 3、移动characterController 以及碰撞检测 注:使用时首先要给物体添加CharacterC

    2024年02月13日
    浏览(47)
  • Unity中的物体移动

    局部坐标系(Transform.localPosition)是指当前物体相对于父物体的位置,会受到父物体的影响。 世界坐标系(Transform.Position)是指当前物体在世界空间坐标系中的位置,不受父物体影响。 若该物体有父类,则二者的关系为:该物体的世界坐标=该物体父类的世界坐标+该物体的局

    2024年02月03日
    浏览(55)
  • unity 物体移动方法

        在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position。     Transform 组件用于描述物体在空间中的状态,它包括 位置(position), 旋转(rotation)和 缩放(scale)。 其实所有的移动都会导致position的改变,这里所说的通过Transform组件来移

    2024年02月12日
    浏览(44)
  • unity物体移动至指定位置

    在Unity中,物体的坐标分为 局部坐标 和 世界坐标 。 局部坐标是相对于物体的父对象的坐标系,而世界坐标是相对于场景的整体坐标系。 举个例子 将下面代码挂载到Sphere上 输出结果如下 如果想让物体运动到指定的位置,通常情况下是参考世界坐标系。因为世界坐标系是整

    2024年02月05日
    浏览(52)
  • Unity子物体脱离父物体,解除父子关系,子物体不随父物体移动

    在Unity中创建一个手雷,并且需求是扔出手雷时,手雷不能跟随人物移动          这个需要调用 gameObject.transform.DetachChildren方法,将GrenadePosition下的所有物体的父子关系解除,那么在扔手雷时,手雷就不会随着主角移动了

    2024年02月11日
    浏览(47)
  • unity UI 跟随3D物体移动

     

    2024年02月11日
    浏览(70)
  • 【Unity入门】物体5种移动方法

    利用修改Transform组件的position的两种常用方法。 使用Translate()函数 直接指定新的位置 将上述两种方法在 void Update()实现每一帧物体向x方向移动1.5个单位,具体代码如下: 注意:此处1.5为啥要写1.5f,根据C#的语法规定,直接写1.5会被认为double类型的数,而这里需要flaot类

    2024年02月02日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包