2017-10-25 1 views
0

Ich arbeite an einem persönlichen Projekt von mir als etwas-was für ein Amateur bei der Programmierung. Mein Ziel bei diesem Projekt ist es, Spielern die Möglichkeit zu geben, ihre eigenen Schiffe zu bauen und anzupassen, sich dann einem öffentlichen Server anzuschließen und damit zu kämpfen.UNET: Dynamische Objekte korrekt registrieren

Der Fehler Ich erhalte als solche:

fehlgeschlagen Server-Objekt zu erzeugen, assetId = 000000000000000000000000000000e7 netId = 3 UnityEngine.Networking.NetworkIdentity: UNetStaticUpdate()

Und hier ist die relevanteste Code dafür:

public void LoadShip(Vector2 pos, string path = "save.xml",Ship oldship = null){ 
    Debug.Log ("Loading Ship!"); 
    ShipObject shipObj; 
    if (oldship != null) { 
     shipObj = oldship.shipObjectClass; 
    } else { 
     GameObject newShip = new GameObject(); 
     shipObj = newShip.AddComponent<ShipObject>(); 
     Rigidbody2D rb = newShip.AddComponent<Rigidbody2D>(); 
     rb.gravityScale = 0; 
     rb.drag = 0.1f; 
     rb.angularDrag = 0.1f; 
    } 
    shipObj.PrepareForLoad(); 
    XmlSerializer serializer = new XmlSerializer (typeof(Ship)); 
    FileStream reader = new FileStream (Path.Combine(Application.dataPath, path), FileMode.Open); 
    if (shipObj.LoadShip ((Ship)serializer.Deserialize (reader))) { 
     shipObj.gameObject.transform.position = pos; 
     reader.Close(); 
     //Give all the children rigidbodies, as they are loaded without them 
     //by default for when physics are not needed. 
     for (int i = 0; i < shipObj.transform.childCount; i++) { 
      GameObject child = shipObj.transform.GetChild (i).gameObject; 
      Rigidbody2D rb = child.AddComponent<Rigidbody2D>(); 
      rb.gravityScale = 0; 
      rb.drag = 0; 
      rb.angularDrag = 0; 
      rb.mass = 0; 
      rb.isKinematic = true; 
     } 
     shipObj.name = shipObj.ship.shipName; 
     Debug.LogError ("Ship name = " + shipObj.name); 
     ClientScene.RegisterPrefab (shipObj.gameObject, NetworkHash128.Parse (shipObj.name)); 
     GameObject prefab; 
     ClientScene.prefabs.TryGetValue (NetworkHash128.Parse (shipObj.name), out prefab); 
     if (!prefab) { 
      Debug.LogError ("Prefab not registered!"); 
      return; 
     } 
     if (shipObj.GetComponent<NetworkIdentity>() != null) { 
      Cmd_SpawnShip (prefab); 
     } else { 
      Debug.LogError ("No network identity here!"); 
     } 
    } 
} 

[Command] 
public void Cmd_SpawnShip(GameObject ship){ 
    NetworkServer.Spawn (ship); 
} 

Als Auslaufes, was Sie sehen: der Spieler ruft LoadShip() mit dem gewünschten Laich pos ition, der Weg des Schiffes, das es lädt, und möglicherweise ein bereits vorhandenes Schiff, das sie übersteuern wollen. Es lädt dann alle notwendigen Daten mit XML, fügt Physik hinzu und registriert das Prefab basierend auf dem Schiffsnamen, der in jedem Fall eindeutig sein sollte.

Sowohl das Hauptschiffsobjekt als auch alle untergeordneten Objekte (also Dinge wie Wände, Geschütze, Konsolen usw.) erhalten NetworkIdentity-Komponenten, und das Hauptschiff erhält innerhalb von LoadShip() auch eine NetworkTransform-Komponente. .

Das Schiff ist für jeden Client gut geeignet, der sich für das Laden entschieden hat, aber weder der Server noch andere Clients können es sehen und erhalten stattdessen diesen Fehler.

Ich habe versucht, dies zu beheben. Vielleicht die letzten 3 Stunden. Es war ein langer Tag, und ich vertraue darauf, dass du mir glauben wirst, wenn ich sage, dass ich sowohl google als auch stackoverflow sorgfältig nach einer bereits geposteten Antwort auf meine Frage durchsucht habe. Die häufigsten Probleme waren unter anderem: Einfach das Prefab nicht registrieren, das Prefab auf dem Server registrieren, vergessend, ihm eine assetID zu geben, und es nicht auf einem Client/etwas mit Autorität aufrufen. Ich bin mir ziemlich sicher, dass ich all diese Dinge vermieden habe und verlinke mich nicht mit den Unity-Tutorials. Ich verspreche dir, ich habe sie mehrmals gelesen.

Wenn ich nur ein Spiel mit nur einem Client hosten und auf einem Schiff spawnen, wird das Prefab nicht in der Liste der registrierten Manager des Network Managers angezeigt, obwohl ich den Netzwerkmanager auf 'Debug' gesetzt habe log level und es teilt mir mit, dass das Prefab erfolgreich registriert wurde.

Das ist über alle relevanten Informationen. Ich werde Ihnen für Ihre Zeit im Voraus danken, hoffentlich ist der Fehler, den ich gemacht habe, nicht zu eklatant offensichtlich.

Antwort

0

Die Motivation, dieses Problem noch besser anzugehen, ist aufgegangen. Nach ein paar weiteren Stunden des Forschens im Internet nach Antworten; Eureka! Die zwei Missverständnisse, die ich in meinem Code hatte, waren:

  • RegisterClientPrefab() macht nicht automatisch ein Fertighaus aus einem Gameobject für die Servernutzung erstellen. Ich bin mir nicht sicher warum ich das überhaupt gedacht habe, es scheint im Nachhinein ziemlich offensichtlich zu sein.
  • Ich nahm an, dass, wenn RegisterClientPrefab() aufgerufen wurde, was es getan hat, sagte der Server, "Hey, du. Ich habe etwas gemacht. Geh und teile es mit allen! ' Aber in Wirklichkeit teilt es dem einzelnen Kunden mit, wo er nach einer bestimmten AssetId suchen soll.

So wie ich um diese Missverständnisse Festsetzung ging, die ich einfach den Server ein Wörterbuch gab jedes Schiff AssetID und einen serialisierte byte [] Array des xml es geladen wurde aus, gefolgt von einem RegisterSpawnHandler enthält, die korrekt führen zu Laichen Die Objekte. Ich bin nicht sicher, das ist die beste Weg, es zu tun, und wenn es eine andere Form der Codierung, die einfacher/schneller ist, über ein Netzwerk als ein Byte [] -Array zu senden, aber es funktioniert für mich.

Verwandte Themen