-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added touchscreen joystick tutorial (#454)
* Outline * WIP * Added buttons section * Update content/en/tutorials/touch-joypad.md * Update content/en/tutorials/touch-joypad.md * Fixed mouse and touch links Co-authored-by: Steven Yau <[email protected]>
- Loading branch information
1 parent
84365c4
commit d720ef0
Showing
13 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
--- | ||
title: Touchscreen Joypad Controls | ||
layout: tutorial-page.hbs | ||
tags: input,ui | ||
thumb: https://s3-eu-west-1.amazonaws.com/images.playcanvas.com/projects/12/1007506/2F5E56-image-75.jpg | ||
--- | ||
|
||
<iframe loading="lazy" src="https://playcanv.as/p/kvE0iJWc/" title="Touchscreen Joypad Controls"></iframe> | ||
|
||
[Click here to see the project][project-link]. | ||
|
||
## Overview | ||
|
||
This tutorial shares a Touchscreen Joypad library that can be installed and customized for any project that needs touch screen controls. | ||
|
||
We recommend reading about the [PlayCanvas UI system][playcanvas-ui] if you have not used it before as it is used to render and position the controls for this library. | ||
|
||
![][preview] | ||
|
||
## How to install | ||
|
||
Open the [example project][project-link], right click on the folder 'touch-joypad' and click on 'Copy'. | ||
![][copy-folder] | ||
|
||
Open your project, right click in the assets panel and click on 'Paste' | ||
![][paste-folder] | ||
|
||
## Adding your joystick | ||
|
||
In the folder we've just pasted, open the 'templates' folder and there will be 4 preconfigured templates for the joysticks to cover the most common use cases. | ||
|
||
* **Left/Right Fixed Touch Joystick** - A fixed joystick that is anchored to the bottom left/right of the screen corners. Recommended for quick reaction games where an instant response is expected such as a retro platforming game. | ||
* **Left/Right Half Touch Joystick** - A joystick where the input area the left/right half of the screen and the joystick will move to where you touch in that area and them requires dragging for movement. Recommended for when 'pushing' or 'pulling' an object in the application. | ||
|
||
For this example, let's use the 'Left Half Touch Joystick' template. | ||
|
||
Create a 2D screen Entity and [add the template][add-template-docs] as a child of the screen Entity. | ||
|
||
![][adding-left-half-joystick] | ||
|
||
The joystick is made of three Entities: | ||
|
||
- Input area (outlined in red) | ||
- Base (outlined in blue) | ||
- Nub (outlined in blue) | ||
|
||
![][joystick-layout] | ||
|
||
The input area will listen for touch and mouse (for debugging purposes) events and also stops the propagation of the event. | ||
|
||
This means that any UI Elements under this and any [pc.Mouse][pc-app-mouse-api] or [pc.Touch][pc-app-touch-api] events will not be fired if this area is interacted with first. | ||
|
||
As the input area is an UI Element, it can be positioned, sized and anchored specifically for your needs via the [UI system layout][elements-manual]. | ||
|
||
It also has the 'touchJoystick' which has all the logic and attributes for the joystick. Each attribute has tooltips describing what they are for with some more details below. | ||
|
||
![][joystick-script-attributes] | ||
|
||
The base and nub Entities are controlled by the script and are UI Elements. If you would like the joystick to be in a different place than where it is in the template, please position and anchor the base Entity to where you need them to be and not the input area. | ||
|
||
### Behavior Types | ||
|
||
There are 3 behavior types for the joystick that are commonly found in touch screen games and applications. | ||
|
||
![][joystick-type] | ||
|
||
'Fixed in place' where the base of the joystick does not move from it's position: | ||
![][joystick-fixed] | ||
|
||
'Move to first touch and fixed' where the base of the joystick moves to where the user first touches in the input area and then stays fixed: | ||
![][joystick-relative-fixed] | ||
|
||
'Move to first touch and drags' where the base of the joystick moves to where the user first touches in the input area and then is dragged when the user drags pass the joystick range: | ||
![][joystick-relative-drag] | ||
|
||
This can be changed at runtime so it's possible to add this as a user option in the application as part of the in-application settings. | ||
|
||
### Reading joystick values | ||
|
||
![][joystick-deadzone-range] | ||
|
||
The red circle is dead zone and if the nub position is within that circle, the value from the joystick will return 0 for both axes. The blue circle is the range and the nub cannot go outside that circle. | ||
|
||
The values are always normalized between -1 and 1 on both axes based on the where the nub is between the dead zone (red circle) and the range (blue circle). | ||
|
||
The size of the circles can be set in the Editor via the script attributes. | ||
|
||
Joystick values can accessed in code from the global Javascript object `window.touchJoypad.sticks` with the identifier. By default, the identifier is 'joystick0' but can be changed in the Editor on the script to be more specific. | ||
|
||
Example code: | ||
|
||
```javascript | ||
// Get the joystick by the identifier from the global object | ||
var joystick = window.touchJoypad.sticks['joystick0']; | ||
|
||
// Get the normalized values of both joystick axes and print to console | ||
console.log('X: ' + joystick.x ', Y: ' + joystick.y); | ||
``` | ||
|
||
[In the demo][project-link], the camera is controlled by the right joystick and you can see how it gets and uses the values in the [script here][orbit-camera-joypad-input-script]. | ||
|
||
|
||
## Adding your buttons | ||
|
||
Buttons are fixed position UI Elements on the screen. There is a template for button in the 'templates' folder and [should be added][add-template-docs] as a child of the screen Entity. | ||
|
||
![][adding-button] | ||
|
||
As they are UI Elements, they can be positioned, sized and anchored specifically for your needs via the [UI system layout][elements-manual]. | ||
|
||
Like the joysticks, they have an identifier so they can be accessed in code from the global Javascript object `window.touchJoypad.buttons` with the following API. | ||
|
||
| Function name | Description | | ||
|---------------|-------------| | ||
| isPressed | Takes the button identifier and returns true if the button is currently being pressed. | | ||
| wasPressed | Takes the button identifier and returns true if the button was pressed since the last frame. | ||
| wasReleased | Takes the button identifier and returns true if the button was released since the last frame. | | ||
| wasTapped | Takes the button identifier and returns true if the button was pressed and released within 200ms. i.e. A quick tap. | | ||
|
||
The joysticks are also buttons which gives extra flexibility in how they can be used. For example, using the `wasTapped` API with a joystick identifier can act like a L3/R3 input on a PlayStation controller. | ||
|
||
Example code: | ||
|
||
```javascript | ||
// Get the button global object | ||
var buttons = window.touchJoypad.buttons | ||
|
||
// Check if the button was pressed since the last frame | ||
console.log('Was pressed: ' + buttons.wasPressed('button0')); | ||
``` | ||
|
||
[In the demo][project-link], the character is controlled by the left joystick and buttons. You can see how it gets and uses the buttons in the [script here][player-controller-script] to play attack animations. | ||
|
||
|
||
[project-link]: https://playcanvas.com/project/1007506/overview/touchscreen-joypad-controls | ||
[playcanvas-ui]: /user-manual/user-interface/ | ||
[copy-folder]: /images/tutorials/touchscreen-joypad-controls/copy-folder.gif | ||
[paste-folder]: /images/tutorials/touchscreen-joypad-controls/paste-folder.gif | ||
[preview]: /images/tutorials/touchscreen-joypad-controls/preview.gif | ||
[add-template-docs]: /user-manual/templates/#adding-templates-in-your-scene | ||
[adding-left-half-joystick]: /images/tutorials/touchscreen-joypad-controls/adding-left-half-joystick.gif | ||
[adding-button]: /images/tutorials/touchscreen-joypad-controls/adding-button.gif | ||
[joystick-layout]: /images/tutorials/touchscreen-joypad-controls/joystick-layout.png | ||
[pc-app-mouse-api]: /api/pc.Mouse.html | ||
[pc-app-touch-api]: /api/pc.Touch.html | ||
[elements-manual]: /user-manual/user-interface/elements/ | ||
[joystick-script-attributes]: /images/tutorials/touchscreen-joypad-controls/joystick-script-attributes.gif | ||
[joystick-fixed]: /images/tutorials/touchscreen-joypad-controls/joystick-fixed.gif | ||
[joystick-relative-fixed]: /images/tutorials/touchscreen-joypad-controls/joystick-relative-fixed.gif | ||
[joystick-relative-drag]: /images/tutorials/touchscreen-joypad-controls/joystick-relative-drag.gif | ||
[joystick-type]: /images/tutorials/touchscreen-joypad-controls/joystick-type.png | ||
[joystick-deadzone-range]: /images/tutorials/touchscreen-joypad-controls/joystick-deadzone-range.png | ||
[orbit-camera-joypad-input-script]: https://playcanvas.com/editor/code/1007506?tabs=111433673 | ||
[player-controller-script]: https://playcanvas.com/editor/code/1007506?tabs=111432679 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+756 KB
public/images/tutorials/touchscreen-joypad-controls/adding-left-half-joystick.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+10.9 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-deadzone-range.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+288 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-fixed.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+55.8 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+131 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-relative-drag.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+182 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-relative-fixed.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+568 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-script-attributes.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+23.9 KB
public/images/tutorials/touchscreen-joypad-controls/joystick-type.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.