Easy WiFi Controller- Turn your mobile phone into a controller!

They are. I’ll give more context about the project that hopefully makes it a bit clearer what I’m after.

The project is a local multiplayer racing game. It’s already set up to allow up to eight players using hardware joypads. We’re using the Rewired asset to facilitate some of this, and piping EasyWifi controller input into ‘custom controllers’ (really ‘virtual controllers’) exposed by Rewired. So we want to allow smartphone control too. We also want it to be possible to have matches where some players use joypads, and other use smartphones. We also want to create logic to preserve player colour between races (if you start again using the same smartphone as last time, you’ll usually be assigned the same color).

To test this stuff is working properly it’d be great if i could have multiple wifi clients running on my local machine.

Edit: Originally, I thought this was going to be possible to assist your Dev enviroment but it’s not. Explanation below.

The underlying technology that Easy WiFi Controller uses (UDP sockets) does not allow multiple applications on the same machine with the same controls to bind to the same port and keep unexpected behaviours from happening. In your final game this sharing is not desired anyways since each player has their own phone. Even if multiple apps bind to the same port it would have unfavorable results because the apps would be in a race to get to the messages on that same port first and it would never be guaranteed which one would see it. While certainly projects can be designed from the ground up to accommodate this (each client using its own port, listener, thread), it unfortunately cannot both accommodate this and have auto discovery in a fast and efficient manner.

Auto discovery is a core pillar of the application (it helps everyone not need to worry about the networking and each piece will find each other automatically on the same WiFi).The auto discovery in the project works because known ports are used for the traffic (these are what you set in Easy Wifi Manager in the inspector). This is also why you see two entries in the Easy wifi manager so that you can have the client and server on the same machine in a development environment but not multiple clients (because they’d be fighting over the same traffic). While in general you can extrapolate this out and have client 1 port, client 2 port, client 3 port, etc. you lose the Auto Discovery when you do this with the current design and it would require a complete rewrite of the projects core networking code to do this. Even if I was to rewrite the core code, I don’t think I would choose to do so because the underlying foundation would increase with every client connected. I suspect that this foundation (especially the number of threads required) would make the 16 players not achievable. Given the choice between supporting up to 16 players and having a development mode not require more than 1 phone/laptop for multiplayer testing, I would again choose the 16 players.

Sorry to get your hopes up at first I thought this was going to be doable.

That would be perfect! Thanks so much.

I have had a few inquiries so far so I figured I would mention it here. Easy WiFi Controller does work with the new Apple TV. I was able to test it fully recently on a dev kit and it works without issue.

Ah I understand. Thanks for the update. Perhaps it might be worth adding a brief note to the documentation somewhere clarifying that one wifi client will work on the same machine acting as host, but not multiple instances.

Certainly will update the documentation, thanks for understanding.

I certainly do plan to still implement the other items in the next update (and a few other things). These include:

  1. A new example scene showing a typical controller select menu scene that launches a simple game scene. This will include example code on how to change the player number at runtime

  2. An “any player” option in addition to the current player 1 - 16 (this is useful for menus).

  3. A much improved connection system. You will no longer in development need to restart the controller app on server only build changes.

  4. Other miscellaneous improvements

This is currently in testing and I hope to have it live on the store in a 1-2 weeks.

Thanks. A separate thing: I’m trying to use a backchannel to set the background color of the wifi client scene (just once, when a player ‘joins’ a race) and things aren’t going as i expected. Before I explain more i have a quick question:

In the client, the method i’ve designated as ‘Notify Method’ seems to be being called every frame, even when I strip away all code in my project (host or client) that I thought would result in in being called. Is this expected behaviour?

It is expected behavior currently most of our controls are setup to be pumped out every frame kind of like telemetry. I can certainly add a enum to the inspector so you can easily switch the common modes you might want (call every frame or only when changed). These modes don’t make sense for a joystick, touchpad, etc. because generally you want to move your player every frame, but they do for buttons, switches, etc. It never hurts to have options though so I’ll add these to all the backchannels in the next update. If you don’t want to wait you can employ the same pattern now that you see in CustomButtonServerController.cs into the client backchannel you’re using currently. I’ll certainly include this in the next update.

Ah i see. I tried modifying StringServerBackchannel.cs in the way you suggested, but it looks like I also need to modify at least StringClientBackchannel.cs too (?). I’ve gotten stuck so I guess I’ll wait for the update. Thanks!

That pattern should be on the receiving end, not the sending end. For buttons or any other forward channel it should be on the server, but on a backchannel going the other way it should be on the client. If you add the follwing to StringClientBackchannel.cs it should work (you don’t need to change StringServerBackchannel).

at the top after the other declarations

[Tooltip("Determines when your Notify Method gets called")]
public EasyWiFiConstants.CALL_TYPE callType = EasyWiFiConstants.CALL_TYPE.Every_Frame;
string lastValue = "";

