polybeach asset

Best #unitytips from Twitter – 4

Every Tuesday we collect the best #unitytips from twitter for you!

(Cover image is from our POLYBeach asset)

polybeach asset

Best #unitytips from Twitter – 2

This is the first post from the weekly #unitytips series. Every Tuesday we collect the best tips from twitter for you!

(Cover image is from our POLYBeach asset)

Which rendering pipeline should I use?

polybeach asset

Best #unitytips from Twitter

This is the first post from the weekly #unitytips series. Every Tuesday we collect the best tips from twitter for you!

(Cover image is from our POLYBeach asset)




Best assets for world building

Making an environment that looks good is a time-consuming hard task without proper tools. My intention with this article is to show you a bunch of very good asset that will help you a lot to make your world in Unity.

Full disclosure: The links below are affiliate links, which means that if you choose to make a purchase, I will earn a commission. This commission comes at no additional cost to you. Please understand that I have experience with all of these assets and publishers, and I recommend them because they are helpful and useful, not because of the small commissions I make if you decide to buy something. Please do not spend any money on these products unless you feel you need them or that they will help you achieve your goals.

Terraforming

The first step to create an outdoor environment is set up the terrain. Although you can draw hills and mountains in Unity by hand, you are better of with a tool that does it for you. Especially if you aim a realistic environment, which requires artistic skills and also some geographic knowledge.

I show you two of the best procedural terrain generator you can find in the asset store.

Gaia combines the procedural generation and the artistic approach in a stamp-based workflow. You can use it fully procedural, manual, or in between.

1100+ positive rating, 400+ review, and the fact that Unity selected as a free Plus/Pro addon back in 2018 assure you the high quality. You really can’t go wrong buying this asset!

If you are looking for a more traditional procedural tool, map magic should be your choice. Not that widely used as the GAIA, but still has 200+ positive ratings and 100+ review. It comes with a free demo version which you can (and should) download and test if this asset works for you.

A living world needs WATER

While you can make environment without any water effect, this can really improve the look of your scene, provided that you have the right tool and shader.

This asset is a genius. It has a river spline editor and a lake tool. The water shader is just beautiful and has tons of customization option. Comes with a set of artistic content like textures, particles, for both PBR and non-PBR or artistic style.

They released a 2019 version to support Unity version 2018.3 and later.

Aquas could be an excellent alternative for water if you somehow won’t choose RAM. It’s quite a powerful asset.

Even if you have RAM this still could be useful for you.

Aiming full realism?

CTS is a PBR shader pack which enhances the looks of your terrain. Must have if you want to go full realistic.

As in case of RAM, this asset also has a 2019 release to work with the 2018.3 and later Unity versions.

Make it green!

In general, Nature Manufacture has quite nice nature packs, especially the Dynamic Nature series. I would start with the Starter pack, due to the large variety of plants and rocks. The Meadow Environment is also worth its price.

Sources:

Shadowdancer Devblog Week 7 – Vertical Slice I.

Last week we began a new project, and start building the game up again for the Vertical Slice. We finished to build the level and adding the gameplay elements to it. We fixed many issues that came up during that. This video would be very long if I would talk about all of these, and to be honest, many of them aren’t that interesting.

I picked a few problems and ideas that actually taught us something new.

Transparency shader - Low FPS

We had the problem when the player hides in the bushes it will cover most of the viewport.

I made a transparency shader that looks much better than the standard shader. I’m not a shader programmer, didn’t learn the syntax. I have some experience with the material editor in Unreal Engine, so I needed a similar solution to make a shader. My choice of tool is Amplify Shader for this task, which is a great tool!

Regardless of all my efforts, the result was devastating: the FPS rate dropped from 100 to 30 on my machine. I should think about it earlier. If you have hundreds of transparent objects on your scene, that nothing near to optimal in deferred rendering.

I could make a script to switch between the opaque and the transparent version of the objects, based on the distance from the player, or otherwise optimize it. However, Dotti had a much simpler solution for the problem: she pushed all the bushes into the ground a little.

This way she solved the cover problem almost entirely. Elegantly simple.

Real-time Global Illumination

When generating the precomputed Global Illumination takes more than a few minutes you are doing something wrong. We never really dive deep into this area. We know something is wrong, but what?

