Escape From a Moon: Creating a Rotating 2D Platformer in Unity (1)

itch.io | GitHub

It’s been some time since Ludum Dare 38 and I wanted to make some improvements to my Compo entry, called Escape From A Moon (you can take a look at Ludum Dare rules if you don’t know what I am talking about), so I worked on them and not long ago I released Escape From A Moon v0.2. You can find the devlog here. Now that this new version is out, I have decided it is time for me to explain a little bit about how this small prototype game works.

You might think this is a fairly simple game and there is not much to explain. Well, that’s basically true 😀 but it’s also true that developing a platformer with a rotating environment can be challenging and is much more difficult than a “normal” one. I will explain this later, but first of all I want to clarify: I am not saying this is something new or revolutionary, and I didn’t look for examples of what I wanted to achieve either, so there may be better approaches than the techniques I’m going to share here, but I want to share them anyway. I will split the explanation into several posts, so this first post will only contain the basics.

Just one more thing: let me remind you all this is an open source project so you can download the source code, use it, and collaborate on it if you want. Now let’s start.

 

 A circular environment

This is the whole environment of the game

Inspired by the LD38 theme (Small World) and with not much originality, Escape From A Moon takes place in a very small satellite. The player controls an astronaut who needs to walk and jump around in order to reach his spaceship before he runs out of oxygen. A peak prevents the astronaut from taking the short way, forcing him to encompass the whole satellite.

The rotation in Escape From A Moon is real. This is: it’s not a visual trick by which I am rotating the background instead of moving the character. I didn’t do such thing because I don’t think physics would work properly, it would have limited extensibility (what if I wanted to add the ability to move to a different satellite or planet?) and the result would have been much less intuitive from the development perspective. But, making the character walk around the satellite has some important implications. Let’s go through all of them.

 

#1 Vertical orientation

For the character, the vertical orientation depends on the position on the planet. Which means, the vertical orientation can be constantly changing. Knowing the vertical orientation is important for things like jumping: a jump is basically the result of applying a force in the direction of the character’s vertical orientation.

Vertical orientation is defined by the vector that goes from the center of the planet to the character’s position

To get the vertical orientation vector, just subtract its origin (planet’s center) from its tip (character’s position). So, in the Character script:

Vector3 _direction = transform.position - planet.transform.position;
upDirection = new Vector2 (_direction.x, _direction.y).normalized;

In this case, we are also storing its normalized, 2D version, as we will need it later.

 

#2 Horizontal movement

Intuitively, we can think of horizontal movement as the one that is parallel to the ground (assuming the ground is horizontal), or perpendicular to our vertical orientation. But in a circular environment, both the vertical orientation of the character and the ground’s orientation depend on the position within that environment. So, in order to know in which direction to move the character, we need to calculate it.

As mentioned above, the horizontal direction is perpendicular to the vertical one. Given we have already calculated the vertical direction vector, we can get the horizontal direction from it.

Looking at the character with a 3D perspective, we can see the trick. The red arrow is the vertical direction. The blue arrow is the depth direction, which is fixed. The green arrow is the direction we want to calculate.

As you can see in the image, we already have two direction vectors: the vertical and the depth ones. The horizontal vector is perpendicular to them both, so we can get it by calculating their cross product. Leveraging the _direction vector we got earlier:

Vector3 _walkVector = Vector3.Cross (Vector3.back, _direction).normalized;
Vector2 _walkDirection = new Vector2 (_walkVector.x, _walkVector.y);

 

Conclusions

We have seen here how by applying simple vector arithmetics we can get the information we lack because of the nature of the game. Now we have both the direction in which to apply the jump force, and the direction in which to apply the walk force. More on this, in a future post.

Some polymorphism in C#

I was watching an online C# 6 course by Jesse Liberty and then decided to play a little bit with inheritance, polymorphism, and method binding. The result of that was a Gist that you can see below.

 

Essentially, C# works pretty much like C++ in the sense it supports both static and dynamic binding, but C# forces the programmer to be more explicit:

 

  • When hiding a method from a subclass, which we could refer to as overriding with static binding, we will get a compiler warning unless we make the method hiding explicit with new:

Warning CS0108: 'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended. (CS0108)

 

  • When overriding a method from a subclass, which we could refer to as overriding with dynamic binding, the first requisite is having the base method declared as virtual (otherwise, there will be a compiler error). Apart from this, we will get another warning unless we make the overriding explicit with override:

Warning CS0114: 'B.Foo()' hides inherited member 'A.Foo()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. (CS0114)

This basically means that binding will always be static unless we tell the compiler we want to make it dynamic with override. This is an important difference with C++, as in C++ once a base method has been declared as virtual, it will always be dynamically bound.

 

Take a look at the Gist with the examples here:


using System;
namespace PolymorphismDemo
{
public class A
{
public virtual void Foo() => Console.WriteLine("A.Foo()");
}
public class B : A
{
public new void Foo() => Console.WriteLine("B.Foo()"); // Static binding (hiding)
}
public class C : A
{
public override void Foo() => Console.WriteLine("C.Foo()"); // Dynamic binding (overriding)
}
/*public class D : A // WARNING: new or override required
{
public void Foo() => Console.WriteLine("D.Foo()");
}*/
public class E : C
{
public sealed override void Foo() => Console.WriteLine("E.Foo()"); // C.Foo() is implicitly virtual
}
/*public class F : E // ERROR: sealed method cannot be overridden
{
public override void Foo() => Console.WriteLine("F.Foo()");
}*/
public class G : E
{
public new void Foo() => Console.WriteLine("G.Foo()"); // … but it can be hidden
}
class MethodOverridingDemo
{
static void Main(string[] args)
{
A thing = new A();
B thing2 = new B();
C thing3 = new C();
A thing4 = thing2;
A thing5 = thing3;
A thing6 = new E();
A thing7 = new G();
thing.Foo(); // A.Foo()
thing2.Foo(); // B.Foo()
thing3.Foo(); // C.Foo()
thing4.Foo(); // A.Foo()
thing5.Foo(); // C.Foo()
thing6.Foo(); // E.Foo()
thing7.Foo(); // E.Foo()
}
}
}

