Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >接收连续输入电话的最佳方式?

接收连续输入电话的最佳方式?
EN

Stack Overflow用户
提问于 2021-06-03 14:37:35
回答 1查看 46关注 0票数 2

我是一个统一的初学者,虽然我没有太多的编码经验,但我知道我的代码一团糟。

所以,事情是这样的:当我点击鼠标(0)时,我插入了一个特定的功能,允许播放器从它的位置到"Object1“。在单击时,一个时间计数器启动,在2秒内,如果我再次单击de鼠标(0),它将将播放机升级到第二次,现在是"Object2“。我应用这个逻辑的一种方式,允许用户4次4次在4个不同的位置,如果每个输入是在5秒以下的球员。

经过大量的努力,我找到了一种让它工作的方法,它是功能性的,但代价是许多布尔人和ifs语句,一个完整而可怕的Spaguetti。所以我的问题是,我怎样才能把这整件事弄得更干净、更有效率?在这种情况下,我可以使用什么代码结构来提高整个程序的可读性,并切断大量的布尔和条件词?提前谢谢大家!

下面是代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [SerializeField] private Transform cube1;
    [SerializeField] private Transform cube2;
    [SerializeField] private Transform cube3;
    [SerializeField] private Transform cube4;
    private float timer;
    private bool canCount;
    private bool click1;
    private bool click2;
    private bool click3;
    private bool click4;
    private bool lerp1;
    private bool lerp2;
    private bool lerp3;
    private bool lerp4;

private void CountDown()
{
    if (canCount)
    {
        timer += Time.deltaTime;
        if (timer >= 2)
        {
            canCount = false;
            Debug.Log("Timer End");
        }
    }
}
private void Lerp()
{
    if (lerp1)
    {
        transform.position = Vector3.Lerp(transform.position, cube1.position, Time.deltaTime * 10);
    }
    if (lerp2)
    {
        transform.position = Vector3.Lerp(transform.position, cube2.position, Time.deltaTime * 10);
    }
    if (lerp3)
    {
        transform.position = Vector3.Lerp(transform.position, cube3.position, Time.deltaTime * 10);
    }
    if (lerp4)
    {
        transform.position = Vector3.Lerp(transform.position, cube4.position, Time.deltaTime * 10);
    }
}