The answer came in the form of an article series from Unity: Introduction to Precomputed Realtime GI. Worth to read all the 9 part of this series, but here is a short list to properly set up your scene for Realtime GI:

  • Set Lightmap Static to true on big objects, like cliffs, large rocks or buildings.
  • Set Lightmap Static to false on small objects.
  • Cover the playable parts of the scene with Light Probes. (specific article from the series)

After we went through these steps, our generation process speeded up and finished under 1 minute!

New Feature: Shadow Objects

Shadow Objects only visible in shadow form. When the character enters the shadow form, she partially travels to the Shadow Plane and can see these objects. Right now we have two ideas about how we can use this feature.

Give the player guidance. The shadowlings used shadow runes to mark their passages in a way that only they can detect. Only those can see these signs who steps into the Plane of Shadow.

These objects are not just visible in shadow form, but they are also touchable. The player can stay on them as long as she can see them. We can make bridges and platforms that disappear if the character steps out of the shadow.

That’s it for this week, hope you enjoyed this article. Next week we continue working on this project and getting closer to the Vertical Slice.

We’ll see you all next time!

Ribbon Compass Script

I made this script for a freelancer project originally, which was a sailing game with pirates and ships. We needed a compass, and we wanted to show the player, how the wind affects his sailing speed.

The basic idea here is to have a horizontal grid layout with Text elements. I call this the ribbon. The script moves this ribbon horizontally based on where the character is facing.

I only want part of the ribbon visible, so I use the mask component.

The problem I encountered is circularity. I wanted to translate from the end of the ribbon to its start seamlessly. The setup below resulted in a failure, the compass ran out of letters.

SE — S — SW — W — NW — N — NE — E —

I figured out I have to make duplicates. I only move the ribbon between the two S letter and let the overflowing part simulate the circularity.

The script

public class RibbonCompass : MonoBehaviour
{
    [SerializeField] Vector3 NorthDirection = new Vector3(0,0,1);
    [SerializeField] Transform Actor;
    [SerializeField] GridLayoutGroup ribbon;
            
    float _angleMultiplier;

    void OnEnable()
    {
        _angleMultiplier = 2 * ribbon.cellSize.x / 45;
    }

    void Update()
    {
        Vector3 actorDirection = Actor.forward;
        float angle = Vector3.SignedAngle(actorDirection, NorthDirection, Vector3.up);

        Vector3 ribbonPosition = ribbon.transform.localPosition;                   
        ribbonPosition.x = angle * _angleMultiplier;
        ribbon.transform.localPosition = ribbonPosition;           
    }       
}

The script is pretty simple. We need three variable for the inspector: 

  • The direction of the north: as default, I set it to Vector3.forward.
  • The actor transform. We’ll compare it’s forward direction to the north direction.
  • The ribbon. This will be a GridLayoutGroup.

We also need a private variable to store the angle multiplier. I’ll explain it later but first, let’s see what this script does.

  1. Calculates the angle between the actors forward and the north direction.
  2. Then sets the ribbon position in a way to show the right letter.

I’m using text game objects for the letters and for the separators (—). Each of these cells has the same width value, defined in the GridLayoutGroup.

Between North and North West there is 45 degrees difference in angle. If I’m staying in the center of the N letter, I have to move 2 cells:

  • I move the ribbon half cell to arrive at the start of the separator.
  • One full cell (the separator).
  • Half cell again to reach the center of the NW cell.

That’s being said, every 45° needs to move the ribbon with 2 cell width. Instead of calculating each time in the update function, I precalculate this and store it on the _angleMultiplier variable.

How to use the component

The component you can download from the Gumroad (for free) has a slightly better inspector, and also contains the color changing feature.

  • North Direction: this is a world direction. As default it is the Vector.forward (0,0,1) direction
  • Actor: This is the transform which forward will be used to determine the facing of the player.
  • Marker UI Image that will change the color based on the direction
  • Ribbon: The Grid Layout Group that contains your cells.
  • Special direction: The script will change the marker color from the default to the special when the Actor faces to this direction.
  • Color Blend: With this curve, you have more control how the two color should blend into each other.

Shadowdancer Devblog
Week 6 – Throwing out the project

