Exception: Write Failed. Custom type not found: UnityEngine.Transform

Hey,

i am currently in the process of building my first multiplayer application or rather adding a spectator mode to an aleady built VR application so other people can join and just watch what the main player in VR is doing.

The application heavily relies on events to progress the story, it basically has events that set the general story state and then other events that can trigger as side-events during that particular story step.

I managed to get the tracking to work after some initial hiccups, I'm at the point where spectators can join and watch through the players eyes.

My next goal is converting all the local events to RPC's. The method i tried is implementing the IOnEventCallback interface on a helper script which is supposed to trigger all local audioevents.
The idea was to trigger the event passing over a string and a transform, telling the receiving function which sound and where to play it.
Sadly it's throwing a pretty long and (for me) cryptic error message, i am not quite sure what to change or why he is complaining about the Transform in the first place, seems like the string is working just fine.

using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using ExitGames.Client.Photon;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

public class PhotonAudioEventHandler : MonoBehaviour
{
    public const byte TriggerMasterAudioOneShotEventCode = 1;

    public static PhotonAudioEventHandler Instance;

    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Debug.LogWarning("Already got one of these, destroying myself.");
            Destroy(this);
        }
    }

    public void TriggerMasterAudioEvent(string sfxName, Transform playbackPosition)
    {
        object[] content = new object[] {sfxName, playbackPosition};
        RaiseEventOptions raiseEventOptions = new RaiseEventOptions {Receivers = ReceiverGroup.All};
        PhotonNetwork.RaiseEvent(TriggerMasterAudioOneShotEventCode, content, raiseEventOptions, SendOptions.SendReliable);
    }
}

And this is the receiver.
using System.Collections;
using System.Collections.Generic;
using ExitGames.Client.Photon;
using Photon.Realtime;
using UnityEngine;
using DarkTonic.MasterAudio;
using Photon.Pun;

public class PhotonAudioEventReceiver : MonoBehaviour, IOnEventCallback
{
    void OnEnable()
    {
        PhotonNetwork.AddCallbackTarget(this);
    }

    void OnDisable()
    {
        PhotonNetwork.AddCallbackTarget(this);
    }

    public void OnEvent(EventData photonEvent)
    {
        Debug.Log("OnEvent() was called!");
        if (photonEvent.Code == 1)
        {
            print("Received event with index 1!");
        }
    if (photonEvent.Code == PhotonAudioEventHandler.TriggerMasterAudioOneShotEventCode)
        {
            Debug.Log("Event is TriggerMasterAudioOneShotEvent.");
            object[] data = (object[])photonEvent.CustomData;
            string sfxName = data[0] as string;
            Transform playbackTransform = data[1] as Transform;

            MasterAudio.PlaySound3DAtTransformAndForget(sfxName, playbackTransform);
        }
    }

}

Then in another script i tried calling
PhotonAudioEventHandler.Instance.TriggerMasterAudioEvent(startSFX, Jan);

but ended up with an error message.

Exception: Write failed. Custom type not found: UnityEngine.Transform.

It goes on quite a bit longer with protocol18.Write statements I can't copy easily right now as i'm on the wrong computer, can post whole log if needed later. The last statement is:
"ExitGames.Client.Photon.Protocol18.WriteCustomType(ExitGames.Client.Photon.StreamBuffer stream, System.Object value, Boolean writeType)(at 'harddrive-location')

Does anyone quickly see what i'm doing wrong? Got a looming deadline, any kind of help would be highly appreciated! :)

Peace,
LaKawa

EDIT: Some typos :wink:

