SignalR und Unity in euren Multiplayer-Indie-Games

Von Berndt+Hamb%c3%b6ck+(Gastblogger) Autor Feed 11. September 2014 07:30
Ihr, als .Net-Entwickler, kennt SignalR möglicherweise bereits als Microsoft-Programmierbibliothek um Nachrichten in Echtzeit zu verschiedenen Clients zu übertragen. Das klingt zuerst einmal schwierig, ist es in Wirklichkeit aber nicht.

Grübelt ihr noch über ein Einsatzszenario? Nun, wie wäre es mit einem großen Monitor, oder Fernseher für euer Support-Team? Auf diesem wird der aktuelle Status von verschiedenen System angezeigt. Sollte eines der Systeme etwas Ungewöhnliches entdecken, dann schickt es zum SignalR-Hub eine Meldung. Alle angeschlossenen Clients erhalten diese Meldung umgehend und können dementsprechend reagieren.
clip_image002

Ich hoffe, ihr seid ein wenig neugierig geworden und wollt jetzt wissen, wie das genau funktioniert? Nun das hat mir mein Blogger-Kollege Toni Pohl schon hier in diesem Blog-Eintrag von letztem Jahr abgenommen. Ich empfehle euch diesen Eintrag zu lesen, dann können wir anschließend an dieser Stelle weiter machen.

Unity und SignalR

Ich möchte euch zeigen, wie man Unity mit SignalR verwenden kann. Für Multi-Player-Games bietet es sich ja geradezu an. Mit einer eventuell bereits vorhandenen Azure-Subscription habt ihr noch dazu alles, was ihr als Infrastruktur in Produktion benötigt. Dazu aber möglicherweise ein anderes Mal mehr. Ich würde gerne mit euch gemeinsam einen Teaser für ein Spiel schreiben. Die heutige Funktionalität ist recht einfach zusammengefasst:

· Unity als Entwicklungstool.
· Ein witziger Hintergrund.
· Ein Sprite (in diesem Fall eine geöffnete Hand), welches sich mit der Maus bewegen lässt.
· Wenn die linke Maustaste gedrückt wird, dann soll eine Faust gebildet werden, also in etwa so, als würde man nach einem Objekt greifen.
· Ein Web-Client, der den gleichen Hintergrund verwendet.
· Ebenfalls die geöffnete Hand, sowie die geschlossene Hand.
· Wenn das Unity-Spiel startet, dann soll sich auf der Webseite die Hand genauso bewegen, wie in dem Unity-Client.
· Wird im Unity-Spiel die Maustaste gedrückt, dann wird die Hand zu einer Faust, das soll der Web-Client widerspiegeln.

Lange Rede, kurzer Sinn, das soll so funktionieren, wie ich es hier auf youtube kurz vorzeige.
Was benötigt ihr dazu? Ich nehme an, wenn ihr diesem Blog folgt, dann habt ihr das schon installiert:

· Unity, die Testversion von http://unity3d.com/ reicht vollkommen.
· Visual Studio 2013, wenn ihr die Visual Studio Integration mit Unity verwenden wollt.
· Visual Studio Tools für Unity von hier: http://unityvs.com/ diese bitte herunterladen und installieren.

Für die ganz Ungeduldigen unter euch, den Source Code gibt es wieder hier zum Download.

Spiele-Sprites

Für den Spiel-Teaser selbst benötigen wir noch ein Hintergrund-Bild, dieses findet ihr als .psd-Datei hier, hat die Größe von 800x500 Pixel und sieht so aus:

clip_image004

Damit wir auch etwas Bewegung in die Sache bringen - die beiden Bilder für die sich bewegende Hand:

clip_image005 clip_image006

Das war es bereits, es kann also losgehen mit dem Unity-Client.

Ein kleiner Hinweis noch, solltet ihr noch nie mit Unity gearbeitet haben, dann lege ich euch meinen letzten Blog-Eintrag ans Herz, da werden einige der Schritte, die ich hier nur kurz anreiße – vor allem beim Anlegen des Projektes – genauer beschrieben. Diesen findet ihr hier.

