Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Blizzer

Frischling

  • »Blizzer« ist der Autor dieses Themas

Beiträge: 49

Wohnort: Götzis

Beruf: C# Software Entwickler

  • Private Nachricht senden

1

07.01.2016, 22:12

C# Unity Networking API

http://mibpaste.com/gIAXu9

Einen schönen guten Abend :)

Ich habe mit Unity einen einfachen Pong klon Programmiert und wollte diesen jetzt mit einen Multiplayer ausstatten.

Dieses hat auch bis auf einen Punkt sehr schön funktioniert.

Ich starte mein Spiel zwei mal einmal als Host und einmal als CLient funktioniert auch alles sehr schön.
Wenn ich den Host bewege bewegt der sich auch auf den Client aber wenn ich den Client bewege bewegt der sich nicht bei meinen Host.

Ich hänge den Code mit hier rein vill. hatte ja schon mal wer das selbe Problem :)

Gruss
Blizzer

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using UnityEngine;
using UnityEngine.Networking;

struct RacketState
{
    public float x;
    public float y;
}

public class MoveRacket : NetworkBehaviour{
    [SyncVar]
    RacketState state;

    public float speed = 30;
    public string axis = "Vertical";

    void Awake() {
        InitState();
    }

    void Start() {
        SyncState();
    }

    void Update()
    {
        if (isLocalPlayer){
            float v = Input.GetAxisRaw(axis);
            GetComponent<Rigidbody2D>().velocity = new Vector2(0, v) * speed;
            CmdMove();
        }
        SyncState();
    }


    [Command]
    void CmdMove()
    {
        state = new RacketState {
            x = transform.position.x,
            y = transform.position.y
        };
    }

    [Server]
    void InitState() {
        state = new RacketState {
            x = 0,
            y = 0
        };
    }


   
    void SyncState() {
        transform.position = new Vector2(state.x, state.y);
        //state.x * Vector3.right + state.y * Vector3.up;
    }
}

Superwayne

Treue Seele

Beiträge: 242

Beruf: Student & App Entwickler (Xamarin)

  • Private Nachricht senden

2

08.01.2016, 00:28

Guten Abend,

ich sitze auch zurzeit an der Networking API und habe schon das ein oder andere Problem gehabt.

In deinem Fall liegt das Problem daran, dass du nur das lokale Spielerobjekt bewegst (indirekt durch den rigidbody). Die Velocity ändert sich auf dem Server nicht und daher bewegt sich auch das Objekt auf dem Server nicht. Wenn du nun CmdMove() ausführst, wird der state einfach einfach auf die Position x und y gesetzt, die sich auf dem Server nicht geändert hat. Um dem Server die geänderte Position mitzuteilen, musst du die neuen float Werte mit CmdMove(float x, float y) an den Server senden. Dieser kann sie dann für die anderen Spieler synchronisieren.

Statt in jedem Frame SyncState() aufzurufen, kannst du übrigens die Funktion als hook definieren:

C#-Quelltext

1
2
[SyncVar (hook = "SyncState")]
RacketState state;


Damit wird SyncState jedes mal dann aufgerufen, wenn sich state geändert hat. Ich vermute, dass die Variable auch an den Spieler zurück synchronisiert wird. Wenn dann die Hook aufgerufen wird, darf der Lokale Spieler natürlich nicht seine Position zurück ändern. Sonst kommt es bei netzwerkbedingter Verzögerung zu einem Stottern beim Spieler, wenn dieser immer wieder auf die vorherige Position zurückgesetzt wird.
Also quasi einfach:

C#-Quelltext

1
2
3
4
5
void SyncState() {
    if(!isLocalPlayer) {
        transform.position = new Vector2(state.x, state.y);
    }
}


Ich hoffe das hilft, bin selber noch nicht so fit mit der API.

Blizzer

Frischling

  • »Blizzer« ist der Autor dieses Themas

Beiträge: 49

Wohnort: Götzis

Beruf: C# Software Entwickler

  • Private Nachricht senden

3

08.01.2016, 08:26

Danke :) hat funktioniert :) :thumbup:

Mabenan

Frischling

Beiträge: 24

Wohnort: Bayern

Beruf: IT-Berater

  • Private Nachricht senden

4

08.01.2016, 09:37

Bei der neuen UNET Network API gibt es auch die Möglichkeit eine Network Transform Componente an das objekt zu packen damit wird das Transform automatisch synchronisiert.

http://docs.unity3d.com/Manual/class-NetworkTransform.html

Blizzer

Frischling

  • »Blizzer« ist der Autor dieses Themas

Beiträge: 49

Wohnort: Götzis

Beruf: C# Software Entwickler

  • Private Nachricht senden

5

08.01.2016, 15:33

Danke das wusste ich auch noch nicht :) Die Componente habe ich jetzt an den Ball gehängt :)

Werbeanzeige