Apr 29

Written by: Michael Washington
4/29/2012 6:23 PM  RssIcon

image

Visual Studio LightSwitch in Visual Studio 11 allows you to communicate directly with the LightSwitch business layer (business rules, custom code, security), though OData. This allows you to use LightSwitch as the orchestrating control for any enterprise application or deployment.

In this example, we will demonstrate, using Visual Studio LightSwitch, an application to monitor and send messages to a Unity 3D online game.

Previously, we covered using LightSwitch to support a Android mobile application in: Communicating With LightSwitch Using Android App Inventor. We have also covered implementing user and role based security using LightSwitch and OData in: A Full CRUD LightSwitch JQuery Mobile Application and A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page.

A Visual Studio LightSwitch Game Controller

image

This article coverers a proof of concept we recently created for a video game project. We plan to have several players playing online at one time and we need to monitor the game from each players perspective. In addition, we need to be able to transmit messages to individual players and to all players.

It is possible to implement this additional functionality using Unity 3D, but Unity 3D is really is not designed for forms over data operations for such things as user account management, tracking and facilitating in-game purchases, forum and chat logs, player notes, and tracking complaints. We desire to use LightSwitch as the control center and database for everything involved with maintaining an online Unity 3D game.

Using the methods described in this article, one could also control each of the players in the game, but currently we do not have that requirement. Also, we will not cover security in this example (to keep the code simple), however, LightSwitch allows you to implement any security methods you require.

A Walk Thru Of The Functionality

image

For the end-user playing the game, all they see are messages transmitted to the game, that appear in a box inside the game.

image

The LightSwitch application allows an administrator to have the Unity 3D game send a screen shot by clicking the Get Screen Shot button.

image

The screen shot is displayed in the LightSwitch application.

image

A message can be sent to the Unity 3D game by clicking the Send Message button…

image

…and entering a message and clicking Save Message.

image

The message appears in the game.

The Unity 3D Game

image

Unity 3D is a game development tool that allows you to create professional games.

image

It allows you to publish your games on multiple platforms.

best of all you can download it for free. You only have to pay if you want to publish your game to anything other than the web based player (or you want the professional features).

image

Unity 3D has some of the best documentation and tutorials you will find anywhere. For the example Unity 3D project, we will use the game covered in the 2D Gameplay Tutorial.

image

