Jump to content
Unity Insider Forum

UNET 5.1.1


Tixewi

Recommended Posts

Hallo zusammen,

 

ich weis nicht ob sich schon jemand mit der Materie befasst hat, jedoch habe ich Probleme mit dem alten Networking System und möchte daher auf das neue Umsteigen. Soweit so gut.

 

Wenn ich nun ein Prefab habe das ich instantiieren möchte, funktioniert das auch alles super.

Aber wenn man abseits von dem Standard "Spielzeug" was Unity da mitgeliefert hat das ganze manuell per Code aufsetzten will funktioniert nichts.

 

Der Server kann theoretisch schon spawnen was er will, und das funktioniert auch. Aber ich kann doch nicht immer dem Client per Command sagen Erstelle mal das Objekt. Zumal der Client das ja nicht mehr mal bewegen kann.

 

Erstelle ich Manuell einen Server kann der Client auf einmal nicht mehr auf diesen Connecten.

 

Es gibt bereits auf YouTube eine Tutorial Serie, die mich nicht mal ansatzweise weiter bring.

 

Die Unity Scripting Reference ist auch nur sehr beschränkt hilfreich,

 

Falls also jemand hier bereits Erfahrung mit UNET gesammelt hat, wäre es toll hier ein paar Ansätze zu erhalten.

 

Ich bedanke mich schon ein Mal.

 

Mit freundlichen Grüßen

 

Tixewi

 

p.s. im offiziellen Unity Forum habe ich mich auch schon umgeschaut.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was die sache ungemein erleichert ist vom NetworkManager abzuleiten.

 

Zum Spawnen von Objekten machst du GameObject.Instantiate und dann mit dem erzeugten Objekt NetworkServer.Spawn.

 

Achtung damit der Spieler das Playerobjekt noch verwenden kann musst du hier nach dem erzeugen nicht NetworkServer.Spawn sondern NetworkServer.AddPlayerForConnection machen. Dies am besten in der überschriebenen OnServerAddPlayer Methode vom NetworkManager.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mir hilft dieser Teil:

http://docs.unity3d.com/Manual/UNetUsingHLAPI.html

 

Hier findest du sample projects:

http://forum.unity3d.com/forums/multiplayer-networking.26/

 

Wie Mabenan schon gesagt hat, ist der Gedanke, dass man GameObjects auf dem Server instanziiert und mit NetworkServer.Spawn diese Instanziierung auf die Clients überträgt. Steht erklärt in der Manual. =)

 

Nervig finde ich, dass die ganze Command Mechanik nur auf dem Player GameObject funktioniert. Ein separates GameObject nur für Input ist somit pasee.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hätte dir bei der alten Networking helfen können, aber bei der neuen habe mich nicht noch nicht rein gehauen. Ich will auch erst bisschen warten. Will kein Game damit starten und falls Bugs auftauchen stehe ich doof da.

 

Aber ich gebe mal dir eine Idee zu deinem Problem, aber als Autoritativer Server:

Falls das dir nichts sagt ignoriere das dann.

Willst du auf den Server und auf den Clients etwas erstellen?

Willst du das die Clients das eventuell steuern können?

Wenn ja, dann zeige ich, wie ich meistens so etwas bei einem Autoritativer Server mache vom Konzept her. Wir nehmen als Beispiel ein Auto.

  1. Erstelle per Instantiate über den Server das Auto
  2. Schicke an alle Clients (per RPC, Command was auch immer): "Erstelle das Auto".
  3. Da das Auto sehr wahrscheinlich ein Script hat, wie man ihn fährt und (wichtig!) welcher Spieler ihn gerade steuert, sollte erst erst mal kein Benutzer haben. Also Owner = NULL;
  4. Sobald ein Spieler es verwendet sollte er den als owner zu gewiesen bekommen. Das schickt der Server an alle.

Du kannst das auch dann anders machen, dass der Client alles schickt, dass er der owner ist und fährt usw.

Im Endeffekt mache ich damit doch das hier was du sagtest: "Aber ich kann doch nicht immer dem Client per Command sagen Erstelle mal das Objekt."

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmm also mit dem alten habe ich es bisher so, das des Hauptobjekt vom Spieler erstellt und berechnet (Physic) wird. Die Stats werden auf dem Server berechnet und dann komplett an alle Clients Synchronisiert. Also Server bekommt Meldung Spieler X -10 HitPoints. Dann sendet Server z.B. 90 HitPoints an die Clients.

 

