I just tried Speckle to connect grasshopper with Unity, to make a physical simulation play ground for my project. I should say that it works really smooth and wonderful, even with Several meshes and millions of Vertices.
However I’ve got couple of problems with it. Since there are tons of complicated scripts (and I’m not quite good at C#) I found it better to share them first.
The biggest problem is in the run time unity builds new game objects for each geometry in GH under the parent of each channel. I need to access each object to add a Rigidbody component and set a Mass float and a Center of mass Vector3, which should be defined in Grasshopper.
The second problem is that as a parameter changes in GH, unity builds a new set of Game Objects (channels and children). How can I make speckel rebuild the last meshes instead of building new ones?
This is a completely unexpected use case though totally valid and something the package should support. So your 3 challenges are:
- when a stream is updated, you only want the relevant values / objects to update, not for everything to be destroyed and re-instantiated
- you want your stream objects (or some portion of them) to also have rigidbody components on them
- you want values in your stream to assign into the rigid body component (or any other component for that matter)
Unfortunately, in it’s current state, SpeckleUnity doesn’t support any of these mainly because there is no “SpeckleUnity Kit” yet which adds to the stream data the specific properties Unity would need to interpret things like rigidbody mass per object. These values could then be directly edited in something like grasshopper rather than you needing to create your own arbitrary values.
I can look into this further, but I can’t say this can be supported officially any time soon.
It can be hacked together as a temporary solution however. If your values for mass and such can be found on the same speckle object as the geometry, then the changes need to only happen here:
on the method on line 190 and here
on the class on line 83.
The changes are basically to just extend the SpeckleUnityMesh class to initialise with a rigid body and assign your value in.
Regarding the preservation of gameobjects when updates are received, this is something I need to investigate more.
Does this help?
Hi @pablothedolphin, we did a lot of thinking about the update problem on the (soon to be open sourced!) Speckle GSA connector. We ended up adding tagging the objects in GSA with both the applicationID and the stream id. The stream ID is necessary so that the connector know what objects it can delete when they disappear from the stream during a future update. There is also a layer of caching, but general behaviour is:
- When a stream is updated, find all the objects that already exist in the application (unity in your case) by comparing Application IDs.
- For objects that are in the stream and in the application, just update their properties to match the stream
- Delete the objects that are tagged with the stream ID but don’t appear in the stream any more
- Add the new objects in the stream.
I hope this helps your investigations!
Thanks david that does help and I’ll be sure to keep an eye out for when it goes open source! (That must’ve been quite the uphill battle getting it approved!)
actually, the approval was straightforward. I’ve just had trouble finding someone to move the CI/CD to github
Thanks for the fast respond guys!
Well today I started working again and found a fast solution (since we need to present tomorrow! :))
I made an extra Game Object as Physics Manager and assigned an extra script to it.
1- I change my input channel names in grasshopper as Meshes, CoM and Mass, so I could easily find the parent objects and children.
2- since Speckle doesn’t send and receive float I sent them as points. At this point there’s an other difficulty here, as I want so send a list of points with the same XZY floats, speckle finds them as duplicates and removes them. so I generated a list of lines with random length (so different second points) and in Unity just used the first point (and first X point for mass). That would be great if speckle could also send floats or int.
3- In Unity I deconstructed points and made Vector3 and floats and assigned them to my mesh list.
The problem is somehow solved. but the main problem is still, that there is no way to change values from GH. There can be a way if I send the whole data back to GH in each frame and rebuild them with corrections. but I believe it would take a lot of time and calculation in each frame. for now couple of UI Sliders could be a fast solution.