The only thing we change in the original project, is the addition of a script, ContactLightSwitch (written in C#. Unity 3D allows you to write your scripts in C#, JavaScript, and Boo), that we drop on the Main Camera object to attach to it.

The ContactLightSwitch script starts off with a few public variables and a private variable that will hold the last message:

 

using UnityEngine;
using System.Collections;
public class ContactLightSwitch : MonoBehaviour 
{
	public string ScreenShotURL = "http://localhost/LsUnity3DController/UploadImage.aspx";
	public string GetCommandURL = "http://localhost/LsUnity3DController/GetCommand.aspx";
	private string LastMessage = "";

 

The public variables show up in the property panel for the script, and allow the game designer to set them explicitly in the Unity 3D inspector panel, or programmatically from another script.

The first method to fire is the Start method, and in that method we use invokeRepeating to call the Loop method every 2 seconds:

 

	void Start() 
	{
		// Call the Loop method every 2 seconds
		InvokeRepeating("Loop", 2f, 2f);	
	}

 

The Loop method sets up a Coroutine to call LightSwitch and get the latest command (either to send a screen shot or to display a message):

 

 

	void Loop()
	{   
		// Contact the LightSwitch application
		WWW www = new WWW(GetCommandURL);
		// Call WaitForRequest method 
        	         StartCoroutine(WaitForRequest(www));
	}	
	
	IEnumerator WaitForRequest(WWW www)
    	{
		// Return control for now but return
		// back to this method when the web call 
		// is complete
        	         yield return www;
        	// check for errors
        	if (www.error == null)
        	{         			
			if(www.text == "SendPicture")
			{
				// Call the UploadPNG method
				StartCoroutine(UploadPNG());
			}
			else
			{
				if(www.text != "")
				{
					// This is just a message so display it
					print(www.text);
					LastMessage = www.text;
				}
			}
        	} 
		else 
		{
			// Show any errors
            		print(www.error);
			LastMessage = www.error;
        	}    
    	}

 

 

The OnGUI method is used to display the contents of the LastMessage:

 

	void OnGUI() 
	{
		GUI.Box(new Rect (300,20,300,30), LastMessage);
	}

 

If a screen shot needs to be sent to LightSwitch, the following method is used (this code is taken from the Unity 3D site):

 

	IEnumerator UploadPNG() 
	{    
		// We should only read the screen after all rendering is complete    
		yield return new WaitForEndOfFrame();  
		
		// Create a texture the size of the screen, RGB24 format    
		var width = Screen.width;    
		var height = Screen.height;    
		var tex = new Texture2D( width, height, TextureFormat.RGB24, false );  
		  
		// Read screen contents into the texture    
		tex.ReadPixels( new Rect(0, 0, width, height), 0, 0 );    
		tex.Apply();    
		
		// Encode texture into PNG    
		var bytes = tex.EncodeToPNG();    
		Destroy( tex );    
		
		// Create a Web Form    
		var form = new WWWForm();    
		form.AddField("frameCount", Time.frameCount.ToString());    
		form.AddBinaryData("fileUpload", bytes, "screenShot.png", "image/png"); 
	  
		// Upload to a cgi script    
		var www = new WWW(ScreenShotURL, form); 
		yield return www;
 	}

 

The LightSwitch Application

image

The LightSwitch application uses a single entity (table) called Unity3DCommand. This is the table that commands for the Unity 3D game are entered into, and read from, by the Unity 3D game.

image

Next, we switch to File View.

image

We add an OData Service Reference. See: Calling LightSwitch 2011 OData Using Server Side Code for a step-by-step walk-thru on the process.

We add a page to receive the screen shot image from the Unity 3D game using the following code:

(note: The following code allows any file to be uploaded. This is not safe to do in production. You should alter the method to only allow certain file types such as .jpg or .png)

 

        protected void Page_Load(object sender, EventArgs e)
        {
            HttpFileCollection uploadFiles = Request.Files;
            // Build HTML listing the files received.
            string summary = "<p>Files Uploaded:</p><ol>";
            // Loop over the uploaded files and save to disk.
            int i;
            for (i = 0; i < uploadFiles.Count; i++)
            {
                HttpPostedFile postedFile = uploadFiles[i];
                // Access the uploaded file's content in-memory:
                System.IO.Stream inStream = postedFile.InputStream;
                byte[] fileData = new byte[postedFile.ContentLength];
                inStream.Read(fileData, 0, postedFile.ContentLength);
                // Save the posted file
                postedFile.SaveAs(Server.MapPath("~") + "\\" + postedFile.FileName);
                // Also, get the file size and filename (as specified in
                // the HTML form) for each file:
                summary += "<li>" + postedFile.FileName + ": "
                    + postedFile.ContentLength.ToString() + " bytes</li>";
            }
            summary += "</ol>";
            // If there are any form variables, get them here:
            summary += "<p>Form Variables:</p><ol>";
            //Load Form variables into NameValueCollection variable.
            NameValueCollection coll = Request.Form;
            // Get names of all forms into a string array.
            String[] arr1 = coll.AllKeys;
            for (i = 0; i < arr1.Length; i++)
            {
                summary += "<li>" + arr1[i] + "</li>";
            }
            summary += "</ol>";
            divContent.InnerHtml = summary;
        }

 

We use the following code for the page that provides the commands for the Unity 3D game. This page is calling the OData service reference we created:

 

        protected void Page_Load(object sender, EventArgs e)
        {
            string strResponse = "";
            // Create DataContext
                ODataServiceReference.ApplicationData objApplicationData =
                    new ODataServiceReference.ApplicationData(
                        new Uri(string.Format(@"{0}applicationdata.svc/", BaseSiteUrl)));  
            
            // Query OData source
            var objUnity3DCommand = (from Unity3DCommands in objApplicationData.Unity3DCommands
                                     where Unity3DCommands.Processed == false
                                     orderby Unity3DCommands.CreatedDate
                                     select Unity3DCommands).FirstOrDefault();
            if (objUnity3DCommand != null)
            {
                // Get the command
                strResponse = objUnity3DCommand.Command;
                // Update Processed
                objUnity3DCommand.Processed = true;
                objApplicationData.UpdateObject(objUnity3DCommand);
                // Save changes 
                objApplicationData.SaveChanges(System.Data.Services.Client.SaveChangesOptions.Batch);
            }
            // Return command as the response
            Response.Write(strResponse);
            Response.End();
        }

 

(note: see: Calling LightSwitch 2011 OData Using Server Side Code for an explanation of the process to add .aspx pages to the project file)

 

image

The main screen allows us to see the screen shot from the Unity 3D game and to issue commands.

When the user requests a screen shot, the following code inserts a record into the Unity3DCommand entity and saves it:

 

        partial void SendPicture_Execute()
        {
            Unity3DCommand objUnity3DCommand = Unity3DCommands.AddNew();
            objUnity3DCommand.Command = "SendPicture";
            this.Save();
        }       

 

The Unity 3D game reads the command, and sends the screen shot, and the following code is used to display it in a LightSwitch Static Image control:

 

        private void SetImage()
        {
            // Make a new Bitmap
            BitmapImage myImage = new BitmapImage();
            // Get the "screenShot.png" sent by Unity3D
            string strWebPageURL = String.Format(@"{0}{1}",
                GetBaseURL(),
                "screenShot.png");
            // Create a random string to add to the image to prevent it from being cached
            string strRandomText = String.Format(@"?param={0}",
                DateTime.Now.Ticks.ToString());
            // Set the Image
            myImage.UriSource = new Uri(strWebPageURL + strRandomText, UriKind.RelativeOrAbsolute);
            UnityImageControl.Source = myImage;
        } 

 

For a text message, the following code is used to open a modal window:

 

        partial void SendMessage_Execute()
        {
            this.OpenModalWindow("EnterMessage");
        }

 

The following code is used to save the message and close the modal window:

 

        partial void SaveMessage_Execute()
        {
            Unity3DCommand objUnity3DCommand = Unity3DCommands.AddNew();
            objUnity3DCommand.Command = this.Message;
            this.Save();
            this.CloseModalWindow("EnterMessage");
            this.Message = "";
        }

 

LightSwitch Without Borders

This solution is actually ‘low tech’. It uses simple communication over normal HTTP protocols. This avoids most network and firewall complications and issues. This is intended to demonstrate that LightSwitch is not just for simple forms over data applications, it can easily integrate into complex applications and deployments.

A few things to note about the example code:

  • The account the web server is running under needs create and write permission to save the screenshot.png file that is sent by the Unity 3D game.
  • If you publish the Unity 3D game to the web player, you will need to run the app in the same domain as the LightSwitch application or create a cross domain policy file and place it in the root directory of the LightSwitch application.
  • The Unity 3D game will go to sleep and not process any commands if it does not have the focus. To properly test this application you need to use two different computers or switch to the Unity 3D game and click on the play area to get it to respond to the commands from LightSwitch.

 

Also See

Shape Your LightSwitch OData Using WCF RIA Services

A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

A Full CRUD LightSwitch JQuery Mobile Application

Calling LightSwitch 2011 OData Using Server Side Code

Communicating With LightSwitch Using Android App Inventor

Using The OData Explorer with LightSwitch OData

Learn How To Make OData Calls In LightSwitch 2011

Accessing Your Visual Studio 2011 LightSwitch Application Using OData

A LightSwitch Netflix OData Mash-up

Download Code

The LightSwitch and Unity 3D source code is available at:

http://lightswitchhelpwebsite.com/Downloads.aspx

Tags: OData
Categories:

5 comment(s) so far...


Gravatar

Re: Using Visual Studio LightSwitch To Orchestrate A Unity 3D Game

Thanks so much

By Arshiyan on   5/1/2012 9:05 AM
Gravatar

Re: Using Visual Studio LightSwitch To Orchestrate A Unity 3D Game

Hi~ I'm Taesoon and Korean Develoments Android & Unity3D

I'm download sample project(LsUnity3DController) and I'm want to debugging this sample project(LsUnity3DController) in My VisualSutudio2012.

But.... At dragging and load LsUnity3DController.sin file, and in to processing the version coverting.... an error occured ;;

error log is ↓

Message
Error LsUnity3DController\LsUnity3DController.lsproj: The application which this project type is based on was not found. Please try this link for further information: http://go.microsoft.com/fwlink/?prd=12395&pver=11&sbp=ProjectTypeDeprecated&plcid=0x409&clcid=0x409&ar=MSDN&sar=ProjectCompatibility&o1=ECD6D718-D1CF-4119-97F3-97C25A0DFBF9

Why this error occured;;

Please hemp me... I'm very tired;;; from this problem;;;

p.s : sorry, I'm very be a poor at English.;;;;

By TaeSoon on   7/4/2013 4:18 AM
Gravatar

Re: Using Visual Studio LightSwitch To Orchestrate A Unity 3D Game

how do change ODataServiceReferenceURL?

I'm try to add the AddReference and my localhostInput in server...

but... ODataServiceReference is already exist... in LsUnity3DController Project;;;

By JAVAHell on   7/4/2013 3:45 AM
Gravatar

Re: Using Visual Studio LightSwitch To Orchestrate A Unity 3D Game

@TaeSoon - I just downloaded the code and it did the upgrade and it worked fine for me.

By Michael Washington on   7/4/2013 4:26 AM
Gravatar

Re: Using Visual Studio LightSwitch To Orchestrate A Unity 3D Game

@JAVAHell - Delete the reference and recreate it.

By Michael Washington on   7/4/2013 4:27 AM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation