草庐IT

Unity如何平滑运动-移动及运动方式(附通用实现代码)

米莱虾 2023-08-09 原文

基础知识引入

移动物体方式分2种

  • 非物理移动(没有力/速度等因素),只需要改变物体的位置Position即可  
  • 物理运动,这个时候就需要使用Unity中的物理系统

运动方式有3种

1. 朝一个方向运动

非物理运动

在Update中对Transform.position中的 (x, y, z) 值自加,例如Transform.position.x+=0.1f,0.1f被称为步长

物理运动(Rigidbody组件中的方法

  • Rigidbody.AddForce() 方法在某一个方向上施加力的效果    
  • Rigidbody.velocity 给物体一个移动速度    
  • CharacterController 中的方法,由于 CharacterController 中继承部分的 Rigidbody 属性,也可以控制物体移动,主要用于制作第一,三人称射击运动  

2. 向着目标点移动(一般是鼠标点击点)

非物理运动

  1. Transform.Translate:举个例子,Transform.Translate(Vector3.zero*Time.deltaTime) 以一米每秒的速度向 (0,0,0) 点运动    
  2. Vector3.lerp:Vector.Slerp,Vector3.MoveTowards插值。Vector3.lerp(transform.position, targetposition, Time.deltaTime),Slerp主要用于角度弧度的插值运算,MoveTowards在Lerp基础上增加了限制最大速度    
  3. Vector3.SmoothDamp:该方法是可以平滑的从A逐渐移动到B点,并且可以控制速度,最常见的用法是相机跟随目标。

物理运动

  • Righdbody 中的 Rigidbody.MovePosition 方法用于实现向目标点移动   

3. 由A点到B点(运动方式2的特殊化)


运用

一个物体在运动状态下,会有一个速度变量,也就是我们期望的速度。而从静止到运动状态的过程,会有一个加速度。而游戏开发中,要做到一个物体平滑的运动,也就是模拟出这个从静止,通过加速度,达到期望速度的过程。游戏是按帧运行的,在初始的时候,目标运动速度为 0,随着每一帧的流逝,目标速度会不断累加一帧中的加速度,当累加到期望速度时,则会以期望速度来运动。

Unity 中实现的代码如下(原理对于所有游戏引擎通用)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovingSphere : MonoBehaviour
{
    // 用户设定最大期望速度
    [SerializeField, Range(0f, 100f)] private float maxSpeed = 10f;
    // 用户设定最大加速度
    [SerializeField, Range(0f, 100f)] private float maxAcceleration = 10f;

    // 当前的运动速度
    private Vector3 velocity;

    // Update is called once per frame
    void Update()
    {
        // 通过读取用户输入,来确定期望速度向量(向量包含了大小和方向)
        Vector2 playerInput;
        playerInput.x = Input.GetAxis("Horizontal");
        playerInput.y = Input.GetAxis("Vertical");
        Vector3 desiredVelocity = new Vector3(playerInput.x, playerInput.y, 0.0f) * maxSpeed;

        // 计算这一帧中的最大加速度(现实中是以秒为单位,而游戏运行是以帧为单位)
        float maxSpeedChanged = maxAcceleration * Time.deltaTime;

        // 下面的代码是将当前速度限制为最大期望速度
        if (velocity.x < desiredVelocity.x)
        {
            velocity.x = Mathf.Min(velocity.x + maxSpeedChanged, desiredVelocity.x);
        }
        else if (velocity.x > desiredVelocity.x)
        {
            velocity.x = Mathf.Max(velocity.x - maxSpeedChanged, desiredVelocity.x);
        }

        if (velocity.y < desiredVelocity.y)
        {
            velocity.y = Mathf.Min(velocity.y + maxSpeedChanged, desiredVelocity.y);
        }
        else if (velocity.y > desiredVelocity.y)
        {
            velocity.y = Mathf.Max(velocity.y - maxSpeedChanged, desiredVelocity.y);
        }

        // 得到了当前速度,就可以计算当前这一帧的位移
        Vector3 displacement = velocity * Time.deltaTime;

        // 将物体的当前位置,累加上这一帧的位移,就是最终的移动
        transform.localPosition += displacement;
    }
}

有关Unity如何平滑运动-移动及运动方式(附通用实现代码)的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  8. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  9. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  10. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

随机推荐