The Other Sky Alpha – Technical Reflection

26581-shot1

You can play my jam entry for Ludum Dare 30 here: The Other Sky

This game was a semi-ambitious idea, but I generally enjoyed developing it. One of the most important things to implement was for the first person controller to be able to support flipped gravity.

I tried to get this working with Unity’s CharacterController, but it wouldn’t be feasible for my purposes. Unity’s CharacterController only works best assuming gravity is always pointing down (with respect to the scene’s world coordinates). When gravity flipped upside down, the CharacterController would not consider itself grounded, even if it landed on a flat plain.

To remedy this and other problems with gravity, I looked for a custom alternative to CharacterController. I found something on Unity’s community called RigidbodyFPSWalker, which acted like a character controller but had Rigidbody properties. The fact that this script didn’t require Unity’s CharacterController allowed me to customize the behavior of things like gravity more easily.

RigidbodyFPSWalker does not support the flipping of gravity automatically. I don’t know of anything out there that does. So I implemented the gravity flipping functionality myself by modifying RigidbodyFPSWalker.

Unfortunately, I spent so much time implementing and tweaking gravity-flipping that I was not able to have too much time making interesting levels for the game. If I continue making this game, I will definitely make interesting puzzles and make gravity flipping a very important mechanic.

Unity3D Camera Movement Revisited

>>Get the revised camera movement script with inertia from Github Gists<<

Some several months ago, I made a much visited tutorial about rotating, panning, and zooming a camera in Unity3d. I was asked if it was possible to make the camera movement more smooth. While I thought the movement was already smooth, no one can ignore the fact that if you let go of mouse when moving the camera, it will suddenly stop.

A more desired behavior is for the camera to smoothly stop after letting go of the mouse. In order for this to work, the camera needs to have some inertia, thus physics properties.

In the link above with the revised camera script, I implemented a version of camera movement that will stop smoothly. You can even control this smoothness from the pubic variables turnDrag, panDrag, and zoomDrag.

Internally, a RigidBody component would be required for this to work, but I made the script take care of that, so that you don’t have to. In other words, if you’re using this script on a camera, do NOT add a RigidBody component because the script will do that automatically.

Continue reading

The Motivation behind XboxCtrlrInput

XboxControllerThe motivation to make XboxCtrlrInput came about from a problem I’ve encountered a few times in Unity3D.

It started with my team capstone project, Fortress Fiasco. One of the important features the team wanted to implement was local co-op play with multiple Xbox 360 controllers. I remember the programmer in our team who was implementing Xbox input was complaining about how awful Unity is about handling multiple joystick input. And he’s not the only one. I looked into his input code and realized that Unity was probably treating joystick input management as an afterthought. Of course I love using Unity, but I think Unity should improve the handling of multiple joysticks.

Flash forward to my Ludum Dare entry 10 Seconds In 10 Seconds, I wasn’t thinking about multiplayer at the beginning of its development. I did implement joystick input with an Xbox 360 controller, but my focus at the time was to make a single player game. Joystick input with just one joystick isn’t terribly hard with Unity. Towards the middle of development, I realized that it was possible to make a multiplayer version of the game because it became a top-down duel. I had to decide between either an AI opponent or a human-controlled second player. I didn’t have two Xbox controllers at the time so I chose to tackle with AI.

When I submitted my game on Ludum Dare, I got a lot of feedback saying that the game would be great with multiplayer, and I agree with them. Considering the control scheme of 10 Seconds In 10 Seconds, I thought using multiple Xbox controllers would be the best way to go, instead of having two players share the keyboard. Since I released a Mac, Windows, and Linux version of the game, it only made sense to me that a post-Ludum-Dare version of the game should continue to work on all those platforms with multiple Xbox controllers.

I know it sounds a little naïve, but I always figured that one of the goals of Unity was to allow people to develop games they can release on multiple platforms. Ideally everything should work on multiply platforms, including joystick input. It’s obviously not as simple as it sounds.

There are two major problems you have to face when implementing such a system. First, you have to get button mapping and axis mapping to “just work” on every operating system. For that, I won’t put much blame on Unity, since that’s a platform-dependent ordeal. But I will put much blame on Unity for the second problem: multiple joystick input support is lacking and difficult work with.