and change the following method like below:

  public void mapDataStructureToMethod()
  {
          if (callType == EasyWiFiConstants.CALL_TYPE.Every_Frame)
              SendMessage(notifyMethod, stringBackchannel, SendMessageOptions.DontRequireReceiver);
          else
          {
             if (!lastValue.Equals(stringBackchannel.STRING_VALUE))
             {
                 SendMessage(notifyMethod, stringBackchannel, SendMessageOptions.DontRequireReceiver);
             }
             lastValue = stringBackchannel.STRING_VALUE;
          }
  }

Then just flip the inspector on the object in question to “only when changed” from “every frame” and it should behave like you expect. I’ll certainly add this to the string backchannel in the next update.

[EDIT]
I’ve managed to get this working as expected in a much simpler test scene. So this is very probably a mistake I’m making elsewhere in my code. Please disregard the following!

Thanks for this. I’ve made the change you explained. I’ve set up a simple test to try to get it working.
In the script attempting to send backchannel data changes to the wifi client i have the following:

public EasyWiFi.ServerBackchannels.StringServerBackchannel stringBackchannel;
// And later...
string s = "TEST"+Random.value;
Debug.Log("About to send: "+s);
this.stringBackchannel.setValue(s);

And on my client the notify method looks like this:

public void ChangeBackgroundColor (StringBackchannelType s) {
cam.backgroundColor = new Color(Random.value,Random.value,Random.value);
}

The notify method appears to be running as soon as the client initialises (i get a different random coloured background each time i open it), but does not change when I set the value of this.stringBackchannel from the host. I do get the expected Debug trace at that moment, so that code is getting executed.

I’ve double checked that the control name and notify method are set correctly. And I have the StringClientBackchannel monobehaviour on my client set to Only_When_Changed.

I realise this might be difficult to troubleshoot from your end, but perhaps you see some obvious mistake I’m making. Thanks in any case for your help so far!

Glad you got it working. If you have any other questions don’t hesitate to ask.

Hi greggtwep16.

I bought your asset today but didn’t had much time to play with it.
I hope to do so in the next days.

Do you believe that it would be possible to send screenshots of the game to the mobile device?

In general the product is mainly geared towards using your phone as a controller. To facilitate this messages are sent out every frame and should be less that 512 bytes (half of 1 kb) since they are being pumped out once a frame. So in general, no the product is not setup for this.

That being said in some instances it could be done but would require modification of the product. In addition Easy WiFi Controller is setup to handle up to 16 devices as a controller (hence the small data requirement) but if your game is single player a normal wifi should be able to handle image data sizes but certainly wouldn’t scale to 16 (I’d be shocked with data that large if it would even get to 4 if you made this modification).

Are you thinking static images once in awhile or more like a second screen?

Well I am thinking something like a stream of the game with highly compressed images. For one player.
They don’t have to be ent every frame.

I am developing a native jpg plugin that could make a lossy compression of a scaled down frame every 0.1 seconds.

I am not asking you to implement this. Some directions on how to do this with your plugin would be enough.

Edit: Perhaps it could be done via sockets. This guy did it this way:

Regardless of the data being sent in Easy WiFi Controller you would use a backchannel control to send information back from the game to controller. You would simply create a ImageBackhannel type and you could model it off the other ones that are already present.

Although stepping back from my product and just talking about your usecase in general in just Unity terms, I don’t think you are going to be able to do what you want fast enough. I originally wanted to make a product pretty similar to what you describe and it just didn’t cut it. The problem is going to be in making the images fast enough to not tank your framerate. Even on a powerful PC and even scaling the images down to low resolution it simply is fighting the natural flow of CPU → GPU and you are wanting to send data back from GPU → CPU. There are several ways to accomplish this (render textures, OS level screenshots, Graphics API specific calls, etc) but in many tests several months ago each effectively even in simple scenes lowered the FPS to about 10. This essentially isn’t good enough for a stream.

Things may have changed or maybe I overlooked something, so as always I encourage you to try maybe you’ll have success, but I certainly wasn’t able to find a effective solution. If you do succeed don’t hesitate to let me know how you accomplished that to because I’m interested in the topic as well.

Are you having luck with your native .jpg plugin and able to keep a high FPS when outputting the screen to it every frame, every other frame, etc?

1 Like

Ok. Thanks for the detailed info and directions!

Of course if I have something I will post it here.

I try to use the Custom Touchpad Server Controller, to call a script that I made. But even if my phone is connected and the console receive the position of the touch input of my phone, the touchpad variable stay null. So I can’t call my function. Any idea ?

The Drawing example scene has an example of the Custom Touchpad Server Controller but the obvious things to check are the following.

  1. The touchpad client control and the server control have the same control name
  2. The function you want it to call is on the same gameobject

If both of these are set I’ll certainly need more information. The fact that it’s in the console though means the data is getting there it’s just not getting hooked up to your object. Most likely it’s one of the above.

Thanks, my control and my function were on the same object. I got confused because in the painting demo scene the touchpad controller and the paint function ar on the same game object.