Jump to content
Unity Insider Forum

Network verschiedene Prefabs spawnen


Recommended Posts

Hey Leute,

Ich habe 2 Spieler die jeweils ihre eigenen Assets(Animator Controller etc(Prefabs)) haben.

Wenn der Host ein Spiel erstellt, soll Prefab1 an position x spawnen

Wenn ein Client connected, soll Prefab2 an position y spawnen

Ich kann im Network Manager nur ein Prefab bestimmen.

Wie sollte ich hier am besten vorgehen?

Ich habe verschiedene Ansätze versucht bin aber leider noch nirgends weiter gekommen. (Bei Unity selbst stand etwas von einem individualisierten network manager script, allerdings kann ich dieses nicht in unity öffnen bzw editieren weil ich unten eine Fehlermeldung bekommen. Wie der Originalcode des network managers aussieht weiß ich leider daher auch nicht. etc.

EDIT: Oder kann es sein dass ich hier versuche auf einer ganz falschen Eben zu agieren? Soll heißen, das Auto Spawn Prefab des Network Managers ist für grundlegendere GameObjekte gedacht als das direkte Spawnen von Spielfiguren. Sollte ich also dort eher eine Grundmechanik ausführen, um mich von dort an durch das Spiel zu hangeln? Ich hoffe es macht Sinn was ich versuche zu sagen ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Soooo bin schon näher dran...

ich kann zwei verschiedene prefabs spawnen etc.

Nur kann jetzt nur ein player das ganze steuern

Ich habe ein Player script wo das movement festgelegt ist. Das sehe ich auch in beiden Fenstern.

Ich habe versucht im Player script 

if (!isLocalPlayer) {

            return;
        }

zu nutzen damit, allerdings kann dann keiner der beiden die units steuern.

Ist es überhaupt möglichi das zwei verschieden Units das gleiche Movement script haben? Wenn ja wie weise ich die unterschiedlich zu? :wacko:

Link zu diesem Kommentar
Auf anderen Seiten teilen

EDIT: SOLVED! ich kanns leider aber auch nicht richtig erklären weil mich jemand durch einen code geleitet hat den ich noch nicht hundert pro verstehe, das wird erst irgendwann die Wochen passieren...

 

Ohmann. jetzt vor 5 Minuten habe ich es endlich hinbekommen, nach ca 100x zwei games laden und schauen ob es geht :o

Das einzige was ich nun nach all den Versuchen noch gemacht habe ist das START PREFAB das im Network Manager liegt  und meine beiden Spieler spawned

bei Network Identity das Local Player authority einzuschalten. Das verwirrt mich allerdings ein wenig. Muss das Prefab mit dem script was meine beiden Units erstellt selbst auch die local player authority eingeschaltet haben? 

Also wenn ich einen Launcher erstelle und das andere spiel in Unity starte, Beim Host Player1 spawne, dann beim client player 2, kann ich beim Host einen zweiten Player1 spawnen, das geht aber nur wenn ich es genau so mache. Wenn ich zwei seperater Game Launcher ausführe geht das nicht. dafür kann der host solange beide units gleichzeitig steuern bis der Client sich das erste mal bewegt hat.

Unity zeigt mir darüber hinaus noch unten den Fehler an: Trying to send command for object without authority.

das passiert immer dann wenn ich mit dem Client eine [Command]  methode ausführen will um die unit zu spawnen, lustigerweise spawned er sie jetzt trotzdem aber der fehler bleibt bestehen. Irgendwie muss das was mit der Local player authority zu tuen haben denke ich. Bei einem Debug.Log test wird mir beim Player script auch immer angezeigt das "isLocalPLayer = false" ist. Das erste Script hier ist mein PlayerSpawn script welches auf meinem START Prefab liegt welches im network manager als Player Prefab liegt, hier ist AUTO CREATE PLAYER angeschaltet da ich somit "isLocalPlayer = true" setzen kann. C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;


public class PlayerSpawn : NetworkBehaviour {

	[SerializeField]
	GameObject player1;
	[SerializeField]
	GameObject player2;

	PlayerController player22;

	Vector3 spawnlocationP1;
	Vector3 spawnlocationP2;
	bool canspawnp1;
	bool canspawnp2;

	// Use this for initialization
	void Start () {
		spawnlocationP1.y = 4f;
		spawnlocationP1.x = 1;
		spawnlocationP2.y = 4f;
		spawnlocationP2.x = 17.83f;
		canspawnp1 = true;
		canspawnp2 = true;

		}

// Update is called once per frame
	void FixedUpdate () {

	if (Input.GetKey (KeyCode.S) && canspawnp1) 
		if (isServer) {
			if (isLocalPlayer) {
				canspawnp1 = false;
				Debug.Log ("testp1");
				CmdSpawn ();
			}
		}
		if (Input.GetKey (KeyCode.S) && canspawnp2) 
		if (!isServer){
			if(isLocalPlayer)
			canspawnp2 = false;
			Debug.Log ("testp2");
			CmdSpawnClient ();
		}
	}

	[Command]
	 private void CmdSpawn()
	{
		
		GameObject p1 = (GameObject)Instantiate(player1, spawnlocationP1, transform.rotation);
		NetworkServer.Spawn (p1 );
			}

	[Command]
	private void CmdSpawnClient()
	{

		GameObject p2 = (GameObject)Instantiate(player2, spawnlocationP2, transform.rotation);
		NetworkServer.SpawnWithClientAuthority (p2, connectionToClient);
			}
		}

Hier ist mein zweites Script, welches beide Unit Prefabs besitzen

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Player : NetworkBehaviour {

	private Animator moveA;
	Transform tr;
	Vector3 pos;
	private float moveRange = 1.668f;
	private int horizontalMoveRange = 1;
	private int verticalMoveRange = 1;

	[SerializeField]
	private int speedA = 1;
	private int speedIdle = 0;

// Use this for initialization
	void Start() 
	{
		pos = transform.position;
		tr = transform;
		Debug.Log ("IsLocalPlayer == " + isLocalPlayer);
	}
		void FixedUpdate()
	{

			//Moving is done by checking IS location(pos) with SHOULD location (tr.position)
			//If Input happens & Player is still standing use Movemethods
			if (Input.GetKey (KeyCode.A) && tr.position == pos && horizontalMoveRange >= 2)
				MoveLeft ();
			if (Input.GetKey (KeyCode.D) && tr.position == pos && horizontalMoveRange <= 31)
				MoveRight ();
			if (Input.GetKey (KeyCode.W) && tr.position == pos && verticalMoveRange <= 17)
				MoveUp ();
			if (Input.GetKey (KeyCode.S) && tr.position == pos && verticalMoveRange >= 2)
				MoveDown ();

			//Moves the Player
			transform.position = Vector3.MoveTowards (transform.position, pos, Time.deltaTime * speedA);

			// If its not walking anymore set to IDLE animation
			moveA = GetComponent<Animator> ();
			if (tr.position == pos)
				moveA.SetInteger ("wspeed", (speedIdle));
	}

	void MoveLeft()
	{
		pos += (Vector3.left) / moveRange;
		moveA = GetComponent<Animator> ();
		moveA.SetInteger ("wspeed", (speedA));
		WalkingSound ();
		horizontalMoveRange--;
	}

	void MoveRight()
	{
		pos += (Vector3.right) / moveRange;
		moveA = GetComponent<Animator> ();
		moveA.SetInteger ("wspeed", (speedA));
		WalkingSound ();
		horizontalMoveRange++;
	}

	void MoveUp()
	{
		pos += (Vector3.up) / moveRange;
		moveA = GetComponent<Animator> ();
		moveA.SetInteger ("wspeed", (speedA));
		WalkingSound ();
		verticalMoveRange++;
	}

	void MoveDown()
	{
		pos += (Vector3.down) / moveRange;
		moveA = GetComponent<Animator> ();
		moveA.SetInteger ("wspeed", (speedA));
		WalkingSound ();
		verticalMoveRange--;
	}

	void WalkingSound(){
		AudioSource audio = GetComponent<AudioSource> ();
		audio.Play ();
	}
}

Also irgendwie habe ich das noch nicht ganz verstanden wie ein Client dinge im network spawnen soll, soweit ich weiß geht das ja nicht.

Nur wenn Client seinen helden auswählt o.ä. läuft der trigger ja zwangsläufig über ihn, vor allem dann wenn er das objekt erstelln muss um authority darüber zu besitzen.

Sehr verwirrend...:blink:

EDIT: Mir ist jetzt doch noch aufgefallen das die Animationen bei beiden nicht synchronisiert werden. Beim einen läuft die ganzezeit permanent die LAUF animation, und beim anderen läuft permanent die IDLE animation, bei sich selbst funktionieren sie aber...

Ich denke s liegt daran das ich kein [COMMAND] + Cmd prefix bei den MoveUp etc methoden habe. wenn ich das tue kann der connect Client sich nicht mehr bewegen wegen Authoriety. ich versteh nicht wie ein Client überhaupt etwas auf dem server tuen kann wenn er keine rechte hat. kann mich hier mal wer aufklären ? Irgendwie verstehe ich nicht wodurch und wie Gameobjekte zugewiesen werden (Dem server, dem Client) und wie diese dann kommunizieren. Ich habe schon so sachen gesehen wie: 

 

[Command]
void CmdKeyDown()
{
  RpcKeyDown();
}
[ClientRpc]
void RpcKeyDown()
{
 ....
}

Allerdings unabhängig davon das dann alles irgendwie doppeltgemoppelt geschrieben werden muss, wirft er auch dann Fehler bei mir aus:

Trying to send command for object without authority. (also immer den gleichen) und darüber hinaus dann noch einen neuen :D

SpawnObject for Player2(Clone) (UnityEngine.GameObject), NetworkServer is not active. Cannot spawn objects without an active server.

Ich krieg echt die Kriese............ :(

EDIT: Wenn ich anstelle des leeren Gameobjects mit dem Script zum Spawnen der Player, das Player prefab selbst in den network Manager packe und auto Spawn aktiviere, dann kann ich beide wunderbar bewegen, nur spawned dann halt die gleiche einheit an der gleichen stelle was ich eben nicht möchte. 

EDIT: Ich finde seit 3 std googlen nicht einmal heraus ob "islocalplayer" nur auf einem einzigen gameobjekt liegen kann, denn bisher ist immer nur "islocalplayer" wenn es vom NetworkManager mit der autospawn function erstellt wurde. alles andere nicht. HILFE :D

 

EDIT: SOLVED! ich kanns leider aber auch nicht richtig erklären weil mich jemand durch einen code geleitet hat den ich noch nicht hundert pro verstehe, das wird erst irgendwann die Wochen passieren...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...