There appears to be a few attempts that exist out there on the internet to try to solve this problem, but none of them are perfect. Somebody with the domain name “uberdruck” showcased a web build that seems to be pretty good at handling multiple controllers, but uberdruck does not explain how the demo’s input system works. It’s only useful as an observation for what is possible. Deciduous Games made a C# input wrapper for Xbox controller input. It’s similar to XboxCtrlrInput in terms of being a static class, but the input mapping was implemented with Windows in mind, and thus will not work on other platforms without tweaking it. The last and most popular solution was a Github-hosted project called XInputDotNet, which is an XInput wrapper to allow XInput to work on .NET and Mono frameworks. This allows XInput to be used in Unity, which will allow for much better Xbox controller input. Only problem is that XInputDotNet relies on DirectX, so it will only work on Windows.

My goal with XboxCtrlrInput is to make a C# wrapper for Unity that makes it easy to get input from Xbox 360 controllers on multiple platforms (Mac/Windows/Linux). The included C# class XCI should be interfaced in the same way as Unity’s Input class. It sounds like a lot, but I’ve made fair progress. I invite anyone to contribute to the project on Github here. It’s free, open-source, and public domain, because I think Xbox controller input should “just work” with Unity. If you want to know the current issues about getting the input to work, be sure to take a look at XboxCtrlrInput’s Issues page on Github. If you don’t use Github, you can download a zip file containing the latest code from Github. Demo project included requires Unity 4.2 because I make use of text asset serialization (which became a free feature in version 4.2).

How to force all newly imported sounds to be 2D in Unity

[This is a cross post from the Fortress Fiasco blog.]

While importing audio into the game, I came across an annoyance. Since Radioactive Lollipop weren’t using 3D sounds in Fortress Fiasco, I had to convert all audio to 2D sounds by unchecking “3D Sound” in the inspector. This is not too big of a deal with small sound effects, but with large music files, Unity ‘re-imports’ the audio file and can take a little while.

So if you’re making a game with Unity and for the most part your sounds will be 2D or you don’t want to waste time converting music to 2D, use this C# script. For it to work, you must name the script “Force2DSound” and put it in the Editor folder. If you don’t have an Editor folder, you’ll have to make one under the Assets folder (so it would be "/Assets/Editor/Force2DSound.cs"). The script looks like this:


using UnityEditor;
using UnityEngine;

public class Force2DSound : AssetPostprocessor
{

    public void OnPreprocessAudio()
    {
        AudioImporter ai = assetImporter as AudioImporter;
        ai.threeD = false;
    }
}

After making this script, just import some audio into the project. It should have “3D Sound” unchecked automatically. Enjoy.

[Update] It seems that if by chance you wanted a 3D sound and you checked “3D Sound” in the Inspector, it will enforce 2D sound. So now I only recommend you use this script if you only want 2D sounds. Delete this script once you want 3D sounds.

———————————————————————

[Update 2] IMPORTANT: It seems this script doesn’t work properly in Unity 4.2. The imported sounds are labeled as not being 3D but when loaded into an AudioSource, it thinks they are 3D and plays them as 3D. I would NOT use this script anymore.

———————————————————————

[Update 3] Changed OnPostprocessAudio() to OnPreprocessAudio() and removed the AudioSource parameter. Works again, but you will still need to delete this script if you want 3D sounds in your game.

Planetary rotations and revolutions in Unity

———————————————————–

Work on Caelium is finally under way, but there will probably be only gradual progress. I implemented a system where celestial bodies can orbit around other celestial bodies and also a system where the bodies rotate on their axis.

To do this, two rotations were required: axial (around its axis) and orbital (around another body).  In Unity, when I tried to apply both types of rotations on a body (as a single GameObject), only the orbital rotation seemed to work.

To fix this problem, I had a simple GameObject hierarchy. You start with a CelestialAnchor, which is basically a point in space that orbits around another CelestialAnchor. It’s responsible for the position of the planet/star/moon and its orbital rotation.

Each CelestialAnchor holds a CelestialBody, which contains the 3D model of the planet/star/moon and does the axial rotation.

In this hierarchy, the planets have an orbital and axial rotation applied, as seen in the video. The speed of the rotations and the distances between the bodies can be tweaked in the editor.

Rotating, Panning, and Zooming a Camera in Unity

————————————————

Link to code on bottom of post. ↓

————————————————

In Caelium, one of the features I wanted was simple camera movement system that could rotate the camera, pan it on the plane defined by its forward direction, and zoom. In the video, I demonstrate the movement of a camera in Unity.

To rotate the camera, you left click the mouse and move around. To pan the camera, you right-click the mouse and move around. To zoom, you middle click the mouse and move up or down.

By no means is it perfect, but what I have now is pretty good, as you can see in the video. I’ll explain how the movements work.

Continue reading