【问题标题】:Using joystick module with Arduino in Unity在 Unity 中使用带有 Arduino 的操纵杆模块
【发布时间】:2020-11-12 05:50:38
【问题描述】:

我刚刚做了一个游戏,一个立方体在平台上移动而没有碰撞任何障碍物。我正在尝试使用带有 Arduino UNO 的操纵杆模块来控制运动。没有任何编译错误并且运行良好。完成一个关卡后,它开始滞后,平滑度消失(你知道,只有一个关卡,同一关卡一直在重新加载,我只是为了学习目的而制作了这个游戏)。此外,Arduino 通信在关卡后关闭,我确信它已关闭,因为每次重新加载关卡时 Arduino 的灯都会重置所以总而言之,当 Arduino 连接时它运行得很好,并且只运行一次就没有任何问题。关卡重新加载后变得非常滞后,即使使用键盘输入也无法控制角色。

这是游戏结束脚本;

using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.IO.Ports;

public class GameManager : MonoBehaviour
{
    public Text scoreEdit;
    public GameObject overText;
    bool gameHasEnded = false;
    public GameObject completeLevelUI;

    public PlayerMovement movementC;


    public void CompleteLevel()
    {
        completeLevelUI.SetActive(true);
    }

    public void EndGame()
    {
        if (gameHasEnded == false)
        {
            gameHasEnded = true;
            Debug.Log("Game Over");
            Over();
            Invoke("Restart", 4f);
            movementC.CloseCom();
        }
    }

    void Restart()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    public void Over()
    {
        scoreEdit.color = Color.red;
        overText.SetActive(true);
    }
}

这是碰撞脚本;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;


public class PlayerCollision : MonoBehaviour
{
    public PlayerMovement movement;


    void OnCollisionEnter(Collision collisionInfo)
    {
        if (collisionInfo.collider.tag == "Obstacle")
        {
            movement.enabled = false;
            FindObjectOfType<GameManager>().EndGame();
        }
    }
}

这是移动脚本;

using System.Collections;
using UnityEngine;
using System.IO.Ports;

public class PlayerMovement : MonoBehaviour
{
    public Rigidbody rb;

    public float forwardForce = 4000f;
    public float sidewaysForce = 100f;
    public int CMD;

    public SerialPort sp = new SerialPort("COM7", 9600);

    // Start is called before the first frame update
    void Start()
    {
        sp.Open();
        sp.ReadTimeout = 1;
    }

    void FixedUpdate()
    {
        if (sp.IsOpen)
        {
            try
            {
                ReadCom();
                Move();
            }
            catch(System.Exception)
            {

            }
        }
        else
        {
            Move();
        }
    }

    // Update is called once per frame
    void Move()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime);

        if (Input.GetKey("d") || CMD == 6)
        {
            rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("a") || CMD == 4)
        {
            rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("w") || CMD == 8)
        {
            rb.AddForce(0, sidewaysForce * Time.deltaTime, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("s") || CMD == 2)
        {
            rb.AddForce(0, -sidewaysForce * Time.deltaTime, 0, ForceMode.VelocityChange);
        }

        if (rb.position.y < -1f)
        {
            FindObjectOfType<GameManager>().EndGame();
        }
    }

    void ReadCom()
    {
        CMD = sp.ReadByte();
    }

    public void CloseCom()
    {
        sp.Close();
    }
}

这是 Arduino 代码;

const int x = A0;
const int y = A1;
const int button = 7;

int curX = 0;
int curY = 0;
int curB = 1;

void setup() 
{
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(button, INPUT);
 
  Serial.begin(9600);
}

void loop() 
{
  curX = analogRead(x);
  curY = analogRead(y);
  curB = digitalRead(button);

 
  if(analogRead(x) >=1000)
  {
    Serial.write(6);
    Serial.flush();
    //Serial.println(6);
    delay(10);
  }else if(analogRead(x) <= 10)
  {
    Serial.write(4);
    Serial.flush();
    //Serial.println(4);
    delay(10);
  }else if (analogRead(y) <= 10)
  {
    Serial.write(8);
    Serial.flush();
    //Serialprintln(8);
    delay(10);
  }else if (analogRead(y) >= 1000)
  {
    Serial.write(2);
    Serial.flush();
    //Serialprintln(2);
    delay(10);
  }else 
  {
    Serial.write(0);
    Serial.flush();
    //Serial.println(0);
    delay(10);
  }
}

正如我所说的没有编译错误,它只是表现异常,所以我添加了所有需要的东西以防万一。

非常感谢您提前回答。

【问题讨论】:

  • 我对操纵杆了解不多,但你说它似乎没有响应,我注意到你正在以蜗牛的速度运行串行通讯 (9600) 并且延迟 (10)通过代码。如果我试图让某些东西做出响应,我肯定会选择以更高的波特率运行串行,并且不会告诉我的微控制器花时间旋转它的轮子。
  • #Delta_G 你是对的,它有帮助。我将波特率更改为 57600 并删除了所有延迟功能,并在循环功能结束时添加了一个延迟。但我有点不明白为什么这能解决问题,因为正如我所说,当我插入 Arduino 时,它运行没有任何问题,但在重新加载关卡后,它不像第一次运行那样流畅。唯一的解决方案是再次插入 Arduino。但它解决了这个问题,所以没关系,谢谢。
  • 我会选择 115200 或更多。为什么你认为你需要延迟呢?
  • 我想知道你是否没有在游戏结束时继续在游戏中发送垃圾串行数据,然后在游戏重新开始时你有一堆缓冲数据要读取。当您重置端口时,您会清除所有这些,以便您获得更多好游戏,然后当游戏结束时,它会建立另一个完整的缓冲区。 IDK,只是一个想法,但应该相对容易确定。
  • 我尝试删除延迟,但游戏根本没有运行。是的,还有很多事情要做来优化它,我会尝试所有的可能性,但现在它运行良好。也许我可以用 115200 去看看它的表现如何。

标签: c# unity3d arduino hardware joystick


【解决方案1】:

我解决了这个问题,这是答案;

我将 Arduino 的波特率提高到 57600(也可以是 115200,但在 57600 上运行良好)。

在 Arduino 脚本中更改了代码和平;

Serial.begin(57600);

另外,我删除了所有的延迟函数,只在循环函数的末尾添加了一个延迟。

在移动脚本中更改了代码和平;

public SerialPort sp = new SerialPort("COM7", 57600);

这解决了这个问题,但我不完全明白为什么它会解决,因为正如我所说,当 Arduino 插入时,它运行得很好,当关卡重新加载时,它没有第一次运行那么流畅。唯一的解决方案是再次插入 Arduino。但是现在它工作正常,所以问题解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多