Der Unity Client Teil 1 – noch ohne SignalR

Im ersten Teil wollen wir den Unity-Client so weit bringen, dass die Hand mit der Maus bewegt werden kann und beim Klicken der Maus sich die Hand schließt und auch wieder öffnet. Im Unity-Client müssen wir somit folgendes tun:

· Ein neues 2D-Unity-Projekt erstellen.
· Den Hintergrund und die Hand in die Spielszene einfügen.
· Ein „wenig“ Physik für die Hand hinzufügen.
· Ein Script erstellen, damit die Hand bewegt werden kann.
· Wenn die Maus gedrückt wird, schließt sich die Hand und öffnet sich wieder, wenn die Maustaste losgelassen wird.

Ein neues 2D-Unity-Projekt erstellen

Im geöffneten Unity erstelle ich ein neues 2D-Projekt und gebe diesem den Namen SignalRUnitySample.

clip_image007

Eine gewisse Ordnerstruktur in Unity ist immer eine gute Sache, um die Dateien nicht irgendwie herumfliegen zu lassen. Das sollte ungefähr so aussehen:

clip_image008

Ich habe auch gleich die drei Bilder in den Ordner Textures mit Drag & Drop hineingezogen.

Den Hintergrund und die Hand in die Spielszene einfügen

Dazu ziehen wir den Hintergrund aus dem Assets\Textures-Folder auf die Main Camera in der Hierarchy-Ansicht. Danach holen wir aus dem Assets\Textures-Folder den Sprite mit dem Namen OpenHand als eigenständiges Objekt – ich habe dieses dann umbenannt auf Player.

clip_image009

Ich habe die Anzeigegröße in Unity noch angepasst, um das Resultat mit dem im Browser besser vergleichen zu können. Dazu klickt ihr in Unity auf Game und in der DropDown fügt ihr mittels Add eine neue Auflösung mit 800x500 Pixel ein.

clip_image010

Danach skaliert ihr noch den Hintergrund und die Hand, dementsprechend. D. h. den Hintergrund skaliert ihr auf der X- und Y-Achse 2 mal. Das macht ihr auch mit dem Player-Objekt (der Hand). Des Weiteren sollte die Hand im aktuellen Layer weiter vorne liegen (Wert 1), damit wir diese auch sehen und diese nicht hinter dem Hintergrund gezeichnet wird.

clip_image012 clip_image014

Jetzt sollte noch etwas Bewegung in die Sache kommen.

Physik und Skript für das Player-Objekt

Wie schon bei dem PhoneCatcher-Spiel das letzte Mal, benötigt unser Player-Objekt einen RigidBody 2D, an dem aber „Is Kinematic“ gesetzt wird, um die Schwerkraft abzuschalten. Die Spieler-Hand wird ja mit der Maus, durch den Spieler selbst, bewegt. Dieser wird mit dem Add Component-Button hinzugefügt (an dem Player Objekt).

clip_image016 clip_image017

Jetzt noch ein Skript mit dem Namen PlayerController, wiederum mit dem Add Component an dem Player Objekt. Falls ihr das alles richtig gemacht habt, dann sieht das im Inspector bisher so aus:

clip_image018

Das Skript ist bisher ebenfalls keine große Überraschung, da es sich an dem vom letzten Mal orientiert. Wir benötigen die Grenzen des Spielfeldes, damit die Hand nicht darüber hinaus bewegt werden kann. Zusätzlich muss das Spieler-Sprite ausgetauscht werden, wenn die Maustaste gedrückt wird – und wieder zurückgesetzt werden, damit wieder die geöffnete Hand sichtbar ist, wenn die Maus losgelassen wird.

using UnityEngine;
public class PlayerController : MonoBehaviour { 
    public Camera cam;
    private float maxWidth;
    private float maxHeight;
 
