-1

I just made a game which a cube is moving on a platform without colliding any obstacles. I am trying to control the movement with a joystick module with an Arduino UNO. There is not any compilation errors and it runs well. After completing one level, it starts to lag and the smoothness just goes away (Just so you know, there is only one level and the same level keep reloading for now I just made this game for learning purposes). Also Arduino communication is closed after the level and I am sure it is closed because the lights o Arduino are reset every time level reloads So to sum up, it runs just fine when the Arduino is connected and runs without any issues just once. After the level is reloaded it becomes so laggy and it is impossible to control the character even using keyboard inputs.

This is end game script;

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);
    }
}

This is collision script;

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();
        }
    }
}

This is movement script;

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();
    }
}

This is Arduino code;

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);
  }
}

As I said there is no compilation errors, it just behaves abnormal, so I added everything needed just in case.

Many thanks for answers in advance.

PJacouF
  • 19
  • 8
  • 1
    I don't know much about joysticks, but you say it seems non-responsive and I notice you're running your serial comms at a snails pace (9600) and have delay(10) sprinkled all through the code. If I were trying for something to be responsive I would definitely opt to run serial at a much higher baud and wouldn't be telling my microcontroller to spend time spinning its wheels. – Delta_G Jul 22 '20 at 18:46
  • #Delta_G You are right mate it helped. I changed the baud rate to 57600 and deleted the all delay functions and added one delay to the end of the loop function. But I kind of did not understand why that solved the problem because as I said when I plug the Arduino in, it runs without any issues but after reloading the level it does not work as smooth as the first run. The only solution was plugging the Arduino again. But it solved the issue so that is ok and thank you. – PJacouF Jul 22 '20 at 18:58
  • I'd go with 115200 or more. Why do you think you need a delay in there at all? – Delta_G Jul 22 '20 at 18:59
  • I wonder if you're not continuing to spam serial data at the game while the game ends and then when the game restarts you have a bunch of buffered data to read. When you reset the port you clear all of that so you get one more good game and then while the game ends it builds up another full buffer. IDK, just a thought, but something that should be relatively easy to determine. – Delta_G Jul 22 '20 at 19:02
  • I tried deleting the delays but then the game did not run at all. Also yeah there is a lot of things to do to optimize it and I am gonna try all of the possibilities but now it runs well. May be I can go with 115200 and see how it performs. – PJacouF Jul 22 '20 at 19:37
  • There's a HUGE difference between "removing the delay calls" and simply deleting those lines. – Delta_G Jul 22 '20 at 20:50

1 Answers1

0

I solved the issue and here is the answer;

I increased the baud rate of Arduino to 57600 (Can be 115200 also but it runs well with 57600).

Peace of code changed in Arduino script;

Serial.begin(57600);

Also, I deleted all of the delay function and added only one delay at the end of the loop function.

Peace of code changed in movement script;

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

That solved the issue but I did not fully understand why it is solved because as I said, when the Arduino plugged in, it ran just fine and when the level is reloaded, it did not run as smooth as the first run. The only solution was plugging the Arduino again. But it works fine now so the problem is solved.

PJacouF
  • 19
  • 8