Last week we finished the playable prototype, and during the weekend we gave it to our friends to test it. Now it’s time to throw everything out and start to build it up once again. No. I’m not joking, and I’ll explain it in a moment, but first, let’s talk about what we learned from the playtesting.

Playtest result of the prototype

One of our testers took her time and captured how she is playing our game. Watching this gameplay was fun, and very informative at the same time.

If you are working weeks on a game, you become less aware of the gameplay problems. You don’t make mistakes, because you know how it works. This video pointed out some issues that we couldn’t figure out. These were gameplay and level design problems that I explain later in this article.

We discovered two obvious problems just by talking with our testers:

  • In the default Quality Settings, the lower ones disable shadows in the game. While we knew about this, we didn’t realize this will be a problem, until one of our testers started to play without shadows… well, that totally ruined the gameplay for her. We have to make our quality tiers, to get rid of this problem.
  • Two of our testers went off-road. Leaving the nicely detailed level behind for a flat nothingness. We need invisible barriers to keep our testers focuses.

First Milestone: The Vertical Slice

With finishing the playable prototype, we closed down the prototype phase of the development. This also means we have to throw out our current work and start it again from scratch. A hard but necessary step since the prototype is some kind of sketch, where we drop in everything that seemed to be fit.

We spent most of our week to set up a new project, importing the assets we want to use, rebuilding the scene and writing the codes we’ll need for the game.

We made some changes on the level layout since the one in the prototype didn’t guide the player well enough. They didn’t find the shadow gate, because the level leads them right into the camp.

Three Levels of Communication

During the prototyping, I combined the 3D Game Kit event system, with my own game architecture that is based on scriptable objects. This architecture follows the idea of Ryan Hipple, he is a principal engineer at Schell Games. He made a Unite Talk about the architecture they are using.

It’s quite genius, and I was inspired to make my own version. I used this for plenty of projects since then, and it was very convenient and quick to work with. I’ll publish it in the Unity Asset Store soon, but that’s a different story.

Since we were satisfied with the workflow in the prototype, I started to build up better this combination. The core principle of this is compartmentalization: separating the parts of the system to prevent malfunctions from spreading between or among them.

You might be thinking, this is the core principle of the object-oriented programming too. You are right, but since we are using component-based architecture, where a single component contains a small code, OOP wouldn’t be appropriate here in my terms. I like to call it Three Layers of Communication.

1st Layer: Prefab

Most of our prefab functions are made with simple components that utilize UnityEvents. Our rule of thumb is that we are only using UnityEvents within the prefabs. We have the Burning Crate prefab, where UnityEvent turns on the particle, the interest target for the AI, and the audio.

2nd Layer: Scene

Every communication between prefabs on the scene works with Game Command System from the 3D Game Kit. This a great system, it’s easy to see which game object calls whom, due to the gizmos.

Currently, it supports only one to one connection type. Where we needed many to one connection, we made child objects for the prefab each with a single Game Command Sender, and call each of them with a UnityEvent.

Important: we only allow this type of communication between game objects that are connected to the scene.

3rd Layer: Game or Global

We are using scriptable object events and listener components, similar to the ones that are presented in the video above. I use Game Communication and Global Communication as synonyms.

Understanding the difference between scene communication and global communication might be difficult sometimes. Our rule of thumb is this: global is when the result of the event should be the same regardless the scene is currently loaded, otherwise it’s scene communication.

Scene Communication Example: a trigger activates the burning crates. Both of them could be used differently in other scenes, so they are communicating on the scene layer instead of global.

Advanced dialogues

For narrative dialogues, we have multiple actors on this scene: the character, the guards and the obelisks. We want to show an avatar image and the name of the actor with the text.

The first question you could ask here: why wouldn’t we use the Dialogue System I made for the Asset Store? It’s hard to admit, but it lacks an important feature that required for this project.

We could use the Runemark Dialogue System for this project, and it would work fine. The asset is made with conversations in my mind, and not with a narrative. For every box of text, we should make a new dialogue graph, which is not an optimal workflow.

I’m working on an update of the Asset to support narratives much better, once it’s done, we will put that into Shadowdancer too. Until that time, we will use this solution, because it was faster to make.

In-Game Pause Menu

It would be useful for the test to have the possibility to restart the level or load the last checkpoint when the player is got stuck somewhere. Now we have a pause menu with these options!