    bool isHandOpen = true;
    public Sprite clickedSprite;
    private Sprite standardSprite;
 
    void Start()
    {
        if (cam == null)
            cam = Camera.main;
        var corner = new Vector3(Screen.width, Screen.height, 0f);
        var targetWidth = cam.ScreenToWorldPoint(corner);
        float playerWidth = renderer.bounds.extents.x;
        float playerHeight = renderer.bounds.extents.y;
        maxWidth = targetWidth.x - playerWidth;
        maxHeight = targetWidth.y - playerHeight;
 
        standardSprite = this.GetComponent<SpriteRenderer>().sprite;
    }
    void FixedUpdate()
    {
        var currentPosition = cam.ScreenToWorldPoint(Input.mousePosition);
        float targetWidth = Mathf.Clamp(currentPosition.x, -maxWidth, maxWidth);
        float targetHeight = Mathf.Clamp(currentPosition.y, -maxHeight, maxHeight);
        var newPosition = new Vector3(targetWidth, targetHeight, 0f);
        rigidbody2D.MovePosition(newPosition);
 
        if (Input.GetMouseButtonDown(0))
        {
            isHandOpen = false;
            MouseDown();
        }
        else if(Input.GetMouseButtonUp(0))
        {
            isHandOpen = true;
            MouseUp();
        }
    }
 
    private void MouseDown()
    {
        Debug.Log("MouseDown");
        this.GetComponent<SpriteRenderer>().sprite = clickedSprite;
    }
 
    private void MouseUp()
    {
        Debug.Log("MouseUp");
        this.GetComponent<SpriteRenderer>().sprite = standardSprite;
    }
}

Zurück in Unity muss noch das Sprite für die Public-Variablen clickedSprite befüllt werden, dazu muss aus Assets\Textures das ClosedHand-Sprite mittels Drag & Drop auf die Skript-Variable gezogen werden.

clip_image019

Wenn das geklappt hat, dann solltet ihr das einmal ausprobieren. Die Hand müsste über den Bildschirm flitzen, wenn ihr die Maus bewegt. Wenn die Maustaste gedrückt wird, dann seht ihr die Faust. Nach dem Loslassen der Maustaste ist wieder die geöffnete Hand sichtbar. Der Unity-Client ist erst einmal fertig, jetzt müssen wir den SignalR-Teil erstellen.

Echtzeit-Kommunikation mit SignalR

Der Unity-Client wird sich am SignalR-Hub, der als Web-Applikation läuft, anmelden und Meldungen absetzen. Der SignalR-Hub informiert alle angemeldeten Clients und diese werden dementsprechend reagieren. Wir benötigen also eine neue Web-Applikation, ihr könnt dafür entweder eine komplett neue Solution in Visual Studio anlegen, oder auch die von Unity angelegte Solution verwenden. Wie auch immer ihr euch entscheidet, wir benötigen eine neue ASP.NET Web Application, ich habe den Namen SignalRUnityWeb ausgewählt. Diese soll leer sein und per Default noch keinerlei Funktionalität zur Verfügung stellen.

clip_image021clip_image023

Wie mittlerweile fast schön üblich benötigen wir zwei NuGet Packages. Dazu drückt am Web-Projekt die rechte Maustaste und wählt „Manage NuGet Packages…“ an.

Das erste Package ist Microsoft ASP.NET SignalR, derzeit in der Version 2.1.1

clip_image025

Das zweite Package ist Microsoft.Owin.Host.SystemWeb in der Version 3.0.0

clip_image027

Jetzt können wir mit dem Implementieren loslegen, wir benötigen eine neue SignalR Hub Class (v2), dazu drückt ihr die rechte Maustaste am Web-Projekt und wählt Add-> SignalR Hub Class (v2), sollte das bei euch nicht zu sehen sein, dann bitte über Add->New Item und sucht nach SignalR – das nächste Mal, taucht der Eintrag dann in der Liste auf.

clip_image029

Diese sollte den Namen SignalRSampleHub bekommen.

clip_image030

Wir passen die Default-Implementierung nur rudimentär an, ich hätte gerne eine Send-Methode mit zwei Parametern, und zwar WER hat die Meldung abgesetzt und WAS ist der Inhalt.

using Microsoft.AspNet.SignalR;
namespace SignalRUnityWeb
{
    public class SignalRSampleHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }
}

Wenn wir SignalR 2.0 verwenden, benötigen wir noch eine OWIN Startup class, wiederum mit der rechten Maustaste am Web-Projekt und Add-> OWIN Startup class, bzw. über Add->New Item.

clip_image031

Der Name soll Startup.cs sein.

clip_image032

Die Implementierung ist kurz und bündig und stellt unseren SignalR-Hub zur Laufzeit zur Verfügung.

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRUnityWeb.Startup))]
namespace SignalRUnityWeb
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Wenn ihr die Web-Applikation ausführt, so wird das leider nicht klappen, da es da noch einen Versionskonflikt mit der aktuellen Microsoft.Owin-DLL gibt.

clip_image034

Diesen können wir in der Web.config lösen, indem wir der .NET-Laufzeitumgebung mitteilen, sodass die Version 3.0 der DLL auch funktioniert.

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" 
                        publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Jetzt benötigen wir noch eine Webseite in unserer Web-Applikation, ich würde vorschlagen wir nennen diese index.html. Diese soll das Hintergrundbild und die Hand darstellen, sowie sich an unserem SignalR-Hub anmelden. Wenn eine neue Meldung eintrifft, dann muss die Hand bewegt werden und bei gedrückter Maustaste das Bild gewechselt werden. Dank Microsoft und jQuery sind das nur ein paar Zeilen JavaScript-Code.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>SignalR-Unity Sample</title>
    <style>
        body {
            background: url(Images/game-background.png);
            /*background-size:*/
            background-repeat: no-repeat;
        }
        #player {
            position: absolute;
            top: 30px;
            left: 30px;
        }
    </style>
 
</head>
<body>
    <img id="player" src="Images/OpenHand.png" />
 
    <div id="infoContainer">
        <label id="message"></label>
    </div>
 
    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-1.6.4.min.js"></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.1.1.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="signalr/hubs"></script>
    <!--Add script to update the page and receive messages.-->
    <script type="text/javascript">
        $(function () {
            // Declare a proxy to reference the hub.
            var signalrHub = $.connection.signalRSampleHub;
            // Create a function that the hub can call to broadcast messages.
            signalrHub.client.broadcastMessage = function (name, message) {
                var messageobj = JSON.parse(message);
                if (messageobj.action == 'Position') {
                    $('#player').css('left', messageobj.value.x + 'px');// update x value
                    $('#player').css('top', 500 - $('#message').height() - messageobj.value.y + 'px');// update x value
                    $('#message').text('x:' + messageobj.value.x + "px, y:" + messageobj.value.y + 'px');
 
                    if (messageobj.value.handOpen == 'True')
                        $('#player').attr('src', 'Images/OpenHand.png');
                    else
                        $('#player').attr('src', 'Images/ClosedHand.png');
                }
            };
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#message').text('connected');
            });
        });
    </script>
</body>
</html>

Nun sollten noch die drei Bilder, die in dem Unity-Client verwendet werden, in die Web-Applikation kopiert werden, und zwar in einen Unterordner mit dem Namen Images.

clip_image035

Solltet ihr eine eigene Visual Studio Solution für diese Web-Applikation erstellt haben, dann startet diese nun. Der Signal-R Hub ist damit erstellt und aktiv. Die Webseite ist nun am Hub als erster Client angemeldet und wartet auf Meldungen vom SignalR-Hub.

clip_image036

Kommen wir zum letzten Abschnitt, SignalR und Unity zu verbinden.