Comments

  • Alright, I'm at the correct PC now, here is the full error log:
    Exception: Write failed. Custom type not found: UnityEngine.Transform
    ExitGames.Client.Photon.Protocol18.WriteCustomType (ExitGames.Client.Photon.StreamBuffer stream, System.Object value, Boolean writeType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:637)
    ExitGames.Client.Photon.Protocol18.Write (ExitGames.Client.Photon.StreamBuffer stream, System.Object value, GpType gpType, Boolean writeType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:52)
    ExitGames.Client.Photon.Protocol18.Write (ExitGames.Client.Photon.StreamBuffer stream, System.Object value, Boolean writeType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:25)
    ExitGames.Client.Photon.Protocol18.WriteObjectArray (ExitGames.Client.Photon.StreamBuffer stream, IList array, Boolean writeType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:554)
    ExitGames.Client.Photon.Protocol18.Write (ExitGames.Client.Photon.StreamBuffer stream, System.Object value, GpType gpType, Boolean writeType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:112)
    ExitGames.Client.Photon.Protocol18.Write (ExitGames.Client.Photon.StreamBuffer stream, System.Object value, Boolean writeType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:25)
    ExitGames.Client.Photon.Protocol18.WriteParameterTable (ExitGames.Client.Photon.StreamBuffer stream, System.Collections.Generic.Dictionary`2 parameters) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:173)
    ExitGames.Client.Photon.Protocol18.SerializeOperationRequest (ExitGames.Client.Photon.StreamBuffer stream, Byte operationCode, System.Collections.Generic.Dictionary`2 parameters, Boolean setType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/Protocol18Write.cs:192)
    ExitGames.Client.Photon.EnetPeer.SerializeOperationToMessage (Byte opCode, System.Collections.Generic.Dictionary`2 parameters, EgMessageType messageType, Boolean encrypt) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/EnetPeer.cs:1147)
    ExitGames.Client.Photon.EnetPeer.EnqueueOperation (System.Collections.Generic.Dictionary`2 parameters, Byte opCode, SendOptions sendParams, EgMessageType messageType) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/EnetPeer.cs:974)
    ExitGames.Client.Photon.PhotonPeer.SendOperation (Byte operationCode, System.Collections.Generic.Dictionary`2 operationParameters, SendOptions sendOptions) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/PhotonPeer.cs:1861)
    Photon.Realtime.LoadBalancingPeer.OpRaiseEvent (Byte eventCode, System.Object customEventContent, Photon.Realtime.RaiseEventOptions raiseEventOptions, SendOptions sendOptions) (at Assets/Photon/PhotonRealtime/Code/LoadbalancingPeer.cs:958)
    Photon.Realtime.LoadBalancingClient.OpRaiseEvent (Byte eventCode, System.Object customEventContent, Photon.Realtime.RaiseEventOptions raiseEventOptions, SendOptions sendOptions) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:2022)
    Photon.Pun.PhotonNetwork.RaiseEvent (Byte eventCode, System.Object eventContent, Photon.Realtime.RaiseEventOptions raiseEventOptions, SendOptions sendOptions) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:2205)
    PhotonAudioEventHandler.TriggerMasterAudioEvent (System.String sfxName, UnityEngine.Transform playbackPosition) (at Assets/Scripts/Networking/PhotonAudioEventHandler.cs:32)
    TutorialController+<WaitAndPlayIntroduction>c__Iterator0.MoveNext () (at Assets/Scripts/TutorialContainer/TutorialController.cs:116)
    UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)

    I'm going to test if it's working when i try to just send the string first, that should be enough to test if general sending/receiving is working. But I am still puzzled on the Transform error... :confused:

    Peace,
    LaKawa
  • Alright, sorry for talking to myself here - found a workaround which i guess was in the error code:
    "Custom type not found." So instead of trying to send over an entire Transform i realized i could simply send a Vector3 for the position and then put that back into a Transform at the receiving end, now everything works fine.
    Next to find out how to load the correct SteamVR render models on the spectating clients :smile:

    A nice weekend to everyone!
  • Don't worry about talking to yourself. Thanks for keeping us posted. :)

    Yes, you can't send a Transform, cause Unity has no way you can re-create it as one. You can only send the values you need and assign them to an existing Transform.