Das Problem ist, das das alte Networking System Network.Instantiate nicht korrekt ausführt. Objekte werden teilweise nie erzeugt von Spielern die später kommen. Würde das nicht passieren, würde ich auch nicht wechseln wollen.

 

Kann soetwas passieren, wenn ich die nViewID verwende bevor das Obj aus dem Buffer Instantiated worden is?

 

Weil Zeitweise hat das alles perfekt geklappt. Das alte Networking System ist manchmal schon etwas komisch.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo. ich finde das neue Unet nicht schlecht, aber mit Instantiate hat es so seine Probleme, ich bekomme es nicht hin, das der nicht locale Player "Client" , wenn er etwas Crafted z.b. den Boden eines Hauses, das der andere Player das sieht, wenn es platziert wurde. Aber der Player der das Spiel hosten tut ,der kann es platzieren und das sieht der andere Spieler dann auch, ka wieso.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo. ich finde das neue Unet nicht schlecht, aber mit Instantiate hat es so seine Probleme, ich bekomme es nicht hin, das der nicht locale Player "Client" , wenn er etwas Crafted z.b. den Boden eines Hauses, das der andere Player das sieht, wenn es platziert wurde. Aber der Player der das Spiel hosten tut ,der kann es platzieren und das sieht der andere Spieler dann auch, ka wieso.

 

Da musst du einen Command senden oder RPC nutzen um dem Server mitzuteilen, dass er das instanziieren und im Netzwerk spawnen soll. Auf dem Client solltest du keine Netzwerkobjekte instanziieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Da musst du einen Command senden oder RPC nutzen um dem Server mitzuteilen, dass er das instanziieren und im Netzwerk spawnen soll. Auf dem Client solltest du keine Netzwerkobjekte instanziieren.

 

[Client]

void IstClient()

{

GameObject a = (GameObject)Instantiate(suelomaderaprefab, suelomaderaspawn.transform.position, Quaternion.identity);

NetworkServer.Spawn(a, assetId);

 

InventarioScript.Suelo -= 1;

Debug.Log ("Ist Client");

}

 

[Command]

void CmdIstServer()

{

GameObject a = (GameObject)Instantiate(suelomaderaprefab, suelomaderaspawn.transform.position, Quaternion.identity);

NetworkServer.Spawn(a, assetId);

 

InventarioScript.Suelo -= 1;

Debug.Log ("Ist Server");

}

}

aber bringt nichts nur der es Hostet kann es platzieren, und so das es auch andere Spieler sehen, aber der Spieler der neu dazu kommt, kann es platzieren und dieser sieht es auch, nur alle anderen nicht ;)

IstClient ist richtig, aber IstServer nicht, also bitte nicht beachten, der obere ist der der das spiel hostet der untere der eigentliche Client!

Link zu diesem Kommentar
Auf anderen Seiten teilen

[Client]

void IstClient()

{

GameObject a = (GameObject)Instantiate(suelomaderaprefab, suelomaderaspawn.transform.position, Quaternion.identity);

NetworkServer.Spawn(a, assetId);

 

InventarioScript.Suelo -= 1;

Debug.Log ("Ist Client");

}

 

[Command]

void CmdIstServer()

{

GameObject a = (GameObject)Instantiate(suelomaderaprefab, suelomaderaspawn.transform.position, Quaternion.identity);

NetworkServer.Spawn(a, assetId);

 

InventarioScript.Suelo -= 1;

Debug.Log ("Ist Server");

}

}

aber bringt nichts nur der es Hostet kann es platzieren, und so das es auch andere Spieler sehen, aber der Spieler der neu dazu kommt, kann es platzieren und dieser sieht es auch, nur alle anderen nicht ;)

IstClient ist richtig, aber IstServer nicht, also bitte nicht beachten, der obere ist der der das spiel hostet der untere der eigentliche Client!

 

http://docs.unity3d....kBehaviour.html

Der [Client] Tag ist für Code, der nur auf dem Client ausgeführt wird.

 

Nehmen wir an, dass du das Script auf deinem Player Objekt hast (Beim Networkmanager das Player Feld).

Zudem muss das zu spawnende Prefab eine NetworkIdentity Component haben und unter den Spawnable Prefabs im Networkmanager sein.

 

Dann kannst du wie folgt sachen spawnen:

 

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class MySpawner : NetworkBehaviour {
public GameObject prefabToSpawn;
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
 if(isLocalPlayer)//is only set on the player object
 {
  //if this is the player object
  if(Input.GetKeyDown(KeyCode.Space))
  {
//and the player presses space
CmdSpawnPrefab();
  }
 }
}

