【unity实战】Unity实现2D人物双击疾跑

最终效果

在这里插入图片描述

前言

我们要实现的功能是双击疾跑,当玩家快速地按下同一个移动键两次时能进入跑步状态

我假设快速按下的定义为0.2秒内,按下同一按键两次

简单的分析一下需求,实现它的关键在于获得按键按下的时间,我们需要知道第一次按下按键的时间,然后判断规定时间内有没有按下按键

有两种实现方法
第一种
启动一个计时器,判断在计时器结束之前有没有再次按下这个键
在这里插入图片描述
第二种
是分别记录下两次按键的时间,然后用第二次按下的时间减去第一次按下的时间,判断是否小于0.2
在这里插入图片描述
这里我采用第二种方法,为了获取按下的时间,我们需要使用到Unity给我们提供的Time类,里面的Time.time会提供游戏启动到现在运行了多少秒,这个需求还需要我们检测到按键是否被按下,我打算使用Input Manager来实现

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

GetAxisRaw会在检测到按键后,马上返回1或-1,松开按键后马上变成0
而GetAxis会在检测到按键的时候,从0过渡到1或-1,松开按键后再过渡到0

为了方便,我使用GetAxisRaw来获得输入的时间,当按键按下时意味着GetAxisRaw的返回值为1的绝对值,我们在符合条件的时候使用Time.time来获得当前的时间即可

但显然,我们不希望玩家按下a后马上按下d,还能让人物进入到疾跑状态,所以两个按键的输入时间要分开存储,还有一个需要注意的地方是,当玩家开始走路或疾跑时,a键或d键是按住不放的,所以当玩家在移动的时候,我们要使个bool变量为真,当这个变量为真时,就不再刷新输入的时间

我们设想一下,玩家进入游戏以后,马上按下了一次移动键,如果他电脑开游戏开的特别的快,他第一次按下移动键的时间,离打开游戏不到0.2秒,如果我们存储按键时间的变量,没有初始化,那么会默认赋值为0,当他第一次按下移动时,就会进入到疾跑状态,这很明显是我们不想要看到的bug

所以最后一个要点是给存储按键时间的变量进行初始化,但初始化的只要赋值为多少也是一个值得考虑的问题,如果赋值为一个极大的正数,就算赋值为1万,万一玩家一开始在挂机刚好在10,000.01秒,按一下移动按键,还是会错误地进入到疾跑状态,所以可以给他赋值为,负的最大等待输入时间,如果实在不放心,可以赋值为2倍,这样第一次输入就不会出现bug

经过了这么多的分析,相信你此时此刻已经完全明白了,接下来我们进入到代码实战环节

开始

配置动画,walk为true进入走路动画,run为true进入跑步动画
在这里插入图片描述
新增人物控制脚本

public class PlayerController : MonoBehaviour
{
    private Rigidbody2D rb;  // 刚体组件
    private Animator animator;  // 动画控制器
    public float maxAwaitTime;  // 最大等待时间
    private float leftPressTime, rightPressTime;  // 左键按下时间,右键按下时间
    private bool moving, canRun;  // 是否在移动,是否可以奔跑
    public int walkSpeed, runSpeed;  // 步行速度,奔跑速度
    private int currentSpeed;  // 当前速度
    private float h;  // 水平输入

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();  // 获取刚体组件
        animator = GetComponent<Animator>();  // 获取动画控制器
        leftPressTime = rightPressTime = -maxAwaitTime;  // 初始化左右按下时间
    }

    private void Update()
    {
        h = Input.GetAxisRaw("Horizontal");  // 获取水平输入
        ChangeFaceDirection();  // 更改角色朝向
        CheckRun();  // 检查奔跑状态
    }

    private void ChangeFaceDirection()
    {
        if (h == 1)
        {
            transform.localScale = new Vector3(1, 1, 1);  // 面向右侧
        }
        else if (h == -1)
        {
            transform.localScale = new Vector3(-1, 1, 1);  // 面向左侧
        }
    }

    private void CheckRun()
    {
        if (h == 1 && !moving)
        {
            if (Time.time - rightPressTime <= maxAwaitTime)
            {
                canRun = true;
            }
            rightPressTime = Time.time;
        }
        
        if (h == -1 && !moving)
        {
            if (Time.time - leftPressTime <= maxAwaitTime)
            {
                canRun = true;
            }
            leftPressTime = Time.time;
        }

		// 取 h 的绝对值
        if (Mathf.Abs(h) == 1)
        {
            moving = true;
            if (canRun)
            {
                currentSpeed = runSpeed;
                animator.SetBool("run", true);  // 设置奔跑动画
            }
            else
            {
                currentSpeed = walkSpeed;
                animator.SetBool("walk", true);  // 设置行走动画
            }
        }
        else
        {
            animator.SetBool("run", false);  // 关闭奔跑动画
            animator.SetBool("walk", false);  // 关闭行走动画
            moving = false;
            canRun = false;
        }
    }

    private void FixedUpdate()
    {
        rb.velocity = new Vector2(h * currentSpeed * Time.deltaTime, rb.velocity.y);  // 更新刚体速度
    }
}

