VisionDesign http://gabrielkoenig.com/ghosttime We make weird games Thu, 09 Nov 2017 20:44:37 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.1 http://gabrielkoenig.com/ghosttime/wp-content/uploads/2021/08/favicon-150x150.png VisionDesign http://gabrielkoenig.com/ghosttime 32 32 Slicing a 3D scene for 2D parallax http://gabrielkoenig.com/ghosttime/slicing-a-3d-scene-for-2d-parallax/ Thu, 09 Nov 2017 20:44:37 +0000 http://gabrielkoenig.com/ghosttime/?p=523 Slicing a 3D scene for 2D parallax Read More »

]]>
It’s been too long since I posted any tutorial stuff. I’m working on a specific thing to do with Jettomero this week and needed to create a dynamic diorama scene without being able to use my game shaders – since the final product will have limited use of shaders/lighting. Since I wanted to keep the look of the game intact I decided it would be best if I used 2D layers for this. Here’s a little sample of the view in Blender3D.

I could have rendered out individual objects into 2D, but this would have not only been time-consuming, but the lighting/shadows and perspective would be difficult to fake. So I used a full scene from the game in Unity3D. It took me a while to find a planet and arrangement that I liked (since it’s all procedural) but I eventually got something that I thought would work.

Here you can see everything is in 3D, but all I really want is a single perspective where I can do some basic panning and zooming. The next step was to cut out all the elements I didn’t need. I removed the skybox as it is easy to add back later, and I also disabled all particles and trails since they’re too dynamic for a looping diorama. I changed the background to white for easy removal later but I could have used any flat colour to key it out.

Now everything is ready for slicing. The most important thing is to avoid slicing down the middle of any small objects, since the parallax will break if those 2 pieces get pulled too far apart. To create each slice I adjust the near and far clipping plane. In this way I can isolate specific 3D sections of the scene and then export a screen capture. Below you can see the back side of the planet, which has a bunch of objects on the backside of the planet too, but these will be blocked by the front layers in the final composition.

I made 3 scene slices, plus a separate layer for Jettomero, which will give me a few more options for animating the diorama layer. Using the magic wand in photoshop it’s easy for me to remove the white space from the background. I add all the layers into a single document.

I export each layer into it’s own file. Then I bring everything into Blender3D. I create planes for each layer and arrange them with some depth – the more space between each layer the heavier the parallax effect will be, (or you can get a similar result by changing the FOV on the camera). Too much depth will completely distort the scene so it needs some careful tuning. I also added a few little drone ships into their own planes which will be able to be animated separately in addition to providing a stronger sense of depth.

That’s essentially all there is to it. It took me several tries to get a scene that worked well since certain elements didn’t always work so well with the layered depth. I’m not sure what other practical applications this kind of thing would have for other people but hopefully you’ve found some of this interesting or helpful. As always, please feel free to message me if you have any questions about the process.

]]>
Jettomero: Filters Update http://gabrielkoenig.com/ghosttime/jettomero-filters-update/ Fri, 29 Sep 2017 06:04:18 +0000 http://gabrielkoenig.com/ghosttime/?p=520 Jettomero: Filters Update Read More »

]]>
Jettomero has been out for 2 weeks now and to celebrate I’ve released an exciting new update. For anyone that has explored the photo mode in the game already, you’ll know there’s a bunch of cool filters that can be applied to the picture. The Filters Update introduces a number of new filters, the ability to adjust them by preset parameters, and additionally play the game using any filter you want!

I love the way the game looks already but it made sense to me to allow players to choose how they want the game to appear, and be able to adjust it as they go. With all the different visual options available the Jettomero experience has just become even more of a trip. Check out this video for a quick preview of the latest changes.

]]>
Jettomero on Kickstarter http://gabrielkoenig.com/ghosttime/jettomero-on-kickstarter/ Wed, 02 Aug 2017 16:49:11 +0000 http://gabrielkoenig.com/ghosttime/?p=493 Jettomero on Kickstarter Read More »

]]>
To help pay for new translations and additional publishing costs I have launched a modest kickstarter campaign for Jettomero. My hope is that this campaign will also catch the attention of a wider audience as the game nears launch time.

Trying to get this game out the door has been pschologically and emotionally exhausting at times. If it wasn’t for the amazing fans and friends that the game has already attracted in the last year I think I would be feeling very different right now. I’m excited to be able to share this game with the rest of the world and it’s all going to start with this campaign.

Some very cool physical rewards are available through the campaign, including a comic book made using screen captures from the game.

]]>
Rope Physics and Rope Rendering http://gabrielkoenig.com/ghosttime/rope-physics-and-rope-rendering/ Sat, 08 Apr 2017 23:23:50 +0000 http://gabrielkoenig.com/ghosttime/?p=465 Rope Physics and Rope Rendering Read More »

]]>
I recently added snare turrets to Jettomero, which will attach cables to Jettomero’s arms when in range and pull them until the turret eventually gets yanked out of the ground when the tension is high enough. I’m sure there’s many different ways to handle something like this but here’s a quick tutorial for how I set it up.

Using Unity3D’s spring joints proved to be effective at running the physics side of this system. For the rendering I used a single line renderer. Since the Line Renderer component relies on specific points to draw to I needed to keep assigning new positions in my Update() function. I assign the first point in the line to the origin of the cable where the first joint lives. Then I run a for loop to iterate over each joint in order of their chain, I can assign each additional point in the line to the position of the connected rigidbody, the last of which will be Jettomero’s arm. So the cable will get rendered for the entire length of the joint system.


You’ll probably want to make sure the line renderer has the Use World Space toggle selected so that all the transform.position references are in the proper space.

As for the RigidBody and SpringJoint components, this was what my settings looked like once I got things working how I wanted.

All the joints are set up the same except for my turret base I freeze the position and rotation so it can pull against Jettomero’s arms. Then I check  joint.currentForce.magnitude against a pre-defined threshold. When the force is high enough I disable the constraints on the base and it come flying out of the ground towards Jettomero.

The joints took me a while to figure out, the Auto Configure option was throwing me off for a while. It really depends on how you’re setting up your scene so sometimes it’s best to run the game and just mess with settings until it’s working how you want. Then right click on the component in the inspector, copy the component, stop the game and then paste the runtime component settings back in. Playing with physics takes patience and lots of tuning and iteration.

That’s essentially it. If I missed something or you have any questions feels free to reach out to me on twitter @GhostTimeGames.

]]>
New Generative Textures using Particles http://gabrielkoenig.com/ghosttime/new-generative-textures-using-particles/ Fri, 07 Apr 2017 17:39:19 +0000 http://gabrielkoenig.com/ghosttime/?p=456 New Generative Textures using Particles Read More »

]]>
I switched to a new fully generative system for creating my planet textures yesterday. I was previously using a few hand-drawn source files and manipulating those but now I’m using a particle system to form my source, largely thanks to the latest Noise and Trails modules in the Unity3D shuriken system.. There’s some neat features that let me do stuff like this:

So I can manipulate the lifetime and size over lifetime and overall size and noise distortion of these lines. Then I render it into a new Texture using a render texture and stack it 10 times with some randomized rotation and random tiling/scaling in the material.. Which gives me stuff like this:

Then I just throw that texture onto the planet and my shader will threshold it and adjust the lines based on the lighting. So it ends up like this:

It’s very similar to the look I had before but because I’m no longer limited to a range of hand-drawn textures it gives me lots of opportunities for greater random variety. It’s exciting creating a system that still has room for surprises each time I visit a new planet. I’ll continue to experiment with the particles to create an even wider range of possibilities.

]]>
Jettomero coming to Xbox One 2017 http://gabrielkoenig.com/ghosttime/jettomero-coming-to-xbox-one-2017/ Mon, 03 Apr 2017 21:22:39 +0000 http://gabrielkoenig.com/ghosttime/?p=445 Jettomero coming to Xbox One 2017 Read More »

]]>
Jettomero: Hero of the Universe is officially coming to Xbox One later this year. The team at ID@Xbox has set me up with everything I need to get the game running on this exciting platform and I’m very pleased to announce that the game will be launching here first. More details on exact dates are TBA.

I’m also excited to announce that I’ll be teaming up with the wickedly talented folks at A Shell In The Pit to make sure the audio in the game is top notch. They already did the SFX for the trailer below and it’s already sounding very good!

]]>
A Disclaimer for Jettomero http://gabrielkoenig.com/ghosttime/a-disclaimer-for-jettomero/ Thu, 16 Feb 2017 19:22:59 +0000 http://gabrielkoenig.com/ghosttime/?p=431 A Disclaimer for Jettomero Read More »

]]>
Please note this is not a tutorial. This is me attempting to explain a number of things to both you and I to alleviate certain expectations about Jettomero that I’m concerned some people may have and that may also be causing me stress/depression. I know there’s lots of great games out there that don’t conform to any pre-existing ideas of what a video game should be – even so I find it difficult at times to feel confident in pushing that myself. Before I start hyping the game for launch I’d like to make a few things clear.

  1. Jettomero probably isn’t the game you think it might be. This is intentional. The core concept of the game (long before it ever took any sort of shape) is still at the base of everything and is very important to me. In order for it to work I do need to undermine the player’s expectation. Some people may not like this. So be it.
  2. Jettomero is more of an experience than a game. This relates to my first point again, I’ll be playing with some gaming tropes explicitly to flip them on their heads.
  3. Jettomero will probably be confusing when and if you first pick it up. I’ll tell you how to play, but I won’t tell you why. I’m not going to give you a mission to complete. The meaning to your actions will need to come from you.
  4. Jettomero is only intended to be 2-3 hours long. This is all the time I need to do the things I want to do and I don’t see any reason to drag this out.

That being said, I do hope you enjoy Jettomero.

]]>
World Space to Screen Space UI http://gabrielkoenig.com/ghosttime/world-space-to-screen-space-ui/ Tue, 20 Dec 2016 21:22:39 +0000 http://gabrielkoenig.com/ghosttime/?p=418 World Space to Screen Space UI Read More »

]]>
It’s not actually that complicated but this is a simple technique for achieving the effect of 2D UI tracking world space positions. If you’re new to Unity then this tutorial may be helpful to you.

The Unity3D UI offers great flexibility, allowing easy setup of multiple canvases in screen space and world space. World space UI works exceptionally well for things like interactive computer screens, but may not always be exactly what you want due to scaling/orientation. In the above case, I needed a way to clearly mark all the planets in the system, so I render them all in the main screen space UI and use the setup as I will describe below.

Step 1) The parent rect transform should extend to all edges of the screen, otherwise this will not work.

Step 2) The UI object should be configured as such:

The important details to note are the anchor is in the lower left corner and the pivot is set to 0, 0. This ensures that the origin of the UI element will always track to the exact point. If you want it off-centered then you can modify the children of the main tracking UI element.

3) Now in your update function you’ll want to find the world position of your target and then set the UI RectTransform’s anchored position. Here’s the example from my code (where I’m iterating over a list of available planets).

Vector3 viewPos = Camera.main.WorldToViewportPoint(planets[i].transform.position);
planetLabels[i].anchoredPosition = new Vector2(viewPos.x * canvasSize.x, viewPos.y * canvasSize.y);

planetLabels[i].gameObject.SetActive(viewPos.z > 0);

The viewPos will always be a normalized value between 0 and 1. So when you apply that to the anchored position of the UI you’ll need to multiply it by the canvas’s size. The size won’t always match the screen’s dimensions, so to find the canvas size you should use Canvas.pixelRect.width and Canvas.pixelRect.height – referencing the Canvas object in the UI element’s upper hierarchy.

It’s also very important to note that if the viewPos.z is less than 0 it means that the object is behind the camera, so unless you take this into account for your handling (in my case I disable the game object), the UI will show up in a mirrored position if it is behind the camera.

That’s all there is to it. In the gif above I also modify the alpha of the parent CanvasGroup to fade in and out the elements. As always, let me know if you have any questions @GhostTimeGames on twitter.

]]>
Jettomero OST http://gabrielkoenig.com/ghosttime/jettomero-ost/ Thu, 17 Nov 2016 17:54:34 +0000 http://gabrielkoenig.com/ghosttime/?p=406 Jettomero OST Read More »

]]>
Two weeks ago I released the Jettomero OST – it’s one of my favourite sets of music I’ve ever recorded. It’s inspired quite a lot of by Boards of Canada, as well as as Phantogram, in addition to many more subtle influences. I ended up writing/recording each song in a single session each – usually around 4-5 hours, which I find is one of the only ways that I can work on music these days. The overall tone of the album is down-tempo and spacey, a little dark at times but more uplifting in other parts. As a soundtrack for the game I think it captures all the feelings I’m trying to go for.

I used mostly the Korg Minilogue for my sounds but also included a good amount of guitars running through synth effects and delay. It took me at least 3 false starts to finally get this soundtrack figured out but once I got rolling with the first track the rest just kind of followed. Really enjoyed the whole process.

Take a listen!

]]>
Runtime crater mesh deformations http://gabrielkoenig.com/ghosttime/runtime-crater-mesh-deformations/ Sat, 12 Nov 2016 22:28:49 +0000 http://gabrielkoenig.com/ghosttime/?p=403 Runtime crater mesh deformations Read More »

]]>
Since I’m already deforming my planets at runtime using a noise map, it made sense to include the ability to add craters to the planets when a large event occurs (landing or blasting off for example).

landingcrater

It’s not entirely ideal but my system seems to work alright – the biggest issue is that I use the deformed surfaces for my mesh collider as well so I need to be careful how much I warp the surface or it might cause issues with character mobility.

 

Here’s the gist of it:

float craterSize = 5.0f;

Mesh mesh = GetComponent<MeshFilter>().mesh;
List<Vector3> vertices = mesh.vertices.ToList();
for (int i = 0; i < vertices.Count; i++) 
{
     vertices[i] = transform.TransformPoint(vertices[i]);
     float distFromCrater =  Vector3.Distance(vertices[i], craterOrigin);
     if (distFromCrater < craterSize)
     {
          Vector3 dirFromCrater = (craterOrigin  vertices[i]).normalized;
          vertices[i] = vertices[i]  dirFromCrater * (craterSize  distFromCrater)/2.0f;   
     }
     vertices[i] = transform.InverseTransformPoint(vertices[i]);
}
mesh.SetVertices(vertices);
mesh.RecalculateNormals();

 

So once I have an array of all the vertices I convert each one into world space (using transform.TransformPoint()) and I can check how close each vertex is from the source of the crater explosion. If a vertex is within range of the crater explosion then I move it back away from the crater origin based on its proximity – so it’s most impacted at the center and becomes gentle towards the edges. Then I convert the vertices back to local space using transform.InverseTransformPoint() and I can assign my modified vertex array back to the mesh. It’s also very important to recalculate the normals.

That’s essentially all there is to it. I use a particle system using rock models to represent the earth that has been displaced and mask the sudden model change in the explosion effects as well. I’ll likely need to limit the number of craters that can be made in a single area to avoid the terrain being completely distorted since it’s definitely possible to start making things weird with enough repeated deformations.

]]>