Tested in Visual Studio Community (C#6). This code does not work directly in Unity as Expression-bodied members were introduced in C#6 and Unity uses C#4 at this point. I have created an alternative Gist, adapted to Unity.

Countless v2.0: a big update

 

App Store EnGoogle Play En

Press Kit

 

Over 5 months after the first release of Countless, a big update, the version 2.0, is available. This new version features lots of additions and improvements:

  • Use shields to protect you against mistakes
  • Collect coins to buy shields and skins
  • Multiple different skins to unlock
  • Fully revised difficulty curve
  • Improved touch response: now you can touch two pieces at the same time
  • Ads are now less annoying and give more rewards
  • Many visual improvements
  • By popular demand, now you can leave the name empty when you make a new record

Countless was born as a simple project with the idea of learning how to use Unity game engine, as well as being able to release a game in a short period of time. There were no plans to expand it very much, and I only planned to maintain it by fixing issues from time to time while I was working on a new project. But once I saw the game actually released and received feedback, I decided I needed to do some important changes, and here they are. Let’s take a detailed look into some of them.

Difficulty Curve

The original difficulty curve was very abrupt. It rapidly reached the most difficult point and stayed there for the rest of the game.

Here you can see how after just a few seconds, the board passes from 2x2 to 4x4 and the time per level is decreased to the minimum
Here you can see how after just a few seconds, the board passes from 2×2 to 4×4 and the time per level is decreased

In order to get a friendlier, more progressive difficulty curve, and at the same time offer a more challenging gameplay to those who manage to reach advanced levels, the progress in the game has been meticulously adjusted.

With the new, adjusted difficulty curve, the board increases its complexity in a much smoother way

Items

The game now allows you to collect two different item types: coins and shields. You can get coins in multiple ways (playing, viewing ads, and even as a gift!). With them, you will be able to buy shields and unlock skins or themes that change the colours in the game. Use the shields when playing to protect you against failures!

Everyday you will get a gift when opening the game

 

See the icon at the bottom left corner? Touch it to open the shop!

 

In the shop you will be able to buy stuff using the coins you have earned. You can also get free coins after watching an ad!

Visual Improvements

Many small visual improvements have taken place: more icons and less text, more color variety, and other improvements to make everything more clear.

Some new icons have replaced the old text markers, and a small separation between pieces in 2×2 boards has been added to improve the look and feel

 

With the new themes you can switch the color scheme to a different one if you have unlocked it

 

New colours have been added to support the new 5×5 boards as well

 

Hopefully this update will make the game much more fun and engaging. Are you enjoying it? Do you have anything to suggest or comment? Please leave a comment at the bottom of this post or use the Contact Form.

See you in the leaderboards!

Testing REST APIs with Postman

Due to my recent work at FinancialForce.com‘s Product Innovation Lab, I have been creating REST APIs, and those APIs needed testing. Initially, I tested them manually, using tools like SOAP UI for POST requests and the browser for GET requests. But soon I needed a way of performing multiple tests, with different sets of data, in short periods of time. And for that, Postman became the ideal tool. To illustrate this, I have created a simple server with an even simpler REST API in Node.js. It is available in this GitHub repo.

 

The example app

The provided example app implements a server that can be started from a terminal with NPM and Node.js installed. After cloning it, simply go to its folder and call this from the command line:

 

[code language=”bash”]
> npm install
> PORT=8080 npm start
[/code]

 

It exposes the following REST API methods:

  • GET /api/v1.0/math/add/<value1>/<value2>
  • GET /api/v1.0/math/subtract/<value1>/<value2>
  • GET /api/v1.0/math/square/<value>
  • POST /api/v1.0/math/accumulate
    • It expects a JSON body with this format:

[code language=”javascript”]
{
"data": <number to accumulate>
}
[/code]

All of them return a JSON object with this format:

[code language=”javascript”]
{
"input": <input data>,
"result": <result value>;
}
[/code]

The REST API methods are defined in src/server.js. If you want more information about Node.js, NPM and how to create servers in Node, these links can be useful:

 

Now let’s start talking about Postman.

 

A powerful UI for testing APIs

Postman screenshot

There is a native app for all major desktop operation systems. And it performs really well, at least on Mac OS X. This app allows to:

  • Define collections of requests
  • Organise them in folders
  • Export collections to JSON files
  • Parameterise requests
  • Define tests for each request
  • Run collections of tests along with their tests in sequence

The last three points are what make Postman so interesting for our purposes. Almost everything in a request can be parameterised, allowing us to reuse requests with variable data. For example, if we want to take the port from a variable (let’s call it LocalhostPort), we just need to put {{LocalHostPort}} in the URL instead of the port. The actual value will be taken from one of these places:

  1. Global Variables. A set of pairs <key, value> defining values for variables, that are available to all requests at every time.
  2. Environment. A ser of pairs <key, value> defining values for variables. One environment, or none, can be selected each time. If a variable with the same name is defined on both the Global Variables and the selected Environment, the latter takes precedence.
  3. Iteration Data. Apart from the Global Variables and the Environment, it is possible to specify Iteration Data when running requests and tests in Postman. Iteration Data contains a list of sets of pairs <key, value>, defining multiple sets of values for the same variables. It is meant to be used in different runs, passing different data for each run. If a variable with the same name is defined on either the Global Variables or the selected Environment, the value from the Iteration Data takes precedence.

All of them can be exported to JSON files. More information about variables can be found here: Setting up an environment with variables.

A full Postman project (if you want to call it that) has been included in the example app, under the postman folder. Simply import the files by clicking Import at the top left => Choose File => select the files and click Open. You can import the collection (with all the requests and their associated tests), the environment (which defines a default value for some parameters to be used in the requests, in case of calling them independently), and the global variables (which defines the port as 8080). The inputData.json file includes data to iterate through when running the requests from the Runner.

 

The Runner

PostmanRunner Screenshot

By clicking the Runner button at the top left of the app, a separate window focused on running collections is opened. There, we can choose one of the collections (or folders inside a collection), an Environment, and optionally, iteration data, to run all of the requests and their tests in sequence. If you have imported everything after the previous section, then you should be able to select the Nodejs-Postman collection and the Nodejs-Postman environment. The global variables will be implicitly applied. Choose the inputData.json file from Data – Select File and click Start Run. If the server is running (if not, you can start it by following the explanation above), the tests should work fine.

 

The tests

A test in Postman is coded in Javascript and can look like this:

[code language=”javascript”]
var resultObject;

try
{
resultObject = JSON.parse(responseBody);
}
catch (ex)
{
console.log("Unexpected response body: " + ex);
console.log(responseBody);

return;
}

function defined(value) { return value !== null && value !== undefined; }

var input1 = Number(defined(data.Input1) ? data.Input1 : environment.Input1),
input2 = Number(defined(data.Input2) ? data.Input2 : environment.Input2);

tests["Request succeeded"] = responseCode.code === 200;
tests["Input included"] = !!resultObject.input;
tests["Input is an object"] = resultObject.input.constructor === Object;
tests["Input 1 is correct"] = resultObject.input.input1 === input1;
tests["Input 2 is correct"] = resultObject.input.input2 === input2;
tests["Correct result"] = resultObject.result === (input1 + input2);
[/code]

This code goes in the Tests section under a request in Postman. Postman provides a simple API that allows us, among other things, to:

  • Get the request’s response data
  • Get Global, Environment and Iteration Data variables
  • Update Environment variables
  • Define tests

All actual tests are defined by adding an entry to the tests object. The key is the test description, and the value is a boolean variable (true if the test succeeded, false otherwise). If nothing crashes, the whole code snippet is run; Postman will raise error information for each test that failed after the script finishes.

More info about Postman tests here: Testing Examples. Other useful links:

 

Newman: a CLI for Postman

It would be great if we could leverage Postman’s testing features in an automated testing workflow and integrate it in a continuous release system. It is perfectly possible thanks to the availability of Newman, a command-line interface for Postman. You can install it through NPM.

 

Newman is compatible with all files Postman can export, and provides nicely formatted results, which ultimately allows us to integrate these tests into any automated workflow or script. An example of a command line running exactly the same tests as above could be:

[code language=”bash”]
> newman run postman/Nodejs-Postman.postman_collection.json –iteration-data postman/inputData.json –environment postman/Nodejs-Postman.postman_environment.json –globals postman/globals.postman_globals.json
[/code]

 

The line above has been included in the postman.sh script, which can be run with:

[code language=”bash”]
> sh postman.sh
[/code]

… which, in turn, thanks to the scripts property in package.json, can be run with:

[code language=”bash”]
> npm test
[/code]

… providing a very straightforward and standard way of running the tests for this app.

 

Authentication

The provided example is very simple and does not require any authentication. A more realistic case will probably need some kind of authentication, typically OAuth. Postman does provide functionality for authentication, but it is also possible to provide the session token, or access token, depending on the authentication system, retrieved by other means. This token can be provided via header. The way of getting it can differ depending on the platform the API we are testing is hosted on. To get the most of this, an automatic way of getting the token and putting it into the header must be sorted out.

 

Conclusions

Postman, and its CLI Newman, have been extremely useful for me while implementing APIs, thanks to their usability, power and performance. I strongly recommend give them a go in case of working with APIs.

Remote Actions: Leveraging class hierarchies to safely pass data

Sometimes, we need our @RemoteAction to be very flexible. This can lead to the necessity of allowing the caller to pass in some arbitrary information. But by doing so, we could be opening a security breach. In this post, I will show an example of this, as well as a possible solution to the security problem. Some knowledge about VisualForce components and remote actions will be needed to follow this.

Say, we want to implement a VF component that takes some data from the org and shows it in a custom picklist. We’d like this component to retrieve data very quickly as the user interacts with it, so we will use a remote action for this.

 
[code language=”xml”]
<apex:component controller="CustomPicklistController">
<apex:attribute name="objectName" description="Object to query from" type="string" required="true"/>

<script type="text/javascript">
function getRemoteData() {
Visualforce.remoting.Manager.invokeAction(
‘{!$RemoteAction.CustomPicklistController.getData}’,
‘{!objectName}’,
function(result, event){

},
{escape: true}
);
}
</script>

</apex:component>
[/code]

 
This is the controller:
[code language=”java”]
public with sharing class CustomPicklistController {

@RemoteAction
public static CustomPicklistData getData(String objectName) {
List<SObject> records = retrieveData(objectName);
CustomPicklistData data = convertData(records);
return data;
}

private static List<SObject> retrieveData(
String objectName
) {
String safeObjectName = getSafeSOQLString(objectName);
String dbQuery = ‘SELECT Id, Name FROM ‘ + safeObjectName;
return Database.query(dbQuery);
}
}
[/code]

 
… where getSafeSOQLString() makes sure no malicious string breaks our query by injecting SOQL code. In the example, there is no filter for the query. We are retrieving all records for the given object.

We want this component to be flexible enough to allow us to set custom specific filters wherever we instantiate it. A first approach would consist of passing the filter text as attribute to the component. This is the definition:

[code language=”xml”]
<apex:attribute name="filterText" type="String" required="false"
description="Filter to append to the query"/>
[/code]

 
The controller would be updated as follows:

[code language=”java”]
public with sharing class CustomPicklistController {

@RemoteAction
public static CustomPicklistData getData(String objectName, String filterText) {
List<SObject> records = retrieveData(objectName, filterText);
CustomPicklistData data = convertData(records);
return data;
}

private static List<SObject> retrieveData(
String objectName,
String filterText
) {
String safeObjectName = getSafeSOQLString(objectName);
String whereClause = String.isBlank(filterText) ? ” : ‘ WHERE ‘ + filterText;
String dbQuery = ‘SELECT Id, Name FROM ‘ + safeObjectName + whereClause;
return Database.query(dbQuery);
}
}
[/code]

 
An example of instantiation for this component can look like:

[code language=”xml”]
<CustomPicklistController objectName="Account" filterText="{!queryCondition}"/>
[/code]

 
… where queryCondition would be something like:

[code language=”java”]
public String getQueryCondition() {
return ‘Name LIKE \’A%\”;
}
[/code]

 
Unfortunately, we cannot apply getSafeSOQLString to filterText, as it is a piece of SOQL code. If we escaped it in order to prevent SOQL injection, it would stop working as well. We control front-end too in this case, so we could think that taking care of making front-end secure (so the user is not able to provide a fully free input for this attribute) is enough. But it isn’t: data is passed to back-end as a JSON string, which is not secure. We need an alternative way of passing the filter information from the front-end to the back-end.

 

Using precompiled, back-end data

 
So we want a component that gives us flexibility to pass whatever filter we need, but also, we don’t want to pass that filter in plain SOQL. We could think of creating a class which instances store the filter somehow codified, and then allows us to retrieve the SOQL string for that filter. A specific instance of that class, with the correct information, would be created from the VF page’s controller and passed to the component via attribute, which, in turn, would then pass the info to the @RemoteAction method. But in the end, it would not be secure either as the filter information is travelling from front-end to back-end, one way or another.

Instead, the flexibility will be moved to the back-end, while the front-end will be restricted to the options implemented in back-end. Let me explain this.

The component will now expect an instance of a class that implements this interface:

[code language=”java”]
public interface ICondition {
String getCondition();
}
[/code]

 
Such instance will not contain any data. It will only give us the information about which specific class implements the condition, so we can call the getCondition() method and get the information we need. This way the query condition is not passed through front end.

For each specific filter, a custom class will be implemented, defining the condition for each component instance:

[code language=”java”]
public class SpecificCondition implements ICondition {
public String getCondition() {
return ‘Name LIKE \’A%\”;
}
}
[/code]

 
The component will now receive the name of the class that implements the condition:

[code language=”xml”]
<apex:component controller="CustomPicklistController">
<apex:attribute name="objectName" type="String" required="true" description="Object to query from"/>
<apex:attribute name="conditionClass" type="String" required="false" default="CustomPicklistController.NoCondition" description="Class implementing ICondition"/>

<script type="text/javascript">
function getRemoteData() {
Visualforce.remoting.Manager.invokeAction(
‘{!$RemoteAction.CustomPicklistController.getData}’,
‘{!objectName}’,
{‘apexType’: ‘c.’+'{!conditionClass}’},
function(result, event){

},
{escape: true}
);
}
</script>

</apex:component>
[/code]

 
What happened here? We are basically applying what this article from Salesforce’s official documentation says about how to pass interface instances to a @RemoteAction method: the instance itself is not passed. What we pass, is a string with the class name (and nothing else in our example given the instance contains no data). The system will then, automatically, take care of instantiating the class.

As you can see, the default c namespace is being concatenated here:

[code language=”xml”]
<script type="javascript">

{‘apexType’: ‘c.’+'{!conditionClass}’}

</script>
[/code]

 
This is to simplify the caller so it does not need to know about the namespace thing. Of course, if we wanted to make this component available from outside our package, we would need to tweak this.

Another interesting detail is the default value given to the attribute: CustomPicklistController.NoCondition. This references a class that we will include with the component’s controller:

[code language=”java”]
public class NoCondition implements ICondition {
public String getCondition() {
return ”;
}
}
[/code]

 
The reason why we need this, is that we cannot pass null or inexistent classes to a @RemoteAction, so if we don’t want to apply any filter, we need a default class that actually implements no filter.

With all of this settled, the @RemoteAction method now looks like this:

[code language=”java”]
public with sharing class CustomPicklistController {

@RemoteAction
public static CustomPicklistData getData(String objectName, ICondition condition) {
List<SObject> records = retrieveData(objectName, condition);
CustomPicklistData data = convertData(records);
return data;
}

private static List<SObject> retrieveData(
String objectName,
ICondition condition
) {
String safeObjectName = getSafeSOQLString(objectName);
String filter = condition.getCondition();
String whereClause = filter.isEmpty() ? ” : ‘ WHERE ‘ + filter;
String dbQuery = ‘SELECT Id, Name FROM ‘ + safeObjectName + whereClause;
return Database.query(dbQuery);
}
}
[/code]

 
So, the Visualforce page instantiates the component this way:

[code language=”xml”]
<CustomPicklistController objectName="Account" conditionClass="{!conditionClass}"/>
[/code]

 
… and the condition class is returned from the VF page’s controller:

[code language=”java”]
public String getConditionClass() {
return ‘WhateverPageController.SpecificCondition’;
}
[/code]

 
(… where WhateverPageController is the VF page’s controller, and SpecificCondition is the specific condition class we saw before, nested within the controller class).

 

Conclusions

With the proposed solution, we have avoided having to open a door to potential SOQL injection attacks by not allowing to pass any data, but only information to access the code that actually generates the data, and all of this while leveraging @RemoteAction’s speed and keeping a great flexibility for the component’s user.

Thanks to my teammates at FinancialForce Ana Cristina López, Abel Martos and Shaun Doyle for their great contribution while looking for a solution to the problem.

UniShare: sharing scores to social media with Unity

Español

One of the features I have missed in Unity when developing Countless, is the ability to share scores to social networks like Twitter or Facebook, as well as any other media like email and other messaging applications. Today’s mobile operating systems have integrated, standard tools that allow applications to easily share text and images to the media chosen by the user, and it would make sense that Unity integrated a unified, multi-platform API to deal with these features when deploying to mobile devices, but it doesn’t.

 

iOS Sharing Dialog
An example of a standard sharing dialog

 

So, after searching a lot, I finally found what seems to be the best existing option at the moment: the UniShare plugin by Level One Games. It allows to easily get a screenshot and share it via the OS’ standard dialog. It is not free, but it is definitely worth its price.

 

Honestly, after installing it I didn’t find it very straightforward to start using it, because I could not manage to find any documentation, and despite of including an example, it didn’t work for me. But everything turned out to be quite simple after taking a look into its code.

 

How to use UniShare

 

After installing it, a new folder called UniShare will appear in your project under Assets/Plugins. It includes an example folder. You can simply remove it. So you will have a structure similar to this one:

 

UniShare Folder Structure

 

If you go to the Scripts folder, you will find a script called UniShare. If you open it, you can find some of the methods that you will need to perform the most common operations related to sharing, like TakeScreenshotTakeScreenshotAndShare, and ShareScreenshot. But… how and where can you use them?

 

Simple. Add a Script component to one of your game objects, with this script:

 

UniShare Script Component

 

There you can see the parameters you can set for sharing, like ShareText and the four Border values. All of them can be configured both in the UI and from code. Once you have this component, it is possible to go to a custom script attached to this same object and do something like this:

 

[code language=”csharp”]
private UniShare uniShare;
private string originalSharingMessage;

void Start () {
uniShare = gameObject.GetComponent<UniShare> ();

// Compute values for borders depending on screen’s aspect ratio if needed
uniShare.BorderLeft = Screen.width * …;

// Keep the original text so we can update it afterwards
originalSharingMessage = uniShare.ShareText;
}
[/code]

 

In the example, I am storing the original value of ShareText in order to be able to update it afterwards. My intention here, is to define the text in Unity’s UI, but with a parameter ({0}):

 

UniShare Share Text

 

… so, from my script, I can use that exact text but replacing the parameter with the needed value:

 

[code language=”csharp”]
public void openSharingDialog(int _score) {
uniShare.ShareText = string.Format (originalSharingMessage, _score);
uniShare.TakeScreenshotAndShare ();
}
[/code]

 

Another important feature, is the ability to set borders for the screenshot. In my custom script, you have seen I was updating the screenshot’s width according to some criteria and depending on screen’s aspect ratio. The parameters defined by UniShare for this, are values between 0 and 1 that are relative to screen’s width and height. In order to make it easier to know what we are doing, UniShare allows us to print a semi-transparent rectangle in Unity’s simulator indicating the area that will be captured, by checking “Simulate Captured Area” in the script’s parameters:

 

UniShare Simulating Captured Area

 

So, you can use that information to tweak the borders and get the data you need to adjust the screenshot.

Comment/share

 

==============

 

UniShare: compartiendo en redes sociales con Unity

 

Una de las funcionalidades que he echado en falta en Unity al desarrollar Countless, es la posibilidad de compartir puntuaciones en redes sociales como Twitter o Facebook, así como cualquier otro medio como email u otras aplicaciones de mensajería. Los sistemas operativos móviles de hoy en día tienen herramientas integradas y estándar para compartir fácilmente texto e imágenes a los medios escogidos por el usuario, y tendría sentido que Unity integrase una API unificada y multiplataforma para acceder a esas características al exportar nuestro proyecto a dispositivos móviles… pero no lo hace.

 

iOS Sharing Dialog
Un ejemplo de un diálogo estándar para compartir

 

De modo que, tras buscar mucho, finalmente encontré lo que parece ser la mejor opción existente en este momento: el plugin UniShare de Level One Games. Permite obtener una captura de pantalla y compartirla fácilmente a través del cuadro de diálogo estándar del sistema operativo. No es gratuito, pero sin duda vale la pena por su precio.

 

Sinceramente, tras instalarlo no encontré demasiado intuitivo cómo comenzar a usarlo, porque no logré encontrar documentación, y a pesar de incluir un ejemplo, este no me funcionó. Pero todo resultó ser muy sencillo tras echar un vistazo a su código.

 

Cómo usar UniShare

 

Tras instalarlo, una nueva carpeta llamada UniShare aparecerá en tu proyecto bajo Assets/Plugins. Incluye una carpeta con un ejemplo. Puedes simplemente borrarla. Así, tendrás una estructura similar a esta:

 

UniShare Folder Structure

 

Si vas a la carpeta Scripts, encontrarás un script llamado UniShare. Si lo abres, verás algunos de los métodos que necesitarás para realizar las operaciones más comunes relacionadas con la funcionalidad de compartir, como TakeScreenshotTakeScreenshotAndShare, y ShareScreenshot. Pero… ¿cómo y dónde puedes usarlos?

 

Simple. Añade un componente Script a uno de tus game objects, con este script:

 

UniShare Script Component

 

Ahí puedes ver los parámetros que puedes configurar para compartir, como ShareText y los cuatro valores Border. Todos ellos pueden ser configurados tanto en la UI como por código. Una vez tengas este componente, es posible ir a un script custom enlazado a este mismo objeto y hacer algo como esto:

 

[code language=”csharp”]
private UniShare uniShare;
private string originalSharingMessage;

void Start () {
uniShare = gameObject.GetComponent<UniShare> ();

// Calcular valores para los bordes dependiendo de la relación de aspecto de la pantalla, si es necesario
uniShare.BorderLeft = Screen.width * …;

// Guardar el texto original de modo que podamos actualizarlo después
originalSharingMessage = uniShare.ShareText;
}
[/code]

 

En el ejemplo, estoy almacenando el valor original de ShareText para poder actualizarlo después. Mi intención aquí, es definir el texto en la UI de Unity, pero con un parámetro ({0}):

 

UniShare Share Text

 

… y así, desde mi script, puedo usar ese texto pero reemplazando el parámetro con el valor requerido:

 

[code language=”csharp”]
public void openSharingDialog(int _score) {
uniShare.ShareText = string.Format (originalSharingMessage, _score);
uniShare.TakeScreenshotAndShare ();
}
[/code]

 

Otra característica importante, es la posibilidad de establecer bordes para el screenshot. En mi script custom, has visto que actualizo el ancho de la captura de pantalla de acuerdo con algún criterio y dependiendo de la relación de aspecto de pantalla. Los parámetros definidos por UniShare para esto, son valores entre 0 y 1 relativos al ancho y alto de pantalla. Para hacer más fácil saber lo que estamos haciendo, UniShare nos permite activar un rectángulo semitransparente en el simulador de Unity indicando el área que será capturada, si activamos “Simulate Captured Area” en los parámetros del script:

 

UniShare Simulating Captured Area

 

Así, puedes usar esta información para configurar los bordes y obtener los datos que necesitas para ajustar la captura de pantalla.

 

Countless, my new game

Español

CountlessTitle

And here it is. Or almost 🙂 . After some months spending part of my very limited spare time learning how to use Unity and working on a game, it is almost finished. Let me introduce Countless.

 

2016_08_13_ScreenshotSaturday

 

Countless is a very simple game. The player is presented with a square board full of squares. Each square has a number, and the player must match numbers, in correct order, as quick as possible. The player will fail when not matching the next pair of squares in time. The goal? Match as many pairs as you can.

 

2016_08_20_ScreenshotSaturday

 

Despite of its simplicity, developing Countless has been (and is being) very didactic when it comes to using Unity game engine. It involves a lot of animations, data persistence, scene and object management, event handling, UI configuration, ads, and access to some target systems’ features. And a lot of scripting. This is my first experience using a third-party game engine. My previous game, EggOrama, was developed from scratch using my own engine.

 

Gameplay1

 

For me, Countless serves a dual purpose. On one hand, it is a game that I will publish. It will be free, but include some ads (as well as a little gamification of this). On the other hand, by working on it I have been able to learn a lot about the game engine without having to spend too much time on each feature. After releasing this game, I will be prepared to start another one (but won’t forget updates for Countless as well).

 

Countless will be released soon, for iOS and Android, featuring both local and online leaderboards. More platforms could eventually join the party. No specific release date yet, though!

Comment/share

 

==============

 

Countless, mi nuevo juego

CountlessTitle

Y aquí está. O casi 🙂 . Tras algunos meses pasando parte de mi muy limitado tiempo libre aprendiendo cómo usar Unity y trabajando en un juego, está casi terminado. Permitidme presentaros Countless.

 

2016_08_13_ScreenshotSaturday

 

Countless es un juego muy simple. Ante el jugador se muestra un tablero cuadrado lleno de cuadrados. Cada cuadrado tiene un número, y el jugador debe emparejarlos, en el orden correcto, tan rápido como sea posible. El jugador fallará cuando no empareje el siguiente par de cuadrados a tiempo. ¿El objetivo? Hacer tantas parejas como puedas.

 

2016_08_20_ScreenshotSaturday

 

A pesar de su simplicidad, desarrollar Countless ha sido (y está siendo) muy didáctico en lo que a usar el motor Unity se refiere. Involucra un montón de animaciones, persistencia de datos, gestión de escenas y objetos, configuración de UI, publicidad, y acceso a algunas características de los sistemas de destino. Y mucho scripting. Esta es mi primera experiencia usando un motor de juego de terceros. Mi anterior juego, EggOrama, se desarrolló desde cero usando mi propio motor.

 

Gameplay1

 

Para mí, Countless sirve para un doble propósito. Por un lado, es un juego que voy a publicar. Será gratuito, pero incluirá algo de publicidad (así como un poco de gamificación de esta). Por otro lado, al trabajar en él he podido aprender mucho sobre el motor sin tener que pasar demasiado tiempo en cada característica. Tras publicar este juego, estaré preparado para empezar otro (sin olvidarme de las actualizaciones para Countless).

 

Countless será publicado pronto, para iOS y Android, e incluirá tablas de clasificación tanto local como online. Puede que más plataformas se unan a la fiesta en el futuro. ¡Pero no tengo una fecha de lanzamiento específica todavía!

Constructors and global classes in Apex

It is well known that special care must be taken when creating global classes in Apex, because global classes, methods and member variables that are released in a package, cannot be removed in further versions of the same package. Some of the restrictions are well explained in official Salesforce docs like this one and this one, but there are some issues for which it is difficult to be prepared until we face the problem or test it ourselves. This is the case of the thrilling world of constructors in global classes.

How do constructors behave in global classes?

Pretty much the same as in non-global ones. But there are some important nuances to be considered.

Let’s say… we are creating a class with no “particular” way of instantiation. We don’t need to pass any argument, there’s no needed initialisation, and it can be freely instantiated. We can then omit the constructor:

[code language="java"]
global class InstantiateMeIfYouCan {
    global void foo() {
        System.assert(false, 'OK, so you instantiated me. Now what?');
    }
}
[/code]

Salesforce automatically generates an implicit, global constructor with no parameters. When releasing this class in a package, it can be instantiated and used from the customer’s org:

[code language="java"]
public class ISwearICanInstantiateYou {
    public static void foo() {
        new VSTest.InstantiateMeIfYouCan().foo();
    }
} [/code]

(… where VSTest is the package’s namespace).

So far, so good.

Updating our global class with a new constructor

It turns out that after releasing our class, now for some reason we want it to be instantiable only with a parameter specified in the constructor. So we add a new constructor:

[code language="java"]
global class InstantiateMeIfYouCan {
    global InstantiateMeIfYouCan(Boolean coolModeActivated) {

    }

    global void foo() {
        System.assert(false, 'OK, so you instantiated me. Now what?');
    }
}
[/code]

As with any other class, global or not, Apex automatically removes the implicit, no-param constructor. This common behaviour is detailed in the official documentation:

If you write a constructor that takes arguments, you can then use that constructor to create an object using those arguments. If you create a constructor that takes arguments, and you still want to use a no-argument constructor, you must include one in your code. Once you create a constructor for a class, you no longer have access to the default, no-argument public constructor. You must create your own.

And Salesforce allows us to package this new version. One could think that, implicit or not, the previously existing constructor with no parameters was global and had already been packaged, so the system would forbid us to perform this action. But the truth is, it doesn’t. When we release this new version, it is possible for the customer to upgrade the package in their org, despite of the fact that the new version breaks their existing code. When trying to run their code with the new version, an error similar to this arises:

Dependent class is invalid and needs recompilation: ISwearICanInstantiateYou: line 3, column 16: Constructor not defined: [VSTest.InstantiateMeIfYouCan]()

OK, so now we know this is a breaking change. Let’s try to fix this and release a new version.

Recovering the no-param constructor

We have already released our 1-param constructor, and it’s global, so there’s no way to return to the original status. Now the only thing we can do, is adding an explicit, no-param constructor:

[code language="java"]
global class InstantiateMeIfYouCan {
    global InstantiateMeIfYouCan() {

    }

    global InstantiateMeIfYouCan(Boolean coolModeActivated) {

    }

    global void foo() {
        System.assert(false, 'OK, so you instantiated me. Now what?');
    }
}
[/code]

Again, the system allows us to package the new version and release it. And again, the customer can install the new version with no issues. But when running their code…

Dependent class is invalid and needs recompilation: ISwearICanInstantiateYou: line 3, column 16: Package Visibility: Constructor is not visible: [VSTest.InstantiateMeIfYouCan].<Constructor>()

Weird, isn’t it? So we have explicitly added the constructor and set it as global. We know it is global. But the platform does not get it correctly, even though when entering the class in the customer’s org, it informs about the availability of those methods:

InstantiateMeIfYouCan

Actually, not so weird. The existing class ISwearICanInstantiateYou is linked to a previous version of our package. It’s a matter of changing the version it is using by editing the class and going to Version Settings. If we create another, new class in the customer’s org that makes use of the mysterious no-param constructor:

[code language="java"]
public class SoYouThoughtICouldNotInstantiateYou {
    public static void foo(){
        new VSTest.InstantiateMeIfYouCan().foo();
    }
} [/code]

It works directly because it is taking the latest version by default.

So, the fact that we didn’t explicitly declare the no-param constructor in the first version, caused issues in the end (our updates are throwing compile errors in customer’s org). This makes it highly advisable to always declare an explicit, global no-param constructor in our global classes in order to prevent potential issues. But it is not always possible: sometimes it does not make sense to allow customers to instantiate our class.

What if we create an explicit, private no-param constructor?

[code language="java"]
global class InstantiateMeIfYouCan {
    private InstantiateMeIfYouCan() {}

    global void foo() {
        System.assert(false, 'OK, so you instantiated me. Now what?');
    }
}
[/code]

This way we are “booking” the constructor and at the same time, preventing customers from using it unless we decide to make it global in a future version. This would work as long as we keep the restriction of not being able to instantiate the class with the default constructor from the outside. Otherwise, after releasing the first version with the private constructor, an update that changes it into a global one would obviously need an update in existing customer code to start leveraging it. We could think of an alternative solution that would work without them needing to update nothing but our package.

Implementing an explicit prohibition

Let’s create an explicit, global no-param constructor that throws a special exception:

[code language="java"]
global class InstantiateMeIfYouCan {
    global InstantiateMeIfYouCan() {
        throw new InvalidInstantiationException();
    }

    global InstantiateMeIfYouCan(Boolean coolModeActivated) {
        ...
    }

    global void foo() {
        System.assert(false, 'OK, so you instantiated me. Now what?');
    }
}
[/code]

By including the global constructor in the first version, we make sure it will be available in future releases if we need it. On the other hand, we are explicitly forbidding its usage by throwing an exception that we have created for this situation. And if we need to “unlock” the constructor and make it available in a new release, we can always change its implementation with no issues. Actually, the customer would need to update their code anyway in order to use the new constructor, unless they implemented something like this to anticipate this situation:

[code language="java"]
public class ISwearICanInstantiateYou {
    public static void foo() {
        VSTest.InstantiateMeIfYouCan instance;

        try {    // Firstly, try to instantiate with default values
            instance = new VSTest.InstantiateMeIfYouCan();
        }
        catch (VSTest.InvalidInstantiationException ex) {
            // Not available: use the constructor with an explicit argument
            instance = new VSTest.InstantiateMeIfYouCan(false);
        }

        instance.foo();
    }
} [/code]

So now, there’s no need at all for the customer to create a new version of their code or product, because it will be prepared to work with and without the no-param constructor in advance.

Creating a hierarchical HUD in Unity

Español

 

UnityGameProject

I have been “playing” a bit with Unity for the last few months, building a very simple game (which the image at the top of this post belongs to) that I expect to release soon, and I have learned quite a few things about Unity. In this case I want to share my experience setting up hierarchical HUDs.

There are a bunch of great official tutorials on creating user interfaces (UI) in Unity, which are quite useful to learn about this functionality provided by Unity. But… what do I mean by “hierarchical HUDs”?

As you probably know, a HUD is basically the set of indicators a game shows in the display to give some information to the player. In the game I am creating, I found myself creating a HUD composed by several text objects: Score and Remaining Time. But sometimes, I needed to handle all of them as a single object. For example, when fading them in and out (because I have animated them to show and hide with a smooth animation). If they are independent, we have to create a separate animation for each of them, and handle each of them separately as well from our scripts.

The solution is to create a hierarchy with our HUD elements.

 

First step: create a UI hierarchy using an additional GameObject

HierarchicalHUD

A hierarchy in UI elements in Unity works very much as every game object hierarchy: we can create an empty GameObject in our Canvas (which I have named HUD in this case), and then drag all of the components inside of it. Very simple. BUT…

The fact that UI elements have sizes and positions relative to the screen (or, more precisely, relative to their parent object) forces us to make some adjustments so the components of the HUD keep working correctly on all screen resolutions.

 

Second step: make the container object match the Canvas

When we have just created our empty HUD game object, it appears as a square centered inside the Canvas:

CanvasGameObject

It has a fixed size. Given all HUD components will size and position relative to their parent object (the HUD object), we need the HUD object to adjust to the Canvas so it keeps being relative to the screen dimensions (otherwise, all HUD components will have fixed size and positions as well).

For this, we have to set the HUD to stretch to completely match its parent, so we select the HUD object and go to the Inspector, and set this configuration:

HUDObjectRectTransform

(when selecting the Stretch configuration, if we hold Alt while clicking on the stretch option, the dimensions will be automatically adjusted for us; otherwise we will have to manually set all values -Left, Top, Right, Bottom- to 0).

 

Third step: fix HUD components’ positions and sizes

After this, HUD components’ positions will probably be incorrect. We only need to configure their positions, sizes and anchor presets again and then we will have our hierarchical HUD working.

Now, it will be possible to activate or deactivate the whole HUD at once, or animate all of its components with a single animation and animation controller, or to store it as a prefab and instantiating it with a single line of code. For me, this has been quite useful. Hope it helps you too 🙂

 

Comment/share

 

==============

 

Creando un HUD jerárquico en Unity

 

UnityGameProject

He estado “jugando” un poco con Unity durante los últimos meses, construyendo un juego muy simple (al que pertenece la imagen de cabecera de este post) que espero publicar pronto, y he aprendido bastantes cosas sobre Unity. En este caso, quiero compartir mi experiencia configurando HUDs jerárquicos.

Hay un puñado de tutoriales oficiales geniales sobre crear interfaces de usuario (UI) en Unity, que son muy útiles para aprender sobre esta funcionalidad proporcionada por Unity. Pero… ¿a qué me refiero con “HUDs jerárquicos”?

Como probablemente sabéis, un HUD es básicamente el conjunto de indicadores que un juego muestra en pantalla para dar información al jugador. En el juego que estoy creando, me encontré creando un HUD compuesto por varios objetos de texto: Score y Remaining Time. Pero a veces, necesitaba manejarlos todos como un único objeto. Por ejemplo, al hacerlos aparecer y desaparecer con suavidad (porque los he animado para mostrarse y ocultarse con una animación suave). Si son independientes, tenemos que crear una animación separada para cada uno de ellos, y manejarlos también por separado desde nuestros scripts.

La solución es crear una jerarquía con los elementos de nuestro HUD.

 

Primer paso: crear una jerarquía de UI usando un GameObject adicional

HierarchicalHUD

Una jerarquía en elementos de UI en Unity funciona como cualquier jerarquía de objetos: podemos crear un GameObject vacío en nuestro Canvas (que yo he nombrado HUD en este caso), y entonces arrastrar todos los componentes a su interior. Muy simple. PERO…

El hecho de que los elementos de UI tengan tamaños y posiciones relativos a la pantalla (o, para ser más precisos, relativos a su objeto padre) nos fuerza a hacer algunos ajustes para que los componentes del HUD sigan funcionando correctamente en todas las resoluciones de pantalla.

 

Segundo paso: hacer que el objeto contenedor coincida con el Canvas

Cuando creamos nuestro objeto HUD vacío, aparece como un cuadrado centrado dentro del Canvas:

CanvasGameObject

Tiene un tamaño fijo. Dado que todos los componentes del HUD se escalarán y situarán relativos a su objeto padre (el objeto HUD), necesitamos que el objeto HUD se ajuste al Canvas de manera que siga siendo relativo a las dimensiones de pantalla (de lo contrario, todos los componentes del HUD tendrán también posiciones y tamaños fijos).

Para esto, tenemos que configurar el HUD para estirarse (stretch) hasta coincidir completamente con su padre, así que seleccionamos el objeto HUD y vamos al Inspector, para poner esta configuración:

HUDObjectRectTransform

(al seleccionar la configuración de Stretch, si mantenemos pulsado Alt mientras hacemos clic en la opción de stretch, las dimensiones se ajustarán automáticamente para nosotros; si no, tendremos que establecer manualmente todos los valores -Left, Top, Right, Bottom- a 0).

 

Tercer paso: arreglar posiciones y tamaños de los componentes del HUD

Tras esto, las posiciones de los componentes del HUD serán probablemente incorrectas. Sólo necesitamos configurar sus posiciones, tamaños y anchor presets de nuevo y tendremos nuestro HUD jerárquico funcionando.

Ahora, será posible activar o desactivar el HUD completo con una única acción, o animar todos sus componentes con un solo animation controller, o almacenarlo como un prefab e instanciarlo con una única línea de código. Para mí, esto ha sido muy útil. Espero que os ayude a vosotros también 🙂