效果
在这里插入图片描述

参考

如果觉得本文实现的效果不错的话,非常推荐大家去支持一下原作者

【视频】https://www.bilibili.com/video/BV1YN4113771/

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/124059.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS进阶:水源涵养功能分级评价操作

首先抛出水源涵养重要性评价的公式&#xff1a;水源涵养量降雨量-蒸散发量-地表径流量&#xff0c;其中地表径流量降雨量*平均地表径流系数 声明&#xff1a;以下数据来源于来自于牛强老师书籍&#xff08;城乡规划GIS技术&#xff09;。 以下给出重要性评价阈值表&#xff1…

什么是final修饰 使用final修饰类、方法、变量的区别?

简介: 变量成为常量&#xff0c;不允许修改 当final修饰类时&#xff0c;该类变为最终类&#xff08;或称为不可继承的类&#xff09;。不能从最终类派生子类。这样做的目的是为了防止其他类修改或扩展最终类的行为。当final修饰方法时&#xff0c;该方法成为最终方法&#xf…

采集Prestashop独立站

这是一个用Lua编写的爬虫程序&#xff0c;用于采集Prestashop独立站的内容。爬虫程序使用代理信息&#xff1a;proxy_host: jshk.com.cn。 -- 首先&#xff0c;我们需要导入所需的库 local http require(socket.http) local url require(socket.url)-- 然后&#xff0c;我们…

集合框架:List系列集合:特点、方法、遍历方式、ArrayList,LinkList的底层原理

目录 List集合 特有方法 遍历方式 1. 使用普通 for 循环&#xff1a; 2. 使用增强型 for 循环&#xff08;foreach&#xff09;&#xff1a; 3. 使用迭代器&#xff08;Iterator&#xff09;&#xff1a; 4. 使用 Java 8 的流&#xff08;Stream&#xff09;API&#xff…

Python按类别和比例从Labelme数据集中划分出训练数据集和测试数据集

Python按类别和比例从Labelme数据集中划分出训练数据集和测试数据集 前言前提条件相关介绍实验环境按类别和比例从Labelme数据集中划分出训练数据集和测试数据集代码实现输出结果 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#x…

六大排序算法:插入、选择、冒泡、快排、希尔、归并

1、插入排序 解析&#xff1a;第一个元素设定为已经排好序&#xff0c;依次选择后续的元素插入到已经排好序的组内进行排序。 图示&#xff1a; 代码&#xff1a; public static void insertionSort(int[] arr) {int n arr.length;for (int i 1; i < n; i) {int key a…

视频剪辑高手的秘诀:如何从视频中提取封面,提高视频点击率

在视频分享平台上&#xff0c;一个吸引人的封面往往能吸引更多的观众点击。一个好的封面可以传达视频的主题&#xff0c;吸引人们的兴趣&#xff0c;提高视频的点击率。那么&#xff0c;如何从视频中提取封面呢&#xff1f;下面&#xff0c;让我们一起来看看云炫AI智剪如何操作…

计算机网络期末复习-Part1