private void Update()
{
    CountDown();
    Lerp();

    if (Input.GetMouseButtonDown(0))
    {
        if (!canCount)
        {
            click1 = true;
            click2 = false;
            click3 = false;
            click4 = false;
            lerp2 = false;
            lerp3 = false;
            lerp4 = false;

            if (click1)
            {
                click1 = false;
                click2 = true;
                lerp4 = false;
                lerp1 = true;
                timer = 0;
                canCount = true;
            }

            else if (click2 && canCount)
            {
                click2 = false;
                click3 = true;
                lerp1 = false;
                lerp2 = true;
                timer = 0;
            }
            else if (click3 && canCount)
            {
                click3 = false;
                click4 = true;
                lerp2 = false;
                lerp3 = true;
                timer = 0;
            }
            else if (click4 && canCount)
            {
                click4 = false;
                click1 = true;
                lerp3 = false;
                lerp4 = true;
                timer = 0;
            }
        }
        else
        {
            if (click1)
            {
                click1 = false;
                click2 = true;
                lerp4 = false;
                lerp1 = true;
                timer = 0;
                canCount = true;
            }

            else if (click2)
            {
                click2 = false;
                click3 = true;
                lerp1 = false;
                lerp2 = true;
                timer = 0;
            }
            else if (click3)
            {
                click3 = false;
                click4 = true;
                lerp2 = false;
                lerp3 = true;
                timer = 0;
            }
            else if (click4)
            {
                click4 = false;
                click1 = true;
                lerp3 = false;
                lerp4 = true;
                timer = 0;
            }
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-03 16:29:20

下面的代码应该允许您设置无限多个要移动的对象,以便为每个对象设置唯一的等待时间,直到播放机再次单击移动到下一个对象。如果用户未能在给定的时间内单击,则下一次单击将再次移动到第一个对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using UnityEngine;
using System.Collections.Generic;
using System.Collections;

/// <summary>
/// Holds data to a goal target and how long the player has to click to move towards it
/// </summary>
[System.Serializable]
public class CountdownLerpData
{
    public float timeToWaitForClick = 0.0f;
    public Transform destination = null;
}

public class YourScript : MonoBehaviour
{
    [SerializeField] private List<CountdownLerpData> LerpDestinations = new List<CountdownLerpData>();

    private Coroutine ExtraMouseClicks = null;
    private Coroutine MoveToDestination = null;

    // distance until our object has reached our goal point
    private const float DISTANCE_EPSILON = 0.001f;

    // the speed at which our object moves to a goal position
    private float moveSpeed = 10f;

    private void Update()
    {
        // just use update for your first click input, any successive clicks are handled by the Coroutine
        if (Input.GetMouseButtonDown(0) && ExtraMouseClicks == null)
            ExtraMouseClicks = StartCoroutine(MoveAndDetectMouseClicks(0));
    }

    /// <summary>
    /// Will start a movement coroutine and wait until the time to click is exceeded or
    /// when the player clicks, it will start a new coroutine
    /// </summary>
    /// <param name="idx"></param>
    /// <returns></returns>
    private IEnumerator MoveAndDetectMouseClicks(int idx)
    {
        // we wait for the next frame to assure we do NOT use the same mouse click event
        yield return null;

        // we exceeded our container, so exit the coroutine and set it to null
        if (idx >= LerpDestinations.Count)
        {
            ExtraMouseClicks = null;
            yield break;
        }

        float currentTimer = 0.0f;      // the time to wait for our next click
        bool hasMouseClick = false;     // flag to determine if the user clicked

        // start a new Coroutine for the motion - stop it if it is ongoing
        if (MoveToDestination != null)
            StopCoroutine(MoveToDestination);

        // start it with our current index
        MoveToDestination = StartCoroutine(MoveTowardsDestination(LerpDestinations[idx].destination.position));

        // now wait our time to determine if another mouse click occurs, if it does, then increment our counter
        while (currentTimer <= LerpDestinations[idx].timeToWaitForClick && !hasMouseClick)
        {
            // if we have a mouse click, then 
            if (Input.GetMouseButtonDown(0) && !hasMouseClick)
            {
                // the user clicked, so set our flag to true
                hasMouseClick = true;

                // assign the coroutine
                ExtraMouseClicks = StartCoroutine(MoveAndDetectMouseClicks(idx + 1));
            }

            // increase our time since the last frame
            currentTimer += Time.deltaTime;

            yield return null;
        }

        // the user missed the window to click again, so set the reference back to null
        if (!hasMouseClick)
            ExtraMouseClicks = null;
    }

    /// <summary>
    /// Moves your object to a goal location by moveSpeed speed
    /// </summary>
    /// <param name="goalPosition"></param>
    /// <returns></returns>
    private IEnumerator MoveTowardsDestination(Vector3 goalPosition)
    {
        // now lerp until we reach our destination
        while (Vector3.Distance(transform.position, goalPosition) > DISTANCE_EPSILON)
        {
            transform.position = Vector3.MoveTowards(transform.position, goalPosition, moveSpeed * Time.deltaTime);
            yield return null;
        }
    }
}

我的方法将不再存储多次点击和延迟,这是非常令人头痛的,我的方法将删除单独跟踪这些数据。相反,您将有一个名为List的对象的CountdownLerpData,它包含两个字段。第一个字段是timeToWaitForClick,它是程序在单击发生后等待的时间,以决定单击是移动到列表中的下一个对象,还是移回第一个对象。第二个字段是destination,它是此时要移动到的对象的Transform

当用户首先单击时,它将通过对象数据的List启动一个看似合理的反应链。最初的单击将启动所谓的Coroutine,它可以简单地定义为一个特殊的函数,允许在多个帧上完成一个较大任务的小部分。

一旦您启动倒计时Coroutine,它将启动MoveTowardsDestination Coroutine,它只会将对象移动到倒计时Coroutine所在的索引的目标对象。如果用户碰巧在所需的时间间隔内单击,它将再次调用相同的Coroutine,但是现在索引增加了1,以移动到列表中的下一个对象。如果它碰巧达到或超过了List,它将退出Coroutine

让我知道这对你有什么好处,或者这不是你想要的。如果我的实现不是您想要的,我可以调整答案。如果你对它的工作方式或原因有任何疑问的话,也可以评论一下。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67829446

复制
相关文章
如何使用AndroidStudio将开源项目library发布到jcenter
我相信技术爱好者都喜欢开源,也都喜欢分享,随着技术的慢慢提高,很多开发者想将自己的开源类库分享出来,对于Android开发者来说,以前使用Eclipse开发时,直接引用类库或者打成jar包分享出来就行,现在使用AndroidStudio开发,引用类库直接在build.gradle文件里面添加一行引用代码即可。我们带着问题进入分析。 为什么只需要添加一行引用代码即可 AndroidStudio是从Maven Repository服务器下载类库的。基本上有jcenter和Maven Central这两个服务器用
非著名程序员
2018/02/02
1.1K0
如何使用AndroidStudio将开源项目library发布到jcenter
将XML导入到对象中
注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码, IRIS将使用前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。
用户7741497
2022/07/04
1.6K0
如何将App程序发布到苹果App Store
将App程序发布到苹果App Store的具体步骤如下: 1、首先登录开发者中心进入证书页面。点击证书、ID及配件文件,进入设置。
iOS程序应用
2023/04/13
4410
如何将App程序发布到苹果App Store
数据传输 | 如何使用 DTLE 将 Oracle 数据同步到 MySQL
爱可生测试团队成员,主要负责 DTLE 开源项目相关测试任务,擅长 Python 自动化测试开发。
爱可生开源社区
2022/04/06
1.2K0
如何将App程序发布到苹果App Store
5、点击右下角+ADD选择,下拉选择发布证书,输入证书名称、邮箱、密码,点击ok创建。
iOS Magician
2023/03/22
7090
如何将App程序发布到苹果App Store
将项目发布到jcenter仓库
将项目发布到jcenter仓库可以方便他人直接使用,下面总结一下流程和可能遇到的问题
杜金房
2020/12/21
1.2K0
将项目发布到jcenter仓库
如何使用Restic Backup Client将数据备份到对象存储服务
Restic是一个用Go语言编写,安全且高效的备份客户端。它可以将本地文件备份到许多不同的后端存储库,例如本地目录,SFTP服务器或对象存储服务。
乌鸦
2018/07/20
3.9K1
如何将gradle插件发布到插件门户网站
注册地址:https://plugins.gradle.org/user/register
乱码三千
2021/07/29
1.4K0
如何将gradle插件发布到插件门户网站
Gradle 如何配置将编译的 JAR 发布到 Archiva 中
在这里,你需要指定 archiva 的用户名和密码,这个用户能够具有 archiva 的相关权限。
HoneyMoose
2019/10/18
1K0
如何将 Text, XML, CSV 数据文件导入 MySQL
原文出处: freenik@Jianshu 将 外部数据导入(import)数据库是在数据库应用中一个很常见的需求。其实这就是在数据的管理和操作中的ETL (Extract, transform,
wangxl
2018/03/08
5.9K0
如何将 Text, XML, CSV 数据文件导入 MySQL
Maven 如何将本地的项目发布到 Archiva 中
为了一些私有的项目发布到公司内部的 Archiva 中,如何使用 Maven 进行发布。
HoneyMoose
2020/04/11
2.1K0
Maven 如何将本地的项目发布到 Archiva 中
Gradle 如何配置将编译的 JAR 发布到 Archiva 中
在这里,你需要指定 archiva 的用户名和密码,这个用户能够具有 archiva 的相关权限。
HoneyMoose
2019/10/17
1.2K0
如何使用Hexo发布博客到GitHub Pages
你应该会在GitHub Pages看到你的博客了,地址为http://****.github.io。
fanzhh
2019/08/20
6540
ajax ---- json 和 xml 区别
(1).XML的优缺点 <1>.XML的优点   A.格式统一,符合标准;   B.容易与其他系统进行远程交互,数据共享比较方便。 <2>.XML的缺点   A.XML文件庞大,文件格式复杂,传输占带宽;   B.服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;   C.客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;   D.服务器端和客户端解析XML花费较多的资源和时间。
小蔚
2019/09/11
1.3K0
如何将workerman部署到windows服务器上面
一直以来对php的即时通讯都很好奇,其实是不知道应该怎么来实现,后来了解到了swoole和workerman这两个神器,他们都可以实现即时通信的功能,其中swoole是C语言编写的php扩展,其配置起来比较麻烦,但是性能还是很强悍的这些可以自己去官网上面搜,还有一个就是workerman框架啦!它确实是使用php写出来的框架而且使用的就是php socket中的东西。如果是将项目项目布置到linux服务器的话我觉的两者都可以,但是如果你是使用的windows服务器的话那就面临着一个困难———swoole不支持windows环境,当然如果非要布置的话使用docker应该也可以,但是总觉的有些不伦不类的感觉(不是说docker不伦不类,docker确实强悍),那么我们怎么办呢??这个时候就凸显出workerman的优势啦!它可以在windows系统运行下载这个聊天室项目
码缘
2019/09/11
3.8K0
如何将workerman部署到windows服务器上面
dataTables 使用ajax 和服务器处理 获取数据
Datatables是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。 官网:https://datatables.net/ 中文网:https://datatables.club/
Alone88
2019/10/22
5.2K0
将Hexo部署到云服务器(使用宝塔面板)
本来Hexo是部署在GitHub上的(可以看我之前文章Hexo搭建静态博客 - Taitres' Blog包括了Hexo的基本使用),但是访问太慢了,并且想折腾一下,还想整个个人云盘,就买了个腾讯云的轻量应用服务器,把Hexo搬过来了,看了很多文章,记录下最终的解决方案。
Taitres
2021/05/13
14.1K4
将项目发布到 Homebrew 官方仓库
Homebrew 标榜自己是 “macOS(或 Linux)缺失的软件包的管理器”,使用 macOS 作为开发终端的用户,往往绕不过 brew 这个软件包管理工具。确实在 macOS 上没有比 brew 更好用的软件包管理工具了,基本上想用的 CLI 工具,只需一行命令就可一键安装,非常的方便。记得去年博主还写过一篇 《Golang 装逼指南 Ⅱ:在 Homwebrew 上发布 Golang 项目》,当时只是介绍了如何将 Golang 开发的 CLI 工具发布到自建的 homebrew-tap 上。本文则是讲解如何将自己开发的软件,推送到官方的 homebrew-core[1] 仓库中,使用像 brew install kubecm 这样的命令即可完成安装。
郭旭东
2020/12/30
1.7K0
将项目发布到 Homebrew 官方仓库
【前端系列-1】ajax与Springboot通信将数据库数据渲染到前端表格
jQuery对原生js进行了大量封装,让我们使用起来更加方便,尤其ajax。这里就对jQuery的ajax做一个总结。
云深i不知处
2020/09/16
2.5K0
php与Ajax(四)—xml与json数据格式
因为json数据是原生态数据,因此这种数据格式很稳定,而且描述能力强,我们建议大家使用json格式
致Great
2023/08/26
1920

相似问题

无法在wxPython虚拟网格中添加列

14

无法使用wxpython

10

无法退出wxpython

25

wxPython持续更新面板

11

WxPython StaticText动态更新

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文