DualShock Simulate Controller

Something is waving underneath.

I ask myself again and again for :”How is my life goanna be like when I am 50?”

Will I be rich? Will I be healthy? Will I still be what I wanna be?

Well, that’s another story.

The project need to ,in a short term,be presented like an FPS game. Deploys to Windows/macOS/WebGL/Android/iOS. To all the device which can use mouse/keyboard as the IO, that’s not a problem. Move the character with W/S/A/D and rotate the view by mouse moving is a common solution pack.

But when it comes to touch screen mobile devices. I need to emulate a controller to let user to control the character.

This is how it looks like.

CN Controls

As you see, I need a 2D layer to contain the controller joysticks. I use to implement a joystick with Actionscript and TypeScript. But thankfully, I found a free package called CN Controls. It contains several prefab.

The one named “SensitiveJoystick” is the one that I was looking for. It can react thumbs dragging and instead of sticking on a point, it will follow your thumb to drift a little bit. That’s pretty much comfortable for a mobile phone user. I think about it a little bit.

The reason why you feel uncomfortable when you drag the static joystick away is because the tray is still remain the same place. But most of the time the knob is under you thumb. You can’t see it and feel it (compare this to a physical controller, you can avoid watching them when you get familiar to the layout of the buttons, cause you can touch and feel them). That make you feel you did’t make any change to the controller.

Another thing is, if the tray perform a tiny move towards to the direction of the knob. Then you can identify the situation about your control and the previous movement will help you to predict what is going to happen.

After you release the knob, it will bounce back to the original position. That keeps the experience from an Arcade game console’s joystick. That’s what’s call “natural emulation”.

Steps to add single Joystick

Unity provides a standard assets pack “CrossPlatformInput”, because I am using the character prefab “RigidBodyFPSController”, they belong to the same series. So if you use CrossPlatformInput.MobileSingleStickControl, you will find it works for character movement. That’s the point where we can manipulate and replace.

  • Drag single SensitiveJoystick prefab to the hierarchy window, unity will add a canvas and a EventSystem object additionally. If you run the game now, nothing is gonna change except a Joystick appeared on the left bottom corner.

  • Find the scope which implementing the transform happens. If you’re using RigidBodyFPSController like me ,open the RigidbodyFirstPersonController.cs in the editor. Locate to the postion where “CrossPlatformInput” works. Like this:

    1
    2
    3
    4
    input = new Vector2 {
    x = CrossPlatformInputManager.GetAxis ("Horizontal"),
    y = CrossPlatformInputManager.GetAxis ("Vertical")
    };

    ​This is where the movement comes to play.

  • Replace the code by:

    1
    2
    3
    4
    5
    6
    7
    // import the lib on the top of the class
    using CnControls;

    input = new Vector2 {
    x = CnInputManager.GetAxis ("Horizontal"),
    y = CnInputManager.GetAxis ("Vertical")
    };

    Now run the game and you’ll see the joystick dragging make the character move like an ALS patient.

Steps to add Dual Joystick.

Unfortunately, both of these two pack haven’t got a dual shock prefab. You have to do it by yourself. The joystick on right is for rotating the camera. In another words, your sight.

  • Drag another SensitiveJoystick in or simply duplicate the current one.

  • Move it to the right bottom corner. Select it in the view choose the “Anchor presents” to bottom right. Set the x position to minus the component width.

    )

  • Let’s select the Joystick and check out the Inspector, under Componet “Sensitive Joystick”, the “Horizontal Axis Name” and “Vertical Axis Name” is the ones I should change, or it will affect the game in the same way to the left one. Let me rename them to “Horizontal_R” and “Vertical_R”.

  • Let me find out the place where the original code do the stuff. It’s in the MouseLook.cs (Nice naming!)

    1
    2
    yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
    xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;
  • The same way, replace them to CnInputManager.

    1
    2
    yRot = CnInputManager.GetAxis("Horizontal_R") * XSensitivity;
    xRot = CnInputManager.GetAxis("Vertical_R") * YSensitivity;
  • Now if you run the game, you’re gonna receive errors

    1
    2
    ArgumentException: Input Axis Horizontal_R is not setup.
    ArgumentException: Input Axis Vertical_R is not setup.

    It’s easy to solve, Edit -> Project Setting -> Input.

    In the input defination panel, duplicate “Horizontal” and rename it to “Horizontal_R”. Repeat it on “Vertical_R”. Now you should get it work for the character control.

Platform Adapting

The Control panel should only work on mobile device, here’s the way to confirm:

1
2
3
4
5
6
7
8
9
float yRot,xRot;
if (Application.platform == RuntimePlatform.Android ||
Application.platform == RuntimePlatform.IPhonePlayer) {
yRot = CnInputManager.GetAxis("Horizontal_R") * XSensitivity;
xRot = CnInputManager.GetAxis("Vertical_R") * YSensitivity;
}else{
yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;
}

Not covering all the conditions.