草庐IT

Unity初学1——角色移动控制(2d)

林浮生 2023-07-25 原文

该文来自学习chutianbo老师的笔记,链接b站
在unity中移动角色一般采用控制角色transtion属性中的position其依据的坐标轴,一般就为二元一次方程的xy轴

最简单的移动

public class RubyController : MonoBehaviour
{
    // 每帧调用一次 Update
    // 让游戏对象每帧右移 0.1
    void Update()
    {
        // 创建一个 Vector2 对象 position,用来获取当前对象的位置
        Vector2 position = transform.position;
        // 更改 position 的 x 坐标值,让其 加上 0.05
        position.x = position.x + 0.05f;
        // 更新当前对象的位置到新位置
        transform.position = position;
    }
}

那么这样每一帧我们的角色都会向x的正方向轴移动0.05距离(帧数越高,移动越快)。

用控制来移动

public class RubyController : MonoBehaviour
{
   // 每帧调用一次 Update
    // 让游戏对象每帧右移 0.1
    void Update()
    {
        // 获取水平输入,按向左,会获得 -1.0 f ; 按向右,会获得 1.0 f
        float horizontal = Input.GetAxis("Horizontal");
        // 获取垂直输入,按向下,会获得 -1.0 f ; 按向上,会获得 1.0 f
        float vertical = Input.GetAxis("Vertical");

        // 获取对象当前位置
        Vector2 position = transform.position;
        // 更改位置
        position.x = position.x + 0.1f * horizontal;
        position.y = position.y + 0.1f * vertical;
        // 新位置给游戏对象
        transform.position = position;
    }
}

这似乎是使用unity自带的组件进行移动,通过获取默认的垂直按键和水平案件,即直接对应wasd和方向键。

第二种控制移动方式

public class RubyController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    
        Vector2 position = transform.position;

        if (Input.GetKey("w"))
        {
            position.y = position.y + 0.05f;
        }else if (Input.GetKey("a"))
        {
            position.x = position.x - 0.05f;
        }else if (Input.GetKey("s"))
        {
            position.y = position.y - 0.05f;
        }
        else if(Input.GetKey("d")){
            position.x = position.x +0.05f;
        }

        
       
        transform.position = position;
    }
}

使用getkey自定义控制方式

但是第一种和第二种中使用的GetKey和GetAxis两个方法的区别在于。GetKey只有0和1的区别,不会存在0.5或者0.05。但是getAxis是一种平滑曲线(移动控制推荐)。

直接使用update移动的弊端

由于update的调用时直接和游戏帧数挂钩的,即一帧调用一次update,所以你帧数越高,角色移动越快
假设游戏30帧,那么0.1f在一秒钟移动就是0.1*30为3个单位。如果是60帧,一秒钟就是6个单位。

解决帧数影响移动速率的方法一:锁帧

  void Start()
    {
    //开垂直同步//
        QualitySettings.vSyncCount = 0;
        //帧率设置为50//
        Application.targetFrameRate = 50;
    }

但是锁帧会降低游戏画面质量,所以我们使用单位秒来控制Ruby的行动

暂时的最终解决办法

public class RubyController : MonoBehaviour
{
 public float speed = 0.1f;
 // Start is called before the first frame update
 void Start()
 {

 }

 // Update is called once per frame
 void Update()
 {
     float horizontal = Input.GetAxis("Horizontal");
     float vertical = Input.GetAxis("Vertical");
     Vector2 position = transform.position;
     position.x = position.x + speed * horizontal * Time.deltaTime;
     position.y = position.y + speed * vertical * Time.deltaTime;
     transform.position = position;
 }
}

这样子的话,我们会发现speed=5时才能堪堪获得原本使用帧控制时0.1的速度;

解决碰撞时的bug

如果按照上方最后一份代码控制移动,那么我们会发现在两个刚体碰撞时,我们的角色会出现鬼畜,即我们的位置先进入了碰撞体所占据的位置,然后又被弹了出来,所以这里我们需要引入物体的刚体组件来解决

void Start()
 {
     //获得当前游戏对象的刚体组件
     rigidbody2d = GetComponent<Rigidbody2D>();


 }
   void Update()
 {
    horizontal = Input.GetAxis("Horizontal");
    vertical = Input.GetAxis("Vertical");

 }
 //固定时间间隔刷新方法
 private void FixedUpdate()
 {
    
     Vector2 position = transform.position;
     position.x = position.x + speed * horizontal * Time.deltaTime;
     position.y = position.y + speed * vertical * Time.deltaTime;
     rigidbody2d.position = position;
 }

这里我们需要将获取移动放在update中,因为这样是一帧一调用,会更加平滑,放在FixedUpdate则是约是20ms一调用。

好,常规的bug时间
在上面这套使用物理系统的移动之后,我们在后续加入敌人移动之后,在与其他有力的作用的物体碰撞之后,我们的主角也会获得一个另一个物体移动方向的力(约莫就是机器人向下走,主角在机器人下方被碰撞,主角会一直向下直到碰到其他的碰撞体)
按照解答是刚体移动不能直接使用位置赋值
所以 rigidbody2d.position = position;这一句我们要改成 rigidbody2d.MovePosition(position);

本文仅是个人初步学习unity所用
链接: Ruby’s Adventure:2D 初学者
链接:垂直同步是什么
链接:Time.deltaTime的官方文档

有关Unity初学1——角色移动控制(2d)的更多相关文章

  1. 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上找到一

  2. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  3. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  4. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  5. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  6. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  7. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  8. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  9. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  10. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

随机推荐