Der Unity Client Teil 2 – Kommunikation mit SignalR

Zurück in Unity legen wir ein leeres GameObject an und geben diesem den Namen SignalRObject.

clip_image037clip_image038

Leere Game-Objekte sind sehr praktisch, in unserem Fall ist es so, dass wir nur ein Script benötigen (um den SignalR-Hub zu informieren), aber keinerlei sichtbaren Aktionen am Bildschirm ausführen werden. Also fügen wir gleich das Skript hinzu, wir geben diesem den Namen SignalRUnityController.

clip_image039

Speichert bitte nun eure Spiel-Szene im Scenes Folder, ich habe dieser den Namen GameScene gegeben. Das ist an dieser Stelle WICHTIG, da ihr sonst möglicherweise durch einen Absturz von Unity alles, was ihr bisher gemacht habt, verlieren könnt. Das liegt weniger an Unity, als an der Programmbibliothek, die wir uns im nächsten Schritt zu unserem Projekt dazuholen.

clip_image040

Bearbeiten wir nun gleich das Skript in Visual Studio 2013 und erweitern es, um den SignalR-Hub anzusprechen.

Leider verwendet Unity nicht die .Net 4.0 Laufzeitumgebung, sondern Mono mit der .NET 3.5 Runtime. Dadurch können wir leider das Microsoft NuGet Package (Microsoft.AspNet.SignalR.Client) für SignalR nicht in unserem Unity C# Projekt verwenden. Es gibt aber auf Github ein Projekt, welches für unsere Zwecke ausreichend ist, in diesem wurde die SignalR-Bibliothek auf .NET 2.0 „heruntermigriert“. Dieses findet ihr hier: https://github.com/jenyayel/SignalR.Client.20

Ich habe dieses Projekt meiner Unity-Solution als eigenständiges Projekt hinzugefügt und danach die Referenz zu dem C#-Projekt dazugegeben.

clip_image042clip_image044

Jetzt können wir die SignalRUnityController skripten. Ich dachte mir, dass wir die SignalR-Funktionalität abschaltbar machen, das kann sehr praktisch sein, wenn man den Unity-Client etwas „tweaked“, was ja vor allem gegen Ende in der Spiele-Entwicklung recht viel Zeit in Anspruch nimmt. Die URL zum SignalR-Hub sollte ebenfalls konfigurierbar sein (dort setzt auch bitte eure URL ein, die ist in eurem Web-Projekt vermutlich anders als meine – zumindest der verwendete Port). Der Rest ist sehr ähnlich dem JavaScript-Client, der Unity Client muss sich am Hub anmelden und möchte (im Gegensatz zum JavaScript-Client) Informationen senden. Die Informationen bestehen aus einem String (wer sendet, der UnityClient) und einem weiteren String, dieser wird allerdings als JSON versendet. Dadurch ist diese Klasse in mehreren meiner Projekte einsetzbar.

using SignalR.Client._20.Hubs;
using UnityEngine;
public class SignalRUnityController : MonoBehaviour {
    public bool useSignalR = true;
    public string signalRUrl = "http://localhost:5225/";
 
    private HubConnection _hubConnection = null;
    private IHubProxy _hubProxy;
    private Subscription _subscription;
    void Start()
    {
        if (useSignalR)
            StartSignalR();
    }
    void StartSignalR()
    {
        if (_hubConnection == null)
        {
            _hubConnection = new HubConnection(signalRUrl);
 
            _hubProxy = _hubConnection.CreateProxy("SignalRSampleHub");
            _subscription = _hubProxy.Subscribe("broadcastMessage");
            _subscription.Data += data =>
            {
                Debug.Log("signalR called us back");
            };
            _hubConnection.Start();
        }
        else
            Debug.Log("Signalr already connected...");
    }
    public void Send(string method, string message)
    {
        if (!useSignalR)
            return;
 
        var json = "{" + string.Format("\"action\": \"{0}\", \"value\": {1}", method, message) + "}";
        _hubProxy.Invoke("Send", "UnityClient", json);
    }
}

