在 Unity 中将操纵杆模块与 Arduino 结合使用
Using joystick module with Arduino in Unity
我刚刚做了一个游戏,立方体在平台上移动而没有碰撞任何障碍物。我正在尝试使用带有 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);
}
}
正如我所说,没有编译错误,它只是表现异常,所以我添加了所有需要的东西以防万一。
非常感谢您提前回答。
我解决了这个问题,这是答案;
我将 Arduino 的波特率提高到 57600(也可以是 115200,但它 运行 适合 57600)。
Arduino 脚本中的和平代码已更改;
Serial.begin(57600);
另外,我删除了所有的延迟函数,只在循环函数的最后添加了一个延迟。
移动脚本中的和平代码已更改;
public SerialPort sp = new SerialPort("COM7", 57600);
这解决了这个问题,但我不完全理解为什么它解决了,因为正如我所说,当 Arduino 插入时,它 运行 很好,当关卡重新加载时,它没有 运行 和第一个 运行 一样流畅。唯一的解决办法是再次插入 Arduino。不过现在可以正常使用了,问题解决了
我刚刚做了一个游戏,立方体在平台上移动而没有碰撞任何障碍物。我正在尝试使用带有 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);
}
}
正如我所说,没有编译错误,它只是表现异常,所以我添加了所有需要的东西以防万一。
非常感谢您提前回答。
我解决了这个问题,这是答案;
我将 Arduino 的波特率提高到 57600(也可以是 115200,但它 运行 适合 57600)。
Arduino 脚本中的和平代码已更改;
Serial.begin(57600);
另外,我删除了所有的延迟函数,只在循环函数的最后添加了一个延迟。
移动脚本中的和平代码已更改;
public SerialPort sp = new SerialPort("COM7", 57600);
这解决了这个问题,但我不完全理解为什么它解决了,因为正如我所说,当 Arduino 插入时,它 运行 很好,当关卡重新加载时,它没有 运行 和第一个 运行 一样流畅。唯一的解决办法是再次插入 Arduino。不过现在可以正常使用了,问题解决了