Use Unity Engine as a simulator

I am making a simulator. I want to use unity as a visualiser whereas a custom physics would be my backend.

I want to publish position and rotation data to unity, I dont want the unity physics to affect the overall process.

How should I proceed? I am new to unity.

1 Like

Hello there! It mostly depends just on your backend. But in a nutshell, let’s say you have several get requests prepared on your backend. Next, you open the Unity Web Requests (Unity - Scripting API: UnityWebRequest) docs.
Here’s a small example of what can be done here:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;


public class GetObjectData : MonoBehaviour
{
   [SerializeField] private string _url = "https://your-backend-url.com/get-data";
   [SerializeField] private GameObject _targetObject;
  
   private void Start()
   {
       StartCoroutine(GetData());
   }


   private IEnumerator GetData()
   {
       UnityWebRequest webRequest = UnityWebRequest.Get(_url);
      
       yield return webRequest.SendWebRequest();


       if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError)
       {
           Debug.LogError("Error: " + webRequest.error);
       }
       else
       {
           ParseAndApplyData(webRequest.downloadHandler.text);
       }
   }


   private void ParseAndApplyData(string jsonData)
   {
       ObjectData data = JsonUtility.FromJson<ObjectData>(jsonData);


       _targetObject.transform.position = new Vector3(data.Position[0], data.Position[1], data.Position[2]);
       _targetObject.transform.rotation = Quaternion.Euler(data.Rotation[0], data.Rotation[1], data.Rotation[2]);
   }
}


[System.Serializable]
public class ObjectData
{
   public float[] Position; 
   public float[] Rotation; 
}


Here the _targetObject is an object on scene you will apply your data to. Change the url accordingly as well.
Also, before testing in Unity, you’d better test the requests in Postman, that will save you time.

And here is the example data in json that can get back from your backend.

{
	"position": [1.0, 2.0, 3.0],
	"rotation": [0.0, 90.0, 0.0]
}

and if its realtime data, then look into sockets/udp.

you can rotate/move gameobjects with transform,

i’ve tested this with a MatLab simulation backend, used UDP for sending data (from sim to unity and from unity to sim (when user controls the sim).

and had separate “heartbeat” application to send 1ms ticks
(since same unity build was struggling to send accurate ticks for simulator…) *but you might not need this.

Thanks for your reply,

I am connected to MATLAB via ROS2

I am using the following code to update the position and orientation,


        float velocity_x = msg.velocity[0];
        float velocity_z = msg.velocity[1];

        float heading = Mathf.Atan2(velocity_z, velocity_x);

        rotation = Quaternion.EulerAngles(-msg.euler_angles[1], msg.euler_angles[2], -msg.euler_angles[0]);

        position.x = msg.position[1];
        position.y = -(msg.position[2] - 2.0f);
        position.z = msg.position[0];
        
        main_art_body.TeleportRoot(position, rotation);
    }

However, whenever I update the the transform, the robot starts shaking.

does it have physics joints still?
are the received values correct?

gimbal lock was one issue i had… cant remember if it was due to mixing some joints/physics in the mode.
but check for that, i think i had to rotate different axis separately or through parent objects in some cases.

1.) The body type is ArticulationBody, so yeah, it does have physics
2.) Received Values are correct.
3.) I don’t this it’s gimbal lock.