NpSceneQueries::multiQuery Mobile Error (Unity)

Basically jotting this down here as I recall it, will try to better lay out my solutions later.

Part of this competition involves publishing your finished game to the Windows store as a universal app. After some headaches with getting the Windows phone emulator to work, I had this error bombarding the development console built-in to developer builds of Unity games:

NpSceneQueries::multiQuery input check: distance cannot be negative or zero

I got this on two different occasions, and there doesn’t seem to be a lot of documented cases of this happening out on Google. One Unity forum thread I found had multiple devs experiencing this issue when developing for Android, people seemed to think that the problem was caused by the physics engine.

With that as my only clue, I set out to try and make the error go away.

First Thing to Try: My protagonist is able to wall on ground and ceiling, when it switches to the ceiling I was inverting its Y-scale, having a negative scale seemed to cause this error first time. Removing the scale inversion in favour of adding upside-down versions of the character’s sprites fixed it. Having now encountered this, I would personally advise against using negative scales (for all I know this may have already been common knowledge to some?)

The Next Cause: Was Physics.Raycast. This is more of an issue to resolve, my protagonist has a function that returns true if it collides with an obstacle, triggering a lose game sequence. I’m using basic geometry to handle collisions with the environment, but this won’t work for enemies and dynamic obstacles. I’m going to attempt swapping raycasts out for OnCollision/OnTriggerEnter checks

SFAS Days 4 & 5

So day 4 ended up being especially busy for me, I was only able to get back-end improvements done to the project. The code was restructured to better allow for multiple level appearances and characters, since currently I was editing the prefab’s inspector variables manually to see change.

Over both days, here’s what I got done:

  • Restructured code
  • Created some more character and environment sprites
  • Improved shader code
  • Rubble spawns from broken rocks, coins can also be obtained this way
  • Score counter
  • Game states are back, and it’s now possible to lose the game

There are a couple of things I was asked to go in to detail on, I’ll try to do so on a break, that’s all for now. Next goal is to implement a high-score and total-score counter in order to unlock the extra content.

~ Oli S-L

SFAS Day 3

I took a break yesterday, then got back to work in the evening to add coins and our character’s “super move” which bursts through all the obstacles. Despite not putting so much time in to the project yesterday, a lot of interesting things went on to make all of this happen.


Making it Rain

The coins themselves were easy to implement with what I already had, the sprite is animated using my SpriteAnimation script, and Unity’s collisions take care of collecting the coin, but having the coin just disappear on you is boring. I wanted the coins you collect to fly in to the top-left corner where the score counter is going to be.

There are two coin prefabs in use: one to be collected by the player, and one “post-collection” coin whose only purpose is to curve to its destination and then vanish.

To curve the coin I wrote a BezierCurve script, you set it up with the coin’s starting position, a destination and some random point to the right of the screen

A rough diagram to show what the Bezier Curve is doing, ‘u’ transitions from 0 to 1 .

So this worked, the next issue was when to remove the collected coin from the scene.  If you’re familiar with Unity you’ll notice that the coins in the gif used Trail Renderers to create the yellow streak that follows their path. Removing a GameObject that has a TrailRenderer component attached will remove the trail abruptly.

The cost of aesthetic.

So instead the collected coins has a configurable value for their ‘end lifespan’, when they reach the end of the path, they will go invisible for this amount of time giving the trail time to catch up and finish gracefully, at which point the GameObject is then removed.


Super Move

In addition to collecting the coins, I want for a special powerup to exist in the game, when collected it sends the player in to an over the top rainbow-charged frenzy that allows them to charge full speed through the game, destroying all the blocks in their path.

This was again done with the use of a TrailRenderer and ParticleSystem, probably the most challenging part of this for me was tackling shaders, something I’m not familiar with yet.

Unity’s standard shader (left), and then two of mine.

The Unlit/Cutout shader was my first test run with Unity shaders, since it was bugging me that I had to use a lit shader in order to preserve the transparency on my sprites. If you’re looking to get started quickly with shaders in Unity, Dan Moran’s video tutorial offers a very fast review of the basics, more than enough to get started (and then I’m sure there’s plenty of more advanced documentation of writing shaders out there)

The Unlit/RainbowPower shader was the result of plugging random numbers in and experimenting with the _Time and _Sin or _CosTime variables (Unity docs on built-in shader variables, a great resource)

I plan to experiment more with shaders as I’m starting to realise just how powerful they can be. One simple tweak I would like to make is having the rainbow shader transition through the colours more frequently.

All that was left with Super Move effect after this was to attach the shader to the trails, particles and player, then activate it at the right moment.


Breaking the Terrain

This was probably the toughest to get right, the approach is straightforward but it’s easy to make a mistake on some of the lower level parts.

  • We find the tiles surrounding the player
  • If they are solid, the Wave needs to be updated to set them to non-solid.
  • The TileMap for that Wave then needs to update the appropriate tiles to match the changes.

That last point is where a few attempts were made to get it right, remembering that I wrote the TileMap so that it would auto-tile: When a block is removed, the surrounding tiles must also be updated to no longer connect to it.


 

On to Day 4

I was actually up until 4am finishing off most of the stuff above, and I managed to optimise a few of the texture handling scripts while I was fixing the terrain breaking mechanic. That said I’m now ready to continue!

Today’s goals are to add rubble for when a block is destroyed, a get game states reimplemented (the skeleton project we were given to start us off has this set up already, but I disabled the original scripts while I got my concept to work.)

As always, you can direct your feedback or comments to my Twitter @Jindont.

~ Oli S-L

 

 

 

 

SFAS Day 2

View post on imgur.com

After yesterday’s work, I ended the day with something playable! The level generator adds waves as the player progresses, and removes waves that have strayed off-screen. The player must tap to swap surfaces, avoiding all walls and future obstacles.

I’m going back to work today as I’m ahead of schedule with this project, so I expect to get less done this time, but my next two goals are 1) Make it look nicer, and 2) add obstacles and collectibles!


 

The Level Class

The Level class is responsible for managing the waves, and for retrieving tile data for the player. It iterates through the existing waves (which maxes out at 3 before they start getting removed) until it finds the wave that the player is on.

Waves have a width, height, starting X position and an array containing their collision data. So checking that the player is on a specific wave is as simple as making sure they’re between startX and startX+width. If the Player wants a tile, it calls level’s GetTileAt(x,y) function, which then calls the appropriate wave’s GetTileAt(x,y) function, and returns that result.

Currently, the player only requests 3 tiles from above or below its current position (depending on the direction it’s falling). If a resulting tile is solid, an AABB collision test occurs between two rectangles formed from the player and the tile positions and scales.


 

Frog Bro

The current protagonist!

Coming from a Flash background, I’m not a huge fan of Unity’s animation tools. I find it very slow and overkill when trying to animate a simple 2D sprite, I’m assuming it’s meant for bigger tasks than that but it remains a painful process for cases like this.

So I wrote an AnimatedSprite script, it takes a Texture in the form of a spritesheet like the one above, and an array of animation data (name, frames used, and speed of the animation). The object can then be called on to set its animation to whatever you gave it, it will select the appropriate frame from the spritesheet and draw that on to a Quad.

I’m quite pleased with the result of this script, and a change of parameters is all it takes to implement a new sprite. When I have more time I’ll probably polish it and release it here.


 

This is all I have time to write for now, later today I hope to make a start on collectibles but we’ll see how that goes. For queries and feedback, reach out to me on Twitter @Jindont!

~ Oli S-L

SFAS Day 1

My 2 weeks started yesterday for the second round of the Search for a Star competition. The competition is a nationwide programming challenge for students and graduates that attempts to mimic an application process.

The second round gives contestants 2 weeks to make a game in Unity and publish it to the Windows Phone store. Last year my project got me a ticket to the final round interview, which was a miracle in itself given how restricted I was working on a slow, near broken laptop. I even had to take it to lectures to make progress as it was the only way I’d have time to finish everything. It was also one of my first times really using Unity.

Not my best work, but for a 2 week time-limit I was more than pleased with it!

Upgrade Your Workflow

This year, my placement has afforded me a proper setup, complete with a high-end desktop and multiple monitors, in addition I’ve booked time off work to focus on the project for its duration!

Having a faster machine has also allowed me to spend time looking at workflow improvements before going ahead with implementation. In my first blog entry I was looking at creating Tilemaps out of meshes, and said that I’d like to create an editor to allow for user created tilemaps.

So that’s what I focused on for Day 1, I rewrote the tilemap scripts and scriptable objects infrastructure, then proceeded to write an EditorWindow with very basic functionality for creating a level (or “Wave” as it’s called in this project)


Draft 2D Level Editor

It’s no Tiled but it will certainly do.

So how is it used? First you set the dimensions of your wave, and the window will resize itself to accommodate a grid which fits your given size. Left-click dragging will create black ‘walls’, while right-click dragging will erase them. All that’s left then is to enter a name and click ‘Save Wave’, Unity then creates an asset out of your drawing.

The ‘Wave’ asset, the string property is an artifact from not having the level editor originally, you can change the level with this provided its length agrees with the width and height.

Under the hood, the window itself works by calling DrawRect() and referring to a 2D array of integers to determine which colour to use for each rectangle, the window automatically resizes as you change the dimensions of your level as well.

Since my tilemap script attempts to stitch edges and corners together algorithmically, I have no need for a tileset display or the ability to see what tile you’re placing in this version, though it wouldn’t be too tricky to implement and certainly something I would add before releasing any of it.


On to Day 2

Today’s work will involve getting a factory in place to generate the level, the level is made up of ‘Waves’ which my editor is used to create. A Wave is just a segment of the level, I’ll create a large pool of preset waves which the factory will then choose between when it comes to generate the level.