[Command]
void CmdSpawnPrefab(){
 GameObject instantiatedObject = (GameObject)GameObject.Instantiate(prefabToSpawn,transform.position+transform.up*5+Random.onUnitSphere*3,Quaternion.identity);
 NetworkServer.Spawn(instantiatedObject);
}
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

<p>

http://docs.unity3d....kBehaviour.html Der [Client] Tag ist für Code, der nur auf dem Client ausgeführt wird. Nehmen wir an, dass du das Script auf deinem Player Objekt hast (Beim Networkmanager das Player Feld). Zudem muss das zu spawnende Prefab eine NetworkIdentity Component haben und unter den Spawnable Prefabs im Networkmanager sein. Dann kannst du wie folgt sachen spawnen:
 using UnityEngine; using UnityEngine.Networking; using System.Collections; public class MySpawner : NetworkBehaviour { public GameObject prefabToSpawn; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if(isLocalPlayer)//is only set on the player object { //if this is the player object if(Input.GetKeyDown(KeyCode.Space)) { //and the player presses space CmdSpawnPrefab(); } } } [Command] void CmdSpawnPrefab(){ GameObject instantiatedObject = (GameObject)GameObject.Instantiate(prefabToSpawn,transform.position+transform.up*5+Random.onUnitSphere*3,Quaternion.identity); NetworkServer.Spawn(instantiatedObject); } } 

</p>

<p> </p>

Danke, hat nach ein paar Änderungen dann doch geklappt, so war fast alles schon ok, nur das IsLocalPlayer hatte gefällt! Aber es ist ja immer so, ein Fehler ist behoben, und ein neuer ist da, jetzt klappt das, das alle Spieler es sehen was gespawnt wird, aber nur derjenige der des Spiel hosten tut, platziert das Objekt an der stelle, wo das &quot;spawnprefab&quot; grün wird, wenn man dann auf den Mouse-Button klickt, der Spieler also der in das Spiel beigetreten ist der kann es auch spawnen aber nicht da wo das &quot;spawnprefab&quot; mit der Mouse Plaziert ist sondern daneben, obwohl der Code der gleiche ist ,wie von dem der das Spiel hostet.

 

<div>GameObject P1 = (GameObject)Instantiate(bodenprefab, bodenspawn.transform.position,bodenspawn.transform.rotation)as GameObject;</div>

<div>NetworkServer.Spawn(P1,bodenId);</div>

<div>InventarioScript.boden -= 1;</div>

Link zu diesem Kommentar
Auf anderen Seiten teilen

Und wenn ich jetzt einfach nur den Inhalt einer Variablen senden möchte? Also würde gerne beide Richtungen kennen...Server->Client und Client-> Server. RPC´s sind ja jetzt "obsolete".... =P Für die Reference bin ich wohl zu deppert um das zu verstehen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Und wenn ich jetzt einfach nur den Inhalt einer Variablen senden möchte? Also würde gerne beide Richtungen kennen...Server->Client und Client-> Server. RPC´s sind ja jetzt "obsolete".... =P Für die Reference bin ich wohl zu deppert um das zu verstehen.

 

 

Hallo, das machst du dann über oder mit SyncVar !

 

using UnityEngine.Networking;

class Combat : NetworkBehaviour

{

[syncVar]

public int Health;

 

// generated property

public int HealthSync {

get { return Health; }

set { m_dirtyFlags |= 0x01; Health = value; }

}

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

Auch wenn die antwort nun obsulet ist, bzw bald ist.

Beim "einsteigen" eines spielers nach der erstellung von gameobjects ist meist das problem das der ablauf so aussieht: connecting zum server > levelload > spiel.

Als kleine hintergrund info, die network initalisierten objekte werden beim connecting erstellt.

Also, verbindet er sich, baut die game objects und löscht sie weil sie im alten level sind.

Außerdem müssen die neu erstellten objecte im prefab schon ein networkvied haben. Sonst werdens ja nicht syncronisiert ;)

Hoff das hilft noch die letzten versionen, mit dem alten networking :P

Link zu diesem Kommentar
Auf anderen Seiten teilen

SyncVar ist aber nur Server zu Client. Ein Client kann den Wert der Variablen nicht ändern, dazu muss ein Command her, den der Client beim Server aufruft, der diesen Wert ändert. Ist aber auch irgendwie sinnvoll, soll das Ganze authoritative sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...