That’s it for this week, hope you enjoyed this article. Next week we continue working on this project and getting closer to the Vertical Slice.

We’ll see you all next time!

Shadowdancer Devblog Week 5 – Playable Prototype II.

Last week we started to work on the playable prototype. We made the first two sections of our level and developed an AI sensory system. If you missed it, I recommend to check it out. I linked two articles from Travis Hoffstetter and from Tom Leonard. Travis is a game designer at EA, while Tom is the lead programmer of Thief: The Dark Project.

Let’s see what we got done this week.

Level Building

We finished the second half of the level: the mountain path which has platformer and the puzzle room.

Building a level means two tasks: placing down the visual elements (like environment meshes, particles, sounds) and implementing the gameplay. The second half needs programmer knowledge.

Fortunately, the 3D Game Kit has very well made component based gameplay toolset, which is easy to use, even for those who don’t know how to write code. After I explained to her the basics, Dotti was able to implement most of the gameplay elements without my active help.

She made all the pop-up dialogues, triggers, burning crates, collapsing rocks, and the puzzle room by herself. This really speeds up the development, because I could focus on other parts of the game which requires heavy coding.

Player Character

Jumping is too strong in the current form. This is clear since the last playtest. After some trial, I made two changes.

The player character has two stances, stealth and normal. The player can’t switch between them, this is handled automatically. In the first two sections of our prototype level, the stealth stance will be active, while on the other two the normal.

In stealth stance, the player can move slower and not able to jump. I use different animation in stealth and in the normal mode to distinguish these two state.

Once I did this, I tested the game, and immediately have the oooh moment. I forgot that the first parts of the level also need the player to go higher ground. This could be a failure for me, but it wasn’t.

We removed the deep connection between the player and the shadow when we decided how the stealth should work (check Week 3). Stealth mechanics work very well, so we need something in place of it to represent this connection.

In the time we wrote the concept document, I had an idea of shadow dash, but we cut it out from the concept document for some reason. Now it was the time to grab that feature and put it into the game. Well, at least make a prototype and convince Dotti about it. (spoiler: I succeed)

Shadow dash is the new ‘jump’ in stealth mode. She moves forward with high speed until she reaches her destination, or a wall blocks her way. The idea came from Witcher 3 by the way, I really love Ciri’s dash ability, and I’m sure I’m not alone with this.

I want to allow the player to use this ability only from a shadow, and rewarding her when she arrives into a shadowy area. To achieve this, I implemented the Shadow Form. I only allow shadow dash, when the player is in this form.

When the player stays in the shadow long enough, her skin and hair changes its color and enters the shadow form. If she steps out of the shadow, her connection to the shadows weakens, and her skin and hair return to the original color.

During the shadow dash, the player moves to the shadow plane, because of this the light don’t weaken her connection. That being said, she can continuously dash as long as she arrives at a shadowy place.

Welcome screen and the game end scene

Even if this is just a prototype, I couldn’t let the game floating in the space, I wanted to give it a frame. I made a simple main menu and an ending scene.

We were curious, how much time does it take to our testers to go through the level, so I made a simple stopper scriptable object, to measure the playtime. I needed 5 minutes to finish the game.

The Light Entity

Since Dotti couldn’t resist the calling of Blender too long, she made a new model, this time the third participant of the level: the Light Entity.

While writing a good story is way out of our scope, we think about the story, that will be told in some day. The game is about the invasion of an evil army (perhaps demons), the world’s civilization is terrorized by this army, and only angels could defeat them.

However, angels disappeared a long time ago. Legends told, the natives of these lands were the shadowlings: small humanoids who had a strong connection with the shadow plane. Angels being light-based creatures were natural enemies of them. The shadowlings managed to imprison all the angels into mystical seals. Nobody knows if this is true, or just a fairytale.

The player is a member of the shadowling race, she knows the history of her kind and the seal’s location. Understanding the danger of the evil army decides she will break all the seals and put an end to the invasion.

The story is just an idea that came up during the development, it might change over time, but right now it’s very inspiring to work based on this.

That’s it for this week, hope you enjoyed this article. Next week we close our prototype phase and start working on the Vertical Slice. 

We’ll see you all next time!