Category: Gameplay Prototyping Module

12 – Mobile Integration & Playtesting

What I needed to do

To convert the game to the mobile format I needed to revamp the control scheme:

  • Tap to Jump
  • Tap and Hold to Parachute
  • Tap to shoot Rope
  • Accelerometer to move left/right
Integrating mobile controls was way simpler than I expected, I had never done any mobile stuff in Unity or at all ever before so it was a completely new experience.

Apparently (for now) I don’t need to work with Input.touch as the Input.GetMouseButton(0) works for your usual mouseclick as well as a single tap.

Picture

 
To make everything else work with taps I had to convert all code with the Input.GetButtonDown(“Jump”) with a Input.GetMouseButtonDown(0), essentially replacing all Spacebar related movement with Mouseclicks.
Picture

 
To work with the new mouseclick system I had to modify the Rope Swinging system too: now the player has to be mid-air to shoot their Rope.
 
Picture

 
Integrating the phone’s Accelerometer required me to use Platform Dependent Compilation (the #ifs) as while all other controls could be converted to mouseclicks (eg jumps and parachute deployment) the movement would have to remain A/D for PC.
 

Playtesting Feedback

Myself and my girlfriend playtested the new android build and discovered a few things:

Bugs/Issues

  • Respawning doesn’t respawn the powerups due to its nature and prevent progress, may need to stick to reloading scenes (no multiple respawn points)
  • Background needs some differences (tiling?) as its sometimes difficult to tell if you’re moving due to the minimalist nature
  • Obvious graphical hitches related to 2DDL Lighting system
  • Sometimes respawning via killbox makes two players appear

Feedback

  • Wall Jumping is too hard (requiring major tilts where you can’t even see the screen)
  • ropeHook deployment is awkward as it requires aiming whilst others require taps anywhere
  • Landing on platforms is hard, a simple element made much more interesting due to the accelerometer
  • Frustrating enough to make you want to try again but not so much to make you quit (main KPI for casual games!)

For the video below I fixed the Wall Jumping is too hard by multiplying the accelerometer input by 2 to make it more sensitive to tilting.

 

Video

11 – Finishing the rest of the Building Blocks

With the revamping of the Platform prefabs I was set on adding the rest of the game’s level building blocks:

  1. Killboxes
  2. Respawning (inc GameMaster obj and sorting the camera)
  3. Ending the level
  4. PowerUps Activators

In addition I also created a tutorial level that showcases the above off and everything i’ve done so far!

 

Killboxes

A standard mechanic in platformers are hazards the player must avoid, wheter it be spikes or (for now) red boxes in our game.

To do this I simply created a new kill gameObject that had the tag “Kill” as well as the usually Trigger collider and added the following code in the playerScript.

Picture

 
 

Respawning

Once the player dies (for now it’s all instant-kill) they need to respawn. For this I needed to create the _GameMaster object, essentially what handles the running and utilities of the game.

As you can see in the code above when the player collides with a “Kill” object it calls the KillPlayer function from the gamemasterScript.

Picture

 
Once the player is killed I added a delayed function (via coroutines) that handles respawning – in this case a new instance of the player is created at the spawnPoint game obj’s location.

If I were to add multiple spawn points I would have to handle saving the player’s current instance (so we know eg what powerups they have or even their health in the future if needed) and respawn that instead – but for now we have this.
If the game also to fit the casual market we wouldn’t really need multiple spawners as each ”encounter’ could essentially be a level on its own.

Picture

 
 
Camera Changes
With the new changes I also had to change the way the camera followed the player.

In the old version the camera was simply a child object that belonged to the player, a rather simple and blunt way of doing it.
This came to a head when implementing respawning as the main camera would also be destroyed when the player died which caused some issues, namely the camera not being able to render anymore as our only viewport into the game is destroyed.

To fixed this I used Unity’s StandardAsset’s Camera2DFollow script which accomplished the same thing as before but kept the camera independent of the player.

I also added some new code in the existing script below:

Picture

 
 

Ending the Level

This one works exactly like the Kill code, if the player collides with an object tagged “EndLevel” then the current scene will be reloaded.

Right now this is a temp measure, in the future this would be linked up to a GUI for example, asking if the player wants to restart or go back to the menu, etc.

 

PowerUp Activators

I had several ideas on how to implement the usage of PowerUps (eg Parachutes, Rope, Spikes). One of the ideas was to have a inventory-like system where the player can select which one they used but this required going into GUI so I decided on a much simpler and arcade-y option = collectible powerups.

In my current version the player can only have one powerup at a time (to minimize any unforeseen conflict between them that might arise). When the player collects a certain powerup, all other powerups are disabled. The way I made powerups was to make them individual gameObject children to the player but instead of adding and deleting powerups (which might cause issues with instantiated clones) I opted to just activating and disabling the existing children.

How the PowerUp system works

  • player has all powerups as children gameObjects
  • if a powerup activator is collected the relevant gameObject is activated and all others are deactivated
  • when a gameObject is deactivated this means its sprite graphics appear and its component scripts can happen

I had a bit of an issue doing this as again I tried to do it the simplest way possible (and Unity apparently requires jumping through hoops) as seen in the code below:

Picture

 
Apparently you need to make an object reference first, you can’t just find an object with the name and use it straight away which is perfectly understandable.
 
Picture

 
Instead of working with tags like before I opted to just use the object’s name as the search criteria as making it tag-based could easily lead to spam with lots of tags if I decide to add new powerups.
 

Video

10 – Finetuning Rope Swinging

So last time the base rope from the tutorial was done but there were a few issues:

1. Rope can be deployed everywhere
2. The rope can be seen through the 2DDL lighting shadows
3. The rope prevents normal movement

As this is the gameplay prototyping module I focused on the aspects that affected gameplay, namely issue 1 and 2.

This was the most difficult task to do so far as it required me to essentially go out and experiment on my own with very little from help tutorial (not for the lack of looking there just wasn’t any that did it the way I wanted to)

 

Fixing Issue 3 – Rope prevents normal movement

This was easy enough as I realised it had more to do with the physics of the game than the actual code: essentially the combined mass of the rope (aka the nodes who have Rigidbody2D) would be too great and prevent movement. This wasn’t a problem for short ropes (aka few nodes meaning lower mass) but for long ropes like the one in the video this can be a problem.

After playing about with changing the Rigidbody2D masses of both the nodes and the player (as well as gravity scale) I settled on simply changing the ropeNode prefab’s mass from 1 to 0,1, after all, its so easy to change and play about with that if I changed my mind it would take less than a second.

 

Fixing Issue 1 – Rope can be deployed everywhere

This issue was my toughest problem to boot and required a lot of research and trial-and-error.

My core fix was essentially to limit the player’s rope swinging to only the platforms (aka no mid-air). To do this I had to work with and modify the existing code.

How the rope code works:

  • the player mouseclicks a location
  • a ropeHook obj is spawned and made to go to the mouseclick
  • nodes are created as the ropeHook travels through the air as well as after it hits its target
  • the nodes are attached to the player
 
The Failed Attempt
My first attempt failed as I tried to accomplish too many things at once:

  • I wanted to fix the issue
  • I wanted to revamp the way the rope is shot (from mouseclick to an aimed projectile similar to Angry Birds or an Archer shooting an arrow)

While I learned a lot during my research the attempts led to nothing as the existing rope code (hookRope script, the one making nodes) was fixed on the way the rope was deployed: a literal movement of the ropeHook to the fixed target point – whereas I wanted to make a physics-based projectile just shot at the general distance not towards a point.

 
The Successful Attempt
I lowered my scope a bit and focused on the problem at hand: the rope can be deployed everywhere.

After some more exploration I ended up with this:

  • the ropeHook still goes after a hookTarget but
  • if the ropeHook collides with an object tagged with “Platform” it sets its current position as the new target (which makes it stop moving and attach itself to the player)
  • if the rope doesn’t hit a “Platform” but reaches its hookTarget
 
Picture

 
Picture

 
I used the (hookAttached) boolean as a workaround to check if the hook actually hits a collider/platform.
 
While this sorted the main issue the manual destruction of the rope with Destroy(this.gameObject) within the hookRope Script meant the same rope object’s state of existence was being handled by two scripts: the initial hookThrow and now hookRope.

The hookThrow Script is what what handles the deployment and prevention of duplicate ropes and because of the new code: doesn’t actually know that the rope is destroyed. This meant that the player would have to click twice to deploy a new rope instead of clicking once like before.

Picture

 
This function lies within hookThrow’s Update and essentially checks if there’s any ropes around working as an extra-check and failsafe for any rope’s existence.
 

New Platform Prefabs

To make the hook actually register collisions with the Platforms I had to make a child gameObject on the Platform called TriggerCollider (as it previously only had Effector colliders)
 

Video

No video this session as its pretty much a rope being destroyed if it reaches the mouseclick point and doesn’t collide with anything – it’ll be seen for sure in the next video!

9 – Rope Swinging

Rope Swinging is the final Power-Up from my initial design plan and arguably the most complex one as not only does it require working with Unity Physics but also deals with procedural instantiated objects which I don’t have much experience in.
 

Research

From my research I found that there’s two distinct schools surrounding this whole idea: rope swinging and grappling hooks.
Rope Swinging are in games like Hanger: you shoot a rope and swing on it.
Grappling Hook are in games like Terraria or Windlands: you shoot a rope and get pulled towards it – the rope itself is high-tension (aka not ‘floppy’ but a straight line)
While both are pretty good options I was aiming for the Indiana Jones-style rope swinging which could also allow versatility in pulling objects or rapelling/absailing.
 

playerRope

Eventually I found a good tutorial that helped achieve the basics of the Rope Swinging variant, though I would later need to build and iterate upon it to make it my own.

The Setup

Picture

 
Picture

 
Picture

 
This Setup was arguably more complex than the other two Power-Ups, in brief I have a base Power-Up object playerRope (like playerSpikes or playerParachute) which contain the script hookThrow.

hookThrow relates to the ropeHook prefab and the ropeNode prefab, the ropeHook prefab also has its own script tied to it called hookRope which.

Picture

 
 

The Code

hookThrow

Picture

 
This script handles the actual throwing of the hook and its relation to the player’s controls – when future implementation of mobile controls are done it’ll be here.
 

hookRope

Picture

 
The real bread and butter of the code lies in the hookRope script, above is an excerpt showing how Nodes are created.
 

Video

As you can see there’s still some problems afoot which i’ll hopefully deal with next post.

8 – Finetuning Wall Jump

My first iteration of the Wall Jumping was barebones and just got the mechanics working, but not the way I wanted them to be.

A major issue was that if the player kept moving against the wall and jump they immediately go back onto the wall and essentially ‘climb’ their way up similar to a slinky (back-and-forth).

Thise brings up lots of exploits and allows the user to essentially climb and scale up walls really quickly – while a neat feature it goes against what I originally intended.

 
Picture

 
In order to fix it I looked for a way to essentially eiter ‘disable’ controls to prevent the player from holding the move button right back into the wall after jumping or a way to affect the player’s drag to stop them from returning to the wall as quick.

Eventually I settled on the first option as changing the player’s drag affected the directional force applied to the object.

I looked at various ways to disable controls but those suggested disabling a PlayerController script that I didn’t have (for now), but one person suggested creating booleans and use conditions to do it instead so I did just that.

I also played around with modifying movement speed through air via (airSpeed) variable to prevent the player from ‘climbing’ but that went against the whole focus on minimum input lag I was talking about on Post 7.

Picture

 
In order to modify the boolean above I needed to add a delay/wait timer in the playerSpikes script, unfortunately Unity doesn’t have a simple delay function so I found a way suggested to do it via Coroutines. After fiddling about and referring to platformers such as Super Meat Boy I found a good balance on when the player should regain controls.

A good balance for me meant that the player can’t significantly climb high like in the old version (seen in video below) but can also regain control quick enough to add momentum and boost jump to reach further obstacles (also seen in video below)

 

Video