Getting started with Unity Runtime

Hi

I am just after a bit of a pointer in the right direction for using Speckle in Unity at runtime.

I downloaded the connector and the playground to see what to do and the runtime part seems to be marked as “obsolete” (i.e. Receiver, Sender ). But the playground runtime example uses it and is also marked obsolete (same for the instructions in the user guide Unity | Speckle Docs).

I started playing with the editor version (Speckle Receiver and Sender) and reworking that but wanted to double check if that was the best way to go.

thanks

Tony

Hi @TonyTrav

The Sender and Receiver components will soon be superseded by the SpeckleSender and SpeckleReceiver components.
Both are fully functional, but we do plan to phase out the older components eventually.

I’m yet to update the sandbox example to use the new components. (thanks for the friendly reminder to do this :sweat_smile:)

You should find that the newer SpeckleSender and SpeckleReceiver are more flexible and intuitive to use, and can be used at runtime or during editor mode.

The only feature the current SpeckleReceiver lacks over the original Receiver is support for auto-receive / subscriptions. I hope to add support soon, but is a relatively low priority item.

So, unless you require auto receive, I’d recommend using the newer components as they offer more flexibility and will be supported for longer going forward.

Hope this clears things up, and please don’t hesitate to send any other questions/feature requests my way!

1 Like

Thanks Jedd

I won’t need auto receive so I will dig into SpeckleSender and SpeckleReceiver!

Thanks again

Tony

Hi Jedd

I seem to have gotten stuck again with the Unity Speckle Receiver code.

Managed to get the Base object from speckle but things are going pear shaped with the converter.

at:

 Base b = receiveOperation.Result;

 foreach (var _ in Converter.RecursivelyConvertToNative_Enumerable(b, parent, predicate))
 {
     yield return null;
 }

The Converter.RecursivelyConvertToNative_Enumerable is giving

NullReferenceException: Object reference not set to an instance of an object
SpeckleManager+<ReceiveAndConvert_Routine>d__26.MoveNext () (at Assets/Scripts/SpeckleManager.cs:209)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <92140e5241344480af6dc0dece...

b and parent both have expected values (I think) but somewhere in the converter things are going wrong. Not sure why though…

Calling it with

 GameObject expectedParent = new GameObject();
 expectedParent.name = "TEST";
 StartCoroutine(ReceiveAndConvert_Routine(expectedParent.transform));

Thanks for any ideas!

Tony

Please can you share with me the stream you’re trying to receive.

Hi

I am using my own server. It is just a couple of primitives (sphere and cube) imported from blender.

I have been able to import it in using both the old runtime unity code and the new editor code but my version of the editor code at runtime doesn’t like it…

Thanks

TT

Without some more context about your script and the objects you are receiving, I’ll be unable to reproduce the problem.
I suggest maybe debugging the code to find which object is null.

Some suggestions.

  1. Don’t call any of the receive functions from an Awake function of another component. As the Awake function of SpeckleReceiver needs to complete first before any receive can be performed.

  2. Make sure there is a RecursiveConverter Component on the same GameObject as your SpeckleReceiver (this should get added for you, but you may want to double check)

If you can’t make progress please let me know, and I can help investigate further.

If you discover the issue, please let me know, as likely I can add some better error handling and at the very least, ensure a more meaningful error message is displayed.

Hi Jedd

Thanks again for your help.

  1. I did have it in the Start function … so I moved it and still the same error.

  2. The RecursiveReceiver is being added as expected.

  3. I uploaded the test file to the public server (and shared it with you). I get the same error with the public server. Both the local server and the public server are able to import using the playground code as expected (so I am doing something wrong somewhere!)

  4. I tried looking at the Base object and it seems to contain the expect objects (as far as I can tell). I couldn’t debug the read or the convert very much as it is in the dlls? (which don’t debug for me).

  5. Happy to share my version of the SpeckleReciever if that helps. (though it is mostly just a cut down version of the original).

Let me know what I can do to help. I am happy to continue to try and track this down myself but need a bit of guidance.

thanks

Tony

Hi @TonyTrav

I can’t reproduce any issue with the stream you have sent me.

I’ve used the below script, on a GameObject that contains a SpeckleReceiver component already.
I made my selection of your stream, and pressed play. And this appears to work fine.

[RequireComponent(typeof(SpeckleReceiver))]
public class ReceiveExample : MonoBehaviour
{

    void Start()
    {
        SpeckleReceiver  _receiver = GetComponent<SpeckleReceiver>();
        GameObject expectedParent = new GameObject();
        expectedParent.name = "TEST";
        StartCoroutine(_receiver.ReceiveAndConvert_Routine(expectedParent.transform));
    }
}

Please can I get some more information about your component (the full code snippet would be appreciated)
Does it extend SpeckleReceiver through inheritance? or does your script, like mine, sit next to SpeckleReceiver on the same GameObject?

1 Like

Thanks

Yep that works as expected!

I think my issue is related to authentication as I am not using the manager but instead using tokens.

I’ll dig through my code to see what I am doing wrong!

Thanks again for your help!

Tony

Update: working now (removed the analytics code!)

Glad to here you have something working now!

Which analytics code?
If it’s ours, then I’d be happy to look into making it work with a manually created Account object.

Hi Jedd

It seemed to be

Analytics.TrackEvent(
    client.Account,
    Analytics.Events.Receive,
    new Dictionary<string, object>()
    {
        { "mode", nameof(SpeckleReceiver) },
        {
            "sourceHostApp",
            HostApplications.GetHostAppFromString(commit?.sourceApplication).Slug
        },
        { "sourceHostAppVersion", commit?.sourceApplication ?? "" },
        { "hostPlatform", Application.platform.ToString() },
        {
            "isMultiplayer",
            commit != null && commit.authorId != client.Account.userInfo.id
        },
    }
);

causing the issues… it might be something I did or didnt do?! I am only (very) slowly building and understanding of how it all hangs together.

Tony

1 Like

I think I see the problem.

You can see on this line, we are expecting the Account object to have userInfo which perhaps your object does not?

{ "isMultiplayer", commit != null && commit.authorId != client.Account.userInfo.id }

I’ve just pushed an update (2.15.3) that may work better for you.
I’ve changed this line to not assume userInfo is set.

Tho, I haven’t fully tested to see if we are making the same assumption in other places of the code.
Hopefully this is enough to allow you to use this function.

If not, then perhaps simply setting your Account’s userInfo to a new UserInfo will help.

1 Like

Hi Jedd

That works.

Thanks

Tony

1 Like

Hi @Jedd
are there any news regarding the new SpeckleReceiver component and auto receive functionality?

Best
Ben

No updates unfortunately.

But our Client class exposes some functions to subscribe to update events. With a custom script, it should be possible to listen for these events.
This is what our older Receiver component does.