1、列举几种接入网技术&#xff1a;ADSL&#xff0c;HFC&#xff0c;FTTH&#xff0c;LAN&#xff0c;WLAN ADSL&#xff08;Asymmetric Digital Subscriber Line&#xff09;&#xff1a;非对称数字用户线路。ADSL 是一种用于通过电话线连接到互联网的技术&#xff0c;它提供…

小白该如何学习Linux操作系统?

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 Linux作为一种开源操作系…

行人检测综述 之 精华提取——图表与挑战

From Handcrafted to Deep Features for Pedestrian Detection:A Survey 从手工制作到深度特征的行人检测&#xff1a;一项调查 调查内容&#xff1a; 关于行人检测的传统算法和深度学习算法&#xff1b;关于行人检测的单光谱检测和多光谱检测&#xff1b;关于行人检测的多种数…

2023.11.09 homework (2)

【七年级上数学】 教别人也是教自己&#xff0c;总结下&#xff1a; 13&#xff09;找规律的题目&#xff0c;累加题目&#xff0c;要整体看&#xff0c;不然不容易算出来&#xff0c;求最大值&#xff0c;那么就是【最大值集群和】减去【最小集群和】就是最大值 9-12&#x…

falsk框架中安装flask-mysqldb报错解决方案

错误示例 我的是py37版本&#xff0c;无法直接安装flask-mysqldb pip install flask-mysqldb报错如下 解决方案 先去第三方库 https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient 下载mysqlclient 这个是我的版本 mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl 下…

数据权限-字段权限【实践篇-结合相关业务详细讲解如何实现】(基于若依框架)

理论看这个 https://blog.csdn.net/weixin_41842550/article/details/119890216 这里写目录标题 按照部门结构和用户数据来实现数据权限一 需要的基础数据1 系统管理--部门管理--增加如下结构2 系统管理--角色管理--增加两个角色3 系统管理--用户管理--增加7个用户 二 截图和代…

35岁危机来临前,程序员如何未雨绸缪?

程序员逼近35岁”高龄“&#xff0c;救命。。。 &#xff08;目瞪口呆)什么&#xff1f; 程序员而立之年&#xff0c;为未来担忧&#xff1f;&#xff08;双手抱头不敢置信&#xff09; 不可能&#xff01;他们明明那么努力、那么辛苦了&#xff01;&#xff01;&#xff01;&a…

SQL审计是什么意思?目的是什么?有什么好处?

很多刚入行的运维小伙伴对于SQL审计不是很了解&#xff0c;不知道其是什么意思&#xff1f;使用SQL审计的目的是什么&#xff1f;使用SQL审计的好处有哪些&#xff1f;这里我们大家就来一起聊聊&#xff0c;仅供参考哈&#xff01; SQL审计是什么意思&#xff1f; 【回答】&…

【原理篇】三、SpringBoot自动配置原理

文章目录 0、背景demo1、自动配置思路2、META-INF/spring.factories3、Redis自动配置4、自定义一个自动配置5、排除SpringBoot内置自动配置类的加载6、补充点&#xff1a;ApplicationContextAware接口 0、背景demo 用一个循序渐进的示例来体验属性配置&#xff0c;方便后面理解…

Oracle 安装及 Spring 使用 Oracle

参考内容&#xff1a; docker安装oracle数据库史上最全步骤&#xff08;带图文&#xff09; Mac下oracle数据库客户端 Docker安装Oracle docker能安装oracle吗 Batch script for add a auto-increased primary key for exist table with records Docker 安装 Oracle11g 注意&a…

用Java(C语言也可以看)实现冒泡排序和折半查找(详细过程图)+逆序数组

目录 一、冒泡排序 1.冒泡排序介绍 2.排序的思路 3.完整代码 二、折半查找 1.折半查找介绍 2.查找的思路 3.完整代码 三、逆序数组 1.逆序思路 2..完整代码 一、冒泡排序 冒泡排序是众多排序的一种&#xff0c;无论在C语言或者Java中都很常见&#xff0c;后续在数据…

浅谈智能变电站自动化系统的应用与产品选型

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;现如今&#xff0c;智能变电站发展已经成为了电力系统发展过程中的内容&#xff0c;如何提高智能变电站的运行效率也成为电力系统发展的一个重要目标&#xff0c;为了能够更好地促进电力系统安全稳定运行&#xff0c;…