Level will be assembled from randomly selected presets, Player will ask Level if it’s colliding with any of the tiles in each Wave.

Having an editor allows me to ensure that the waves are surpassable, and also allows me to do things such as pick viable locations for collectibles such that they will never be unreachable.

Hopefully my post tomorrow will give more of an idea of the actual gameplay as I wrap up on this workflow business.

If you’re interested to see more about the Tilemap solution, see my previous blog post. If you have questions or feedback, feel free to reach out to me on Twitter @Jindont!

~ Oli S-L

Tile Maps in Unity

I’ve been experimenting with Unity a lot lately. I’ve usually worked with 3D prototypes but this weekend I wanted to investigate the work that was involved in getting something tile-based up and running.

I was going to do an introductory blog post first, but I’ve made some interesting developments with this so I thought I would document it all here now.


Tile-Based Anything in Unity

The main annoyance I’ve had with trying to do anything tile-based with Unity is that a lot of the documentation and tutorials I’ve read seem to steer you in the direction of using GameObjects for each individual tile. While this approach is simple and easy to follow, I don’t feel that it scales well, and I generally dislike approaches that clog up the Hierarchy this much (granted steps can be taken to organise it properly)

Fortunately, there are some techniques that can be learned to get around the use of GameObjects per tile, this fantastic tutorial series by quill18 introduces you to the concept of creating meshes programmatically, and even touches on extending the editor, a technique that I think is essential to getting the most out of Unity.

I followed enough of the series to get a basic understanding of the process, and set off to produce this:

What we have is a script component in which you specify your level’s dimensions in tiles, along with the scale of each tile in Unity units. The script will take this, generate a mesh and a texture to produce what you see on the left. quill18’s tutorial also shows you how you can add a custom element to the component’s inspector in the form of the ‘Rebuild’ button, which in my script allows you to generate a new level, the changes are also visible in edit mode.


The Process

The end goal with this was to produce something seamless with a very minimal tileset. Something like these which contain just enough information to construct what you see in the above screenshot:

These have of course been scaled up, each tile is 16×16, making each tileset 48×48.

The map is an array of 1’s and 0’s, where 0 is air and 1 is a solid block. Initially the mesh was only textured to show solid tiles, with no inclusion of the edge tiles. Below is a screenshot comparing this original look (foreground tileset) with the new, auto-tiled look (background) which gives all adjacent tiles a connected appearance:

Getting the auto-tiling to work was an interesting challenge on its own, and one that still needs some work before it will work with any tileset I give it.


Auto-Tiling Our Level

The first step in my approach was to assign numbers to each of the corner and edge tiles surrounding the center ‘wall’ tile, like so:

Then, for each tile in our level’s array, we compare its surrounding 8 tiles and add the corresponding number from the above image.

int getAdjacentTiles(int x, int y) {
    int value = 0;
    int center = 0; // have we reached the center tile yet?
    for (int i = 0; i < 8; i++) {
        int currentX = x + (i%3) - 1;
        int currentY = y + (i/3) - 1;
        if (currentX == x && currentY == y) {
            center = 1; // for offsetting i after the center tile.
            continue; // skip the center tile
        }
        if (tileOutOfBounds(currentX, currentY) 
        ||  levelTiles[currentY,currentX] == 1) {
            value |= 1 << (i - center);
        }
    }
    return value;
}

After getting this value for a tile, you can determine which edges/corners need to be added by checking if the expression:

value & (1 << i)

is non-zero.

In Unity, stitching adjacent textures together on to a single tile was easier said than done, although I could be something crucial in Texture2D’s functionality. Traditionally, you can use Texture2D’s getPixels() and setPixels() to effectively combine portions of textures together. This is fine so long as you don’t intend for your pixels to overlap, but in my case this was not so, and as a result the transparent pixels would overlap the colour.

I got around this with a naive rewrite of the setPixels function, which attempts to ignore ‘transparent’ pixels so that only the non-transparent parts of an image are overlayed:

private void setPixels(ref Texture2D texture, int x, int y, int w, int h, Color[] p)
{
    for (int i = 0; i < w* h; i++)
    {
        if (p[i].a != 0) // if the pixel to be written is solid
        {
            texture.SetPixel(x + (i % w), y + (i / w), p[i]);
        }
        else
        {
            // this was a hack to ensure that the image wouldn't
            // lose its transparency, like I said it needs work.
            Color c = texture.GetPixel(x + (i % w), y + (i / w));
            if (c == Color.white || c == Color.clear)
            {
                texture.SetPixel(x + (i % w), y + (i / w), Color.clear);
            }
        }
    }
}

This is something I will come back to, since I’m sure there’s going to be a better way to get around this then what I went with. That said, I’m very pleased with the end result. I have a script generating a mesh, a random level and auto-tiling the mesh according to that level’s data.


What’s Left?

The next step with this is that I want to extend the editor further to allow the user to draw the level on to the mesh themselves, at that point I may release what I’ve got so far for others to mess around with.

~ Oli S-L