Was jetzt noch fehlt ist, dass die Informationen aus der FixedUpdate-Methode im PlayerController in der Send-Methode der SignalRUnityController-Klasse landen.

Dazu reichen uns insgesamt vier Zeilen Code. Das Trickreiche daran ist zum einen, dass wir eine Referenz auf das leere Gabe-Objekt benötigen, an dem das Skript zum Senden der Informationen hängt, zum anderen müssen die Koordinaten vom Unity-Format in Weltkoordinaten umgerechnet werden. Abschließend noch einen JSON-String gebaut und es kann auch schon losgehen.

using UnityEngine;

public class PlayerController : MonoBehaviour {

public Camera cam;

private float maxWidth;

private float maxHeight;

bool isHandOpen = true;

public Sprite clickedSprite;

private Sprite standardSprite;

private SignalRUnityController _signalr;

void Start()

    {

if (cam == null)

            cam = Camera.main;

_signalr = (SignalRUnityController)GameObject.Find("SignalRObject")

            .GetComponent(typeof(SignalRUnityController));

var corner = new Vector3(Screen.width, Screen.height, 0f);

var targetWidth = cam.ScreenToWorldPoint(corner);

float playerWidth = renderer.bounds.extents.x;

float playerHeight = renderer.bounds.extents.y;

        maxWidth = targetWidth.x - playerWidth;

        maxHeight = targetWidth.y - playerHeight;

        standardSprite = this.GetComponent<SpriteRenderer>().sprite;

    }

void FixedUpdate()

    {

var currentPosition = cam.ScreenToWorldPoint(Input.mousePosition);

float targetWidth = Mathf.Clamp(currentPosition.x, -maxWidth, maxWidth);

float targetHeight = Mathf.Clamp(currentPosition.y, -maxHeight, maxHeight);

var newPosition = new Vector3(targetWidth, targetHeight, 0f);

        rigidbody2D.MovePosition(newPosition);

if (Input.GetMouseButtonDown(0))

        {

            isHandOpen = false;

            MouseDown();

        }

else if(Input.GetMouseButtonUp(0))

        {

            isHandOpen = true;

            MouseUp();

        }

var worldCoordinates = cam.WorldToScreenPoint(newPosition);

var json = "{" + string.Format("\"x\": \"{0}\", \"y\": \"{1}\", \"handOpen\": \"{2}\"",

            worldCoordinates.x, worldCoordinates.y, isHandOpen) + "}";

        _signalr.Send("Position", json);

    }

private void MouseDown()

    {

Debug.Log("MouseDown");

this.GetComponent<SpriteRenderer>().sprite = clickedSprite;

    }

private void MouseUp()

    {

Debug.Log("MouseUp");

this.GetComponent<SpriteRenderer>().sprite = standardSprite;

    }

}

Damit Unity auch unsere beiden Referenzen kennt, die in unserem Projekt nun notwendig sind, müssen die beiden DLLs

· Newtonsoft.Json.dll

· SignalR.Client.20.dll

in den Assets-Folder kopiert werden. Ihr findet diese im bin\Debug-Verzeichnis von dem SignalR.Client.20 Projekt.

clip_image046

clip_image048

Bevor ihr in Unity den Client startet, achtet bitte darauf, dass die Web-Applikation mit dem SignalR-Hub läuft, da sonst Unity hängen bleibt und ihr Unity erneut starten müsst. ACHTUNG, falls ihr eure Spielszene nicht zuvor gespeichert habt, dann verliert ihr alle ungespeicherten Schritte.

Wenn die Web-Applikation und der Unity-Client läuft und ihr die Maus bewegt, werden sich die Hände gemeinsam bewegen.

Falls ihr SignalR mit anderen Clients verwenden wollt, dann solltet ihr einen Blick auf die folgenden Native-Implementierungen werfen:

· iOS (3rd Party): https://github.com/DyKnow/SignalR-ObjC
· Android (offizieller Android-Client): https://github.com/SignalR/java-client
· Windows Phone 8/8.1 (offizieller .Net Client): https://github.com/SignalR/SignalR

Für Unity muss noch ein Wrapper um diese Bibliotheken herum geschrieben werden, dazu findet ihr Näheres in der Unity-Dokumentation:

http://docs.unity3d.com/Manual/PluginsForIOS.html
http://docs.unity3d.com/Manual/PluginsForAndroid.html
http://docs.unity3d.com/Manual/wp8-plugins-guide-csharp.html

Zusammenfassung

Microsoft SignalR und Unity ergeben die perfekte Lösung für Multiplayer-Spiele. Mit wenigen Schritten ist die Echtzeit-Kommunikation bereit gestellt. Ich bin schon gespannt, welche tollen Spiele ihr mit dieser Kombination bauen werdet. Ich freue mich darauf und hoffe ihr habt genauso viel Spaß wie ich beim Entwickeln eurer Indie-Games!


Berndt Hamböck ist seit 2007 MCT, darüber hinaus befasst er sich mit Lösungen für komplexe Anwendungsszenarien mit den neuesten Microsoft Technologien. Die Erfahrungen aus der Projektarbeit gibt er in Vorträgen und Trainings weiter und begleitet Entwicklerteams in Softwareunternehmen bei Projekten im Microsoft Umfeld. Folge ihm auf Twitter, um nichts zu verpassen.

Das ist ein Gastbeitrag. Die Meinung des Autors muss sich nicht mit jener von Microsoft decken. Durch den Artikel ergeben sich keinerlei Handlungsempfehlungen. Microsoft übernimmt keine Gewähr für die Richtigkeit oder Vollständigkeit der Angaben.

Comments (3) -

>

9/11/2014 1:23:43 PM #

Super Beitrag! Gestern noch habe ich überlegt wie ich ein ähnliches Problem lösen könnte. Heute eine gute Idee dazu. Smile

Matthias Deutschland

>

1/19/2015 5:12:16 PM #

Hi Berndt,

I've tried out your code, however when using Action (System.Core) it won't compile due to an ambiguous reference. This error looks like this in Unity:

Assets/Scripts/SignalRUnityController.cs(13,25): error CS0433: The imported type `System.Action' is defined multiple times

And like this in Visual Studio:

Error  1  The type 'System.Action' exists in both 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Unity Subset v3.5\System.Core.dll' and 'C:\Users\Søren\Projects\SignalR\Assets\Newtonsoft.Json.dll'  C:\Users\Søren\Projects\SignalR\Assets\Scripts\SignalRUnityController.cs  13  25  UnityVS.SignalR.CSharp

Do you have any idea on how to solve this?

Søren Nielsen Dänemark

>

7/8/2015 12:11:02 PM #

Thank you for this great article.
you saved my time!

mohammadreza berneti Iran

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

Datenschutzhinweis: Sie stimmen durch "Kommentar speichern" der Speicherung Ihrer Angaben durch Microsoft Österreich für die Beantwortung der Anfrage zu. Sie erhalten dadurch keine unerwünschten Werbezusendungen. Ihre Emailadresse wird auf Ihren Wunsch dazu verwendet Sie über neue Kommentare zu informieren.

Microsoft respektiert den Datenschutz. Datenschutz & Cookies


 
    Build2016
    Developer Events

Aktuelle Downloads

Azure Free Trial
 
Visual Studio Downloads
 
Windows Azure Free Trial
Instagram
CodeFest.at on Facebook

Datenschutz & Cookies · Nutzungsbedingungen · Impressum · Markenzeichen
© 2013 Microsoft. Alle Rechte vorbehalten · BlogEngine.NET 2.7.0.0 · Diese Website wird für Microsoft von atwork gehostet.
powered by atwork