Warning: mysql_real_escape_string(): No such file or directory in /home/drsoda/scriptocalypse.com/wp-content/plugins/esh_wordpress_v1.2.1/easy-google-syntax-highlighter.php on line 50

Warning: mysql_real_escape_string(): A link to the server could not be established in /home/drsoda/scriptocalypse.com/wp-content/plugins/esh_wordpress_v1.2.1/easy-google-syntax-highlighter.php on line 50

Warning: Cannot modify header information - headers already sent by (output started at /home/drsoda/scriptocalypse.com/wp-content/plugins/esh_wordpress_v1.2.1/easy-google-syntax-highlighter.php:50) in /home/drsoda/scriptocalypse.com/wp-includes/feed-rss2.php on line 8
Scriptocalypse http://www.scriptocalypse.com Lighting Bitmaps on Fire Thu, 16 Feb 2012 05:51:38 +0000 en-US hourly 1 https://wordpress.org/?v=4.5.2 The Way Things Used To Be :: Reset Components and Unity 3D http://www.scriptocalypse.com/?p=112 http://www.scriptocalypse.com/?p=112#comments Thu, 16 Feb 2012 05:36:43 +0000 http://www.scriptocalypse.com/?p=112 One of the very interesting aspects of Unity 3D and its architecture is the fact that it is component based. This one factor makes it very easy to implement some very interesting behavior in your games that separates concerns rather nicely. One such interesting notion is that of a Reset component.

When the Horseman created Hug Monster he realized quickly that he’d need to store the initial positions of the game’s objects somehow. Re-loading the Scene every time the player dies is simply unacceptable given the time Unity takes to perform loads, so somehow there must be a way to easily store initialization data. In other langauges such as AS3 the most tempting way to do this would be to implement something like :

HugMonsterGameObject
  public function getInitialValuesFromScene():void{ /*collect initial values*/ }
  public function reset():void{ /*reset to initial values*/ }

As a consequence, all game objects would carry this baggage around, and they all must remember to subclass HugMonsterGameObject whether they needed the functionality or not. This doesn’t sound bad on its face, but it can bloat the number of responsibilities of a given class, such that it simply has to concern itself with “too much.” On the bright side, Unity’s component-based architecture allows us to split this behavior out completely! I do have a Player class, and a Hugmonster class, but neither of them knows a thing about how to grab initial coordinates or restore to an “initial” state. Instead, the gameObjects that have Player and Hugmonster components (as well as everything that can be moved or altered) have a ResetBehaviour object sitting alongside their “main” component.

How it works is as such.

// In the file ResetBehaviour.cs
//    This is merely an abstract class, to give 
//    us a typed Component that is responsible 
//    for Resetting things.
 
using UnityEngine;
using System.Collections;
 
public class ResetBehaviour : MonoBehaviour {	
	virtual public void RecordStartingVariables(){}	
	virtual public void ResetGO(){}
}
 
 
// In the file GenericResetBehaviour.cs
//    Our most basic implementation of ResetBehaviour.
//    This is ideal for things like the blocks that 
//    the Hug Monster can shove around, or for
//    other miscelaneous objects that only move 
//    with position / rotation and have a 
//    changing velocity.
 
using UnityEngine;
using System.Collections;
 
public class GenericResetBehaviour : ResetBehaviour {
 
	public Vector3 resetToPosition;
	public Quaternion resetToRotation;
	public Vector3 resetRigidBodyToVelocity;
	public Vector3 resetAngularVelocity;
 
	// Use this for initialization
	void Start () {
                // Unity's default Start method
                // is an ideal spot to initialize
                // since this is where the object
                // was placed in the editor.
		RecordStartingVariables();
	}
 
	override public void RecordStartingVariables(){
		resetToPosition = transform.position;
		resetToRotation = transform.rotation;
		if(rigidbody != null){
			resetRigidBodyToVelocity = rigidbody.velocity;
			resetAngularVelocity = rigidbody.angularVelocity;
		}
	}
 
	override public void ResetGO(){
		Debug.Log("Default ResetBehavoiur");
		transform.position = resetToPosition;
		transform.rotation = resetToRotation;
		if(rigidbody){
			rigidbody.velocity = resetRigidBodyToVelocity;
			rigidbody.angularVelocity = resetAngularVelocity;
		}
	}
}

If an object needs a more specialized form of ResetBehaviour, I can simply derive from GenericResetBehaviour without necessarily overriding anything in the Player, Hugmonster, Switch, Wall, Camera, or any other class definition. This makes content creation and behavioral scripting ridiculously flexible.

But Mr. Horseman, why make Reset components for all these objects? Don’t you have to then grab that component from each game object, by specific type, and call ResetGO() on it?

Aaaah, I’m glad you asked. You do NOT have to do any such thing! The reset level code, which lives inside the GameManager class looks something like this…

public void RestartLevel(){
 
		ResetBehaviour[] rbs = Component.FindObjectsOfType(typeof(ResetBehaviour)) as ResetBehaviour[];
		foreach(ResetBehaviour rb in rbs){
			rb.ResetGO();
		}
 
                // a few more lines of code for displaying the Game Over text go here.
}

Because the ResetBehaviour class is virtual, and because all the Reset components derive from it in some manner, all I have to do is find every component derived from ResetBehaviour using the handy function shown above and then iterate through the resulting array an call ResetGO() on each. Every item in the scene will reset to its initial position as specified by the component without any further work on the developer’s part.

I have to say that I first looked at the component system and saw the potential for chaos, but in fact the philosophy underpinning the Unity Editor gives you ways to funnel that chaos into pure elegance.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=112 3
I dare you! I Ludum Dare you! http://www.scriptocalypse.com/?p=106 http://www.scriptocalypse.com/?p=106#comments Tue, 27 Dec 2011 00:39:07 +0000 http://www.scriptocalypse.com/?p=106 The Horseman recently gave a presentation on the 2DToolKit sprite animation library and toolchain at his local Unity 3D Users Group. As it happens, one of the attendees asked The Horseman if he’d ever heard of Ludum Dare and its 48 hour game competition. I had to admit that I was not familiar with it, which might be somewhat surprising given its connection to Minecraft. However, upon reading about what Ludum Dare is and upon hearing that the next competition was starting the very next night, The Horseman did a quick check on his calender to make sure he wasn’t about to blow off any engagements and then declared his intention to enter the competition. It was high time to determine whether he could create a game from the ground up using Unity 3D and the 2D Toolkit in 48 hours. What follows is a summary of the experience.


(The tl;dr version : “Yes, The Horseman can do such a thing and the resulting entry is here under the name dr_soda. There also exists a post-competition build with some improved jumping controls, new levels, and new features that is playable at www.hug-monster.com.)

– Ideation –

When you have 48 hours to create a game you don’t have a lot of time to waste coming up with the perfect idea. Coming into the competition completely blind, I did not have any idea what the theme could be (and indeed nobody really knew what it would be until it was announced) so I did not prepare in any way for what might come. As it turns out the theme for this competition was simply Alone. That was my sole guidance for the direction of the resulting game. After about an hour spent thinking of ideas that were at best “maybe” in terms of fun and at worst “too ambitious” in terms of scope, I came across the idea of the player wishing to be left alone by a lovable, excitable, and adorable emoticon named “Hug Monster” and rendered as such : (-o^_^)-o. Considering this to be both the most interesting take on the theme, and also the most achievable concept in the remaining 47 hours, I sat down to refine the elevator pitch version of the game.

The Hug-Monster (-o^_^)-o can never get enough love or hugs, and is always happy to see you. Unfortunately, it’s a little too excitable and at times doesn’t seem to know its own strength.

You on the other hand are small and fragile, and most definitely want nothing more than to be left alone, especially from the big, scary Hug-monster!

How long can you avoid its warm, snuggly, and loving arms of death? Find out in this classic platformer!

– Artistry –

Since I wanted to keep the mood of the game upbeat in the face of the otherwise bleak theme of “Alone” I decided to make the graphics consist of cute emoticons that would be relatively easy to animate with 3 – 5 frame walk cycles. The Hugmonster flails its arms joyfully as it slides across the stage in perpetual persuit of the player. The player itself is merely a “letter” from the Wingdings font set, the skull and crossbones, rendered at 12px size such that it looks more like a little man than what it actually is. Both of these concepts took very little time to render once I’d settled on the proper font sets on which to base them. Once I had my sprite sheets, it was a quick trip into Unity3D and the 2DToolKit and I had (almost) all the sprite animations I would need. Later, once I decided that the levels needed more interactivity, I went back to Photoshop to create a set of switches, again using glyphs from the standard font set available with any Photoshop install.

– Development –

Being no stranger to side-scrolling mechanics from years of writing ActionScript for Flash games, and even a few little experiments on the subject in C# for Unity in the month prior, writing my own implementation of the walk/run mechanics was no large task. I decided that I would let Unity handle the physics for me this time, rather than write my own physics engine. I’d learned some valuable lessons on what works and what really doesn’t work when using Unity’s physics and felt confident that I could get what I wanted out of it. Rather than use Unity’s built-in CharacterController module, I chose to write my own Ambulator class with its own movement logic and use that for both the player and the Hug Monster. Partly this was because I’d forgotten that CharacterController exists, but also even if I’d remembered I may still have opted to create my own Ambulator simply because I wanted to minimize the amount of Unity-isms that I’d have to remember how to work with, and I already know very well how to write the kind of code I was aiming for without relying on Unity’s help to do it.

It turns out that this combination of decisions was simultaneously the best choice I could make and the worst choice. I liked (and still like) the simplicity of the Ambulator, and I feel it does exactly what it needs to with no overhead or extra API functionality to worry about. Then by letting Unity handle the physics of falling objects, there was a whole class of code I did not have to write in order to make the characters collide which saved valuable time. On the other hand, there are many idioms for working with the physics engine in Unity that aren’t always the most conducive to the traditional 2D platformer physics that players expect, and this expressed itself in how the character handles jumping face-first into a wall or obstruction. The difficulties can be worked around, and to a large degree I did manage to work around them (though not to the degree I wanted to by the end of the 48 hours), and after the end of the competition I have discovered yet more ways to work around them. I think this was possibly one of the most valuable technical lessons I took away from the experience of making a Ludum Dare game. If I were to do it again, I would probably choose to implement more of the physics on my own rather than to use the CharacterController component, but I think there’s a good case to be made for trying both approaches just to see where the limits are.

– Sound Design –

You’ll notice that there are no sounds or music. I’ll come out and say it, my history has not included much in the way of sound design. That isn’t to say I didn’t give it a shot, however. I followed the advice of fellow Ludum Dare entrants and traveled on over to BFXR to see if I could cobble together some nice sound effects, and maybe even the rudimentary beginnings of a music loop. After 3 hours of fiddling around with settings and sound generation I realized that I was getting nowhere. Nothing really sounded like I wanted it to and I was beginning to feel that I wouldn’t have the time to really test out every combination of sounds such that I would know how to achieve the effect I was after. This being the case, I chalk it up to a lesson learned even though it ultimately did not advance the state of the final build. I won’t make that mistake again. By the next Ludum Dare I will either know enough to make my own sounds to my satisfaction or I won’t even make the effort and save the time for design or programming. Speaking of design…

– Level Design –

A consequence of my decision to make a game in which a little person flees from the loving embrace of an oversized monster is that level design is critical in selling the idea, because what you are creating amounts to an action-puzzle game. As you might expect then, all the time that was not spent generating art, music, programming, or concepts, was spent designing levels. By the time the competition ended, I had created seven of them. They all had been tested to make sure they were beatable, but also that they could not be cheated. This took time… lots of it. Inherent in creating all these levels was also the playtesting of them all. Any time I wanted to add a switch, a door, move the goal, move a platform, I had to test the entire level from the beginning. As such the levels are short. What they lack in length though, they tend to make up for in difficulty. I’m still finding the appropriate balance here. I think I could have done a better job easing the player into the rules and logic of the game world rather than throw them to the wolves immediately.

– Flair –

You can’t have a game without a title screen or an ending, right? Well, this game had to have both. The most fun part about this was the the title screen and the ending movie both are programmatically animated using the same logic that the characters use in the game. They appear to be acting “intelligently” but in reality are simply doing nothing more than following the logical results of the input supplied as though they were doing their normal business. Astonishingly, I feel like this was possibly the most fun part of the process for me : taking the engine and assets I’d built for use in a game and re-purposing it all to make a set of little movies.

– In Conclusion –

The competition was easily one of the most fun and rewarding weekends The Horseman has spent in the past year. Creating a game under such tight constraints was exhilarating and the knowledge that there were hundreds of other people attempting the same thing was incredibly motivating. When taking breaks from the action, The Horseman would look back at the Ludum Dare blogs to see how other people were progressing, and take heart at the progress of others and admiration at their interpretations of the theme. Would he do it again? The Horseman says : “Verily.”

As well, he says : Play Hug Monster! (-o^_^)-o

]]>
http://www.scriptocalypse.com/?feed=rss2&p=106 6
Further extending the Unity 3D editor http://www.scriptocalypse.com/?p=103 http://www.scriptocalypse.com/?p=103#comments Fri, 21 Oct 2011 04:52:05 +0000 http://www.scriptocalypse.com/?p=103 In our last entry, The Horseman revealed to you an incantation to transmute Unity’s Editor itself. That entry merely skims the surface of what a practitioner of the arts may accomplish through Unity’s editor scripting capabilities. In today’s lesson, we build on top of the previous layers of sorcery such that we can overcome a pernicious problem with getters and setters in C# scripts. As before, project source for this tutorial is available.

Those of you who have spent even a small amount of time adding scripts to Unity’s GameObjects stand a fair chance of having encountered a magnificent property of the editor. A public instance variable declared as a member of a class will be exposed in the inspector for that game object, so if we were to give the PunyPlane a property called health, that property would be editable within the editor on an instance-level basis.

public float health = 1000;

Yes, I hear your questions even before you ask: “But Mr. Horseman, what about encapsulation? What if I want to hide health behind a getter / setter pair? It would be great if the PunyPlane could notify listeners of a change in health, or possibly even alter its own size such that it shrinks as its health decreases.”

Well, let’s try it out!

	protected float healthMax = 1000;
	protected float health = 1000;
 
	public float HealthMax{
		get{return healthMax;}
		set{healthMax = value;}
	}
 
	public float Health{
		get{return health;}
		set{
			health = value;
			ResizeBasedOnHealth();
		}
	}
 
 
	protected void ResizeBasedOnHealth(){
		// As health approaches 0, scale should approach 0.5, 
		// to make the object appear half its normal size
		// when health is depleted.
 
		float newScale = 0.5f;
 
		if(health > 0){
			newScale += (health / healthMax) * 0.5f;
		}
 
		gameObject.transform.localScale = new Vector3(newScale,newScale,newScale);
	}

Huh.

It appears that you can’t encapsulate a variable if you want it to be editable in the Unity Editor. Of course, looks can be deceiving and two can play at deception in this grand illusion. There are in fact several ways to get past this difficulty, and the one you choose depends on what’s most important for your purposes.

The most simple of these solutions is to set up your function to implement the PunyPlane.OnDrawGizmosSelected function, which is called approximately once every 10ms while an object is selected in the Editor.

 
// leave health exposed as public...
public float health = 1000;
 
void OnDrawGizmosSelected() {
     // and when in Editor mode, call ResizeBasedOnHealth on every update
     if(Application.isPlaying == false){
         ResizeBasedOnHealth();
     }
}

This simple solution allows GameObjects to call functions that act on the publicly exposed values in your game. Here, you can set the health of any PunyPlane in the editor and watch as its scale changes on the fly while you edit the Health field.

But Mr. Horseman, what if I want ResizeBasedOnHealth to be called at runtime whenever health is changed? This only works in the editor!

It is at this point that we dig a bit deeper, and uncover the Editor class. You will create a new C# script located in “Assets/Editor” and rename it as PunyPlaneEditor. We’ll start off with this code inside:

using UnityEngine;
using UnityEditor;
using System.Collections;
 
// Remember to declare the Type of editor this should be!
[CustomEditor (typeof(PunyPlane))]
public class PunyPlaneEditor : Editor {
 
	/* * 
	 * This function is called repeatedly as the Inspector GUI is refreshed.
	 * */	
	public override void OnInspectorGUI(){
 
		// Our "target" is the particular PunyPlane
		// instance that is currently selected, and
		// whose properties this inspector panel
		// reveals.
		PunyPlane pp = target as PunyPlane;
 
		GUILayout.Label("PunyPlane Custom Controls");
		pp.Health = EditorGUILayout.FloatField("Health",pp.Health);
 
	}	
 
}

Now, young seeker of arcane wisdom, behold what you should see :

Our custom Editor script has usurped control over Unity’s default implementation and displays for us a field containing a floating point value that we have labeled “Health”, which gets and sets from PunyPlane.Health, the getter / setter pair. The drawback to this method is that it takes work to make your custom inspector layouts look aesthetically pleasing, and if you have a large number of editable fields this can become an onerous task. This should only be undertaken in the event that you have a side effect that must be triggered both at runtime and in the editor, and you don’t want to incur the overhead of performing the operation in the normal void Update() method belonging to all MonoBehaviour objects. The other limitation of the OnInspectorGUI method is that Screen.width and Screen.height will return the pixel dimensions of the inspector panel, not the game screen or the scene. If you need the pixel dimensions of the Scene editor, you can instead perform those actions in Editor.OnSceneGUI() and also from within the OnShowGizmosSelected handler. On the other hand, if you need the precise pixel dimensions of the Game window those are not available at all from within the editor scripts… but there is a way yet to reach them, in the event that you need those dimensions at runtime and you cannot, or do not wish to hard code them. I’ll save that bit of prestidigitation for another time.

There are yet other ways to interact with and change the Editor’s behavior. Virtually anything you see happen in the editor can be harnessed for your own purposes.

Download the source for this tutorial.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=103 1
Extending the Unity 3D Editor http://www.scriptocalypse.com/?p=102 http://www.scriptocalypse.com/?p=102#comments Thu, 20 Oct 2011 05:41:48 +0000 http://www.scriptocalypse.com/?p=102 The Horseman has found that one of the most interesting aspects of Unity 3D is that one is able to extend the authoring tool, such that one can add new functionality, menus, and behaviors to optimize workflow.

Those of you who remember a certain entry about using JSFL to automate build processes in the Flash environment may already have an idea of what I’m talking about, but extending the Unity editor is actually much easier because the same code used to write and script object behavior at runtime in the player can also be used inside the editor itself. This would be as though you were able to write extentions for the Flash authoring tool using ActionScript 3, instead of JSFL. That would be simply huge.

Fortunately, getting started with extending the Unity Editor is relatively straightforward, but unfortunately there is scant documentation on what is possible, and the samples on Unity’s website currently feature only Unity’s JavaScript and not C#. Fortunately for you, the Horseman can shed at least a little light on the subject, so follow along with this tutorial. For those who want the final source project right away, you can download the source here. I am currently using Version 3.3.0f4 of Unity on Windows, and have also tested this on Mac OSX.

First, open the Unity editor and in your “Project” panel create the following folder structure:

 
- Assets
  + Editor
 
- Scenes
 
- Scripts

Create a folder called Assets, with a subfolder called Editor. This is where our editor scripts must live in order for Unity to use them. Scenes is where we will save our Unity Scene, and Scripts is where we will keep our GameObject classes.

First, we need to create our Scene. Simply select File -> Save Scene As… and save the current scene with the name “MyScene”. You will now see “MyScene” in the project panel, so move it into the Scenes folder now.

Next, we’re going to start by creating a GameObject script. For the sake of argument, let’s say we want to write a C# script that, when called, will instantiate a GameObject that represents a simple four-vertex plane. We’ll call it “PunyPlane” for now, so in your “Scripts” folder, right-click and choose Create -> C Sharp Script. Rename this script to be named “PunyPlane”, then replace the code inside with the following, and save:

 
/* *
 * 
 *  This class creates a small, 4 vertex plane.  
 *  It's provided purely for instructional purposes,
 *  as an example of how one can instantiate custom 
 *  GameObjects with graphical representations.
 * 
 *  It is not necessary to understand how this code
 *  works, but feel free to study it if you wish
 *  to get a small taste of how polygons and planes
 *  are created procedurally in Unity.
 * 
 * */
 
 
 
using UnityEngine;
using System.Collections;
 
public class PunyPlane : MonoBehaviour {
 
	public static Material sharedMaterial;
 
	/* *
	 * Call Create without parameters to return a PunyPlane of 1 x 1 world units.
	 * */
	public static PunyPlane Create(){
		return Create(1.0f,1.0f);
	}
 
 
	/* *
	 * Call Create with a height and width expressed in world units.
	 * */
	public static PunyPlane Create(float width, float height){
 
		/* *
		 * We start by creating a GameObject to represent our plane,
		 * giving it the requisite components in order to accomplish
		 * this goal, a <MeshFilter> and a <MeshRenderer>.
		 * */
		GameObject go = new GameObject();
		go.name = "PunyPlane";
		MeshFilter mf = go.AddComponent<MeshFilter>();
		MeshRenderer mr = go.AddComponent<MeshRenderer>();
 
		/* *
		 * Now it's time to create our PunyPlane component.  
		 * */
		PunyPlane pp;		
		pp = go.AddComponent<PunyPlane>() as PunyPlane;
 
		if(mf.sharedMesh == null){
			mf.sharedMesh = new Mesh();
		}
 
		Mesh mesh = mf.sharedMesh;
 
 
		/*	
			Here is a diagram of our plane,
			with the verts labeled. 
		 0    3
		  ----
		  | /|
		  |/ |
		  ---- 
		 1    2		 
 
		 */
 
		Vector3 p0 = new Vector3(-width * 0.5f, -height * 0.5f,0);
		Vector3 p1 = new Vector3(-width * 0.5f, height * 0.5f,0);
		Vector3 p2 = new Vector3(width * 0.5f, height * 0.5f,0);
		Vector3 p3 = new Vector3(width * 0.5f, -height * 0.5f,0);
 
		/* *
		 * Make sure the Mesh is cleared of all old data, then 
		 * apply the new verts and triangles in order to form
		 * a square plane.
		 * */
		mesh.Clear();
		mesh.vertices = new Vector3[]{p0,p1,p2,p3};
		mesh.triangles = new int[]{
			0,1,3,
			3,1,2			
		};
 
		/* *
		 * And we'll want to set up the uv coordinates to match
		 * the verts listed above.  This is so the plane can wear
		 * a texture without it appearing mangled, flipped, or 
		 * inverted.
		 * */
		mesh.uv = new Vector2[]{
			new Vector2(0,0),
			new Vector2(0,1),
			new Vector2(1,1),
			new Vector2(1,0)
		};
		mesh.RecalculateNormals();
		mesh.RecalculateBounds();
		mesh.Optimize();
 
 
		/* *
		 * Using "Unlit/Texture" because of the assumption that 
		 * this will be a flat, 2D sprite and will not need to 
		 * be affected by things like lighting.  This will make
		 * the plane render more efficiently.
		 * */
		if(sharedMaterial == null)sharedMaterial = new Material(Shader.Find("Unlit/Texture"));
		mr.sharedMaterial = sharedMaterial;
		mr.sharedMaterial.shader = Shader.Find("Unlit/Texture");
 
		return pp;
	}
 
 
}

The above script allows us to dynamically generate a plane in 3D space by calling PunyPlane.Create(), for a 1×1 plane, or PunyPlane.Create(width,height) for a variable sized plane. Note that this code does not correct for negative width / height values.

To test this code, let’s give it somewhere to run. We’re going to create a “GameManager” object in our heirarchy, that will contain a “GameManager.cs” component that kicks off and runs our game logic. In this case, it won’t be very exciting logic. It will merely instantiate some of our PunyPlane objects. Go to the toolbar and select GameObject -> Create Empty. This will create a new, empty GameObject in your Heirarchy. Rename this GameObject as “GameManager”. You’ll also create another empty GameObject, and rename it as “World.”

Next, right-click your Scripts folder, and create a new C# script. Rename it as “GameManager”. Next, select the GameManager object in your heirarchy, and then drag the GameManager script over to the “Inspector” panel for the GameManager object (The “Inspector” is the panel where you can set the object’s Transform positions in world space.)

Now, we’re going to open the GameManager.cs script file and write the following code:

/* *
 * 
 * The GameManager kicks off all of our game logic.  In this case, there isn't much logic.
 * We simply instantiate a few PunyPlane objects and place them in the heirarchy.
 * Assuming that this code has been added as a component to one of the GameObjects in the
 * Heirarchy, this should take effect when you press "Play" or when you view the compiled
 * application in the Unity player.
 * 
 * */
 
using UnityEngine;
using System.Collections;
 
public class GameManager : MonoBehaviour {
 
 
 
	void Start () {
 
 
 
		// This creates a PunyPlane instance that lives on the 
		// top level of the heirarchy.
		PunyPlane punyPlane = PunyPlane.Create();
 
		// Let's add a 0 to this instance's name 
		// in order to differentiate it from its kin.
		punyPlane.name = punyPlane.name + "0";
 
 
		// Now let's make a new PunyPlane, giving it
		// an uneven rectangular shape, and give it
		// a distinctive name.
		punyPlane = PunyPlane.Create(3.0f, 0.5f);
		punyPlane.name = punyPlane.name + "1";		
 
		// Add the new PunyPlane to the World.  This removes it
		// from the top level of the heirarchy.  First, find the 
		// "World", then add the plane's transform as a child
		// to the world's transform.
		GameObject world = GameObject.Find("World");
		punyPlane.gameObject.transform.parent = world.transform;
 
 
		// Finally, we offset this new PunyPlane
		// just a bit, so we can see them both on the screen.
		punyPlane.transform.position = new Vector3(0,1.5f,0);
 
 
	}
 
 
}

Now save the script file. All this Manager script does is instantiate two PunyPlane object in our game, dynamically at runtime. Press the Play button to preview the game. If you have performed the steps correctly, you should see two planes appear in the Game window. Once you stop the game, these planes will disappear, as they only exist at runtime.

I already know what you’re thinking. But Mr. Horseman! What does any of this have to do with extending the Unity editor? All we’re doing is creating planes at runtime!

Little do you realize dear reader, that is in fact the magic of what we’re about to do next! It’s nice to be able to generate dynamic planes at runtime, but wouldn’t it be even nicer if we could just treat this plane like a Unity primitive and instantiate it inside the Editor instead of just in the player at runtime? That way we don’t have to rely on the bloated 121 vert / 200 triangle plane that Unity supplies as a primitive. Well, get ready to blow your own mind. Inside the “Assets/Editor” folder (specifically inside Editor), right-click and create a new C# file. Rename it as “CustomToolBar”, then open the file in your text editor and replace it with the following code, then save:

/* *
 * CustomToolBar is used to add some new functionality to the Unity3D Editor.  
 * In this case we're going to add some menu items to the top level toolbar.
 * */
 
using UnityEngine;
using UnityEditor;
using System.Collections;
 
public class CustomToolbar : MonoBehaviour {
 
 
 
 
	/* *
	 * 
	 * The following two methods are added to the Unity default toolbar,
	 * as sub-menus under the GameObject dropdown.  It should appear at 
	 * the very bottom of the GameObject dropdown list.
	 * 
	 * GameObject ->
	 * 		Primitives (We made this one) ->
	 * 			Create XXX
	 * 
	 * */
	[MenuItem ("GameObject/Primitives/Create PunyPlane in Heirarchy")]
	public static void MakePunyPlane(){
 
		// This function simply creates a PunyPlane in the top level of the
		// Heirarchy.
		PunyPlane.Create();
 
	}
 
	[MenuItem ("GameObject/Primitives/Create PunyPlane As Child of Selection")]
	public static void MakePunyPlaneAsChildOfSelection(){
 
		// We start by creating a PunyPlane in the top level of the 
		// Heirarchy.
		PunyPlane pp = PunyPlane.Create();
 
		// And if we've got a GameObject currently selected in the 
		// heirarchy, we'll reparent the PunyPlane to our selected
		// object.
		if(Selection.activeGameObject){
			pp.gameObject.transform.parent = Selection.activeGameObject.transform;
		}
 
	}
 
 
	/* *
	 * And finally, we create a brand new menu item in the Unity editor.
	 * This will actually appear as a new top-level item called "Scriptocalypse"
	 * with a command "Say Hello".  The "Scriptocalypse" item should appear 
	 * between "Terrain" and "Window".
	 * 
	 *   Scriptocalypse ->
	 * 		Say Hello
	 * 
	 * */
	[MenuItem ("Scriptocalypse/Say Hello")]
	public static void SayHello(){
		Debug.Log("Hello from the Unity3D toolbar.");	
	}
 
 
 
 
}

As a reference, your project’s file and asset structure should look like this:

Assuming there are no errors in any of the above scripts, when you click back onto the Unity Editor you should immediately notice that the toolbar at the top has a new entry between “Terrain” and “Window” that was never there before. It should be called “Scriptocalypse”, and inside is a menu with a single option, “Say Hello”. Clicking this option sends a message to the Debugger, as you can see.

But Mr. Horseman, what about those functions that let you create planes in the editor? Where are they?

Aaah, notice in the code sample above that we have some braces that contain some interesting code? Look at the very first function and its brace block:

[MenuItem (“GameObject/Primitives/Create PunyPlane in Heirarchy”)]

That string represents the path to the menu item we’ve created, so as you can see we’ve simply added a new option to the pre-existing GameObject menu item. At the bottom, you should find “Primitives”, which has two functions. The first of them simply adds a new PunyPlane to the Heirarchy. The second will go a step further, and add the PunyPlane to whichever game object is currently selected in the Heirarchy. Go ahead, and try them out.

Do you see the magic here? The same code we use to create and manipulate behaviors at runtime is also the code we use to instantiate scripts in the editor! Such sorcery is simply not known in the lands of Flash, which makes it all the more exciting to actually see in action here.

You’ll notice that the PunyPlane instances we create actually have the PunyPlane component attached to the GameObject. This is by design. We currently have no special behaviors or public properties attached to the PunyPlane component, but we may soon in another posting. We’ll find that public properties are exposed in the inspector, and can be set both at runtime and in the editor… but what about public getter/setter pairs? Aaaah, in C# those are not exposable in the inspector… at least not without a bit of trickery! The Horseman will leave you pondering just what manner of trickery until then, but suffice it to say there are a few ways.

In the meantime, Download the Unity project and source files for this tutorial if you need any assistance.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=102 6
Mommy, where do framescripts come from? http://www.scriptocalypse.com/?p=101 http://www.scriptocalypse.com/?p=101#comments Thu, 28 Apr 2011 00:22:28 +0000 http://www.scriptocalypse.com/?p=101 When writing ActionScript you have your choice of using external class files or attaching code to a timeline by simply typing it into the .fla code editor window. I’m going to ask you to follow four simple steps and observe the results.

  1. Create a new .fla in Flash, set to use AS3
  2. On frame 1, type gotoAndStop(3);
  3. On frame 2, type trace(“I’m a script on frame 2”);
  4. On frame 3, type this[“frame2”]();

This should result in your trace window showing “I am a script on frame 2”.

“No way, Mr. Horseman! How could this have happened? The playhead never touched frame 2!” I hear your cries of astonishment even from here. Indeed, how did this happen? Let’s stop to think for a minute about what happens when Flash actually compiles a swf. The first thing to remember is that in a published swf frame scripts do not exist. In a previous entry I talked briefly about what the compiler does with instances on the stage. Note the following line of code from that old entry:

public var foo_mc:NewMovieClip0; // Where did this come from?????

Something similar happens every time you use the Flash Authoring Tool to write a framescript. There is an undocumented (but by now very well known) function of the MovieClip class called addFrameScript, which allows you to attach “frame scripts” at runtime to a MovieClip or any class derived from MovieClip. Indeed one thing you’ll find is that if you try to subclass Sprite and link that to a library symbol with frame scripts, you’ll recieve an error to the effect that Sprite does not have a function called addFrameScript. This should tell you that internally Flash uses this function to give the illusion that scripts you write in the Flash editor just “exist” as part of the movieclip. If we decompile the swf we just created, we will see exactly that.

package DecompileMe_fla
{
    import flash.display.*;
 
    dynamic public class MainTimeline extends MovieClip
    {
 
        public function MainTimeline()
        {
            addFrameScript(0, frame1, 1, frame2, 2, frame3);
            return;
        }// end function
 
        function frame3()
        {
            var _loc_1:String;
            _loc_1.this["frame2"]();
            return;
        }// end function
 
        function frame1()
        {
            gotoAndStop(3);
            return;
        }// end function
 
        function frame2()
        {
            trace("I am a script on frame 2");
            return;
        }// end function
 
    }
}

When Flash is required to attach frame scripts to a class (regardless of whether you explicitly created the class, or whether you are implicitly creating one simply by nature of the fact that you’ve attached a framescript to a movieclip in the editor) it adds (implicitly) public functions to that class named after the frame on which the code appears, and then uses addFrameScript in the constructor to add those frames at runtime. Since these functions are just public and freely accessable, the fact that the “playhead” never even needs to “touch” a frame in order for the frame’s scripts to be called should be quite obvious.

“You’re making my head hurt, Horseman! I implore you, cease this haunting with accursed visions from beyond the abyss!”

Piercing the veil of abstraction is always a perception-altering experience. You can expect to feel a slight discomfort, but more than that you should feel a distinct thrill about uncovering another of the world’s great mysteries.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=101 2
Reports from the field – Alien Apartment demo on more devices http://www.scriptocalypse.com/?p=99 http://www.scriptocalypse.com/?p=99#comments Wed, 13 Apr 2011 08:36:32 +0000 http://www.scriptocalypse.com/?p=99 On the 12th of April, I gave a very short presentation of my Alien Apartment demo (apk) to a local Android Developer meetup group.

One of the attendees was so kind as to grab the apk that very night and show me how it runs on some other devices. He demoed it running on the Samsung Galaxy Tab, and the Motorola Xoom. The excellent news is that the UI repositions as I’d expected. This was possibly the thing that worried me most, and I was gratified to see it went according to plan. The even better news is that the Galaxy Tab ran the demo so very incredibly smoothly. The animations were smooth as butter, and the controls were very responsive. The framerate felt almost as nice as the web player version. Furthermore, the larger screen size made the whole control scheme feel very nice and open. On my phone it can feel a little cramped, but not so on the larger screen. Performance on the Xoom seemed subjectively to be about 2/3 that of the Galaxy Tab, which is surprising given its raw statistics.

I’d like to thank Mike for letting me see the demo running on another device in-person, and if anyone else (whether you attended the meetup or not) has anything to report on how the demo runs on a device, please let me know.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=99 1
Alien Apartment Update http://www.scriptocalypse.com/?p=98 http://www.scriptocalypse.com/?p=98#comments Mon, 11 Apr 2011 03:20:01 +0000 http://www.scriptocalypse.com/?p=98 This is possibly the last chance I’ll have to work on the Unity 3D demo for a while, so I decided I’d make this update a good one. Here is the web playable version and here is the apk. You’ll notice a few things different between the web playable version and the APK even though they are compiled from the same source. Not all these differences are intentional. Here’s a breakdown of the differences you’l see:

  • Intentional: The apk has onscreen controls for the character
  • Unintentional: The web version shows both a health meter and a rage meter. The apk only shows health
  • Unintentional: The robot enemies in the courtyard have a solid purple helmet in the apk. In the web version you can see that the helmets are clear glass.
  • Unintentional: The player’s character in the web version has a different jump height outdoors than indoors. This was the intended effect. In the apk, the player’s jump height is locked to the very first value known. Since you start in the apartment, the jump height will be very small.

I suspect that the rage meter problem has something to do with the fact that the health / rage meters make use of the native GUI elements (which means that under the hood they’re using OnGUI, which is a shame). As of now I can’t quite explain why the robot’s helmet has lost its texture in the apk. The texture existed until Unity crashed on me and I had to restart it. After the crash, the helmet texture disappeared from the apk and the preview editor. As you can see though, it continues to exist in the web player.

As I mentioned in my previous post, there were a number of code optimizations I implemented, which gained me about 5fps on-average. If I had to take a stab at what causes most of the slowdowns it would have to be that these particular scenes are somewhat heavy in terms of mesh construction and lighting. It’s no problem at all for a desktop (at least a Windows desktop) or a modern laptop, but mobile requires a lighter touch with its models. It doesn’t help that the cameras render a great deal of the field as well.

For more information on using Unity for mobile devices, check out this presentation which shows some additional best practices as well as a particularly impressive example of how an intelligent approach to laying out a scene allows you to squeeze maximum performance out of a Unity mobile project. Do not miss the part of the video where the representative of Crecent Moon Games presents Aralon: Sword and Shadow, which showcases the incredible potential of Unity.

As for myself, I’m suitably impressed by the Unity tool. It renders the code aspect quite easy to work with, as you can program at a much higher level of abstraction than using OpenGL directly, and while the drag-and-drop relationships of the code with the on-screen assets can seem muddy if you come from a strict OOP background it’s possible to create a well-designed structure regardless. The biggest hurdle with Unity, and the one that there is no truly easy solution for, is that 3D assets such as models, animations, and textures are incredibly labor intensive to create. It’s a much bigger field with many more areas of specialization than 2D art. You may or may not have noticed, but almost all the art assets from this project are either from Unity’s own site or otherwise royalty-free. The time investment for 3D assets is the biggest reason why. This example, which constitutes my first forray into simply learning my way around the Unity tool took approximately three weeks of my time, where the only art assets I generated were the A/B buttons in the APK and the titlescreen. Were I to create my own 3D assets, this demo would not even exist in the span of three weeks.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=98 3
Unity 3D Code optimization tips http://www.scriptocalypse.com/?p=96 http://www.scriptocalypse.com/?p=96#comments Sun, 10 Apr 2011 23:23:58 +0000 http://www.scriptocalypse.com/?p=96 I’ve been holding off on attempting to write more optimized code in Unity 3D until I have a basic grasp on putting a project together, but I’ve had a nagging suspicion that there’s plenty of poorly optimized code floating around in the examples I’ve learned from.

Fortunately, many of the lessons learned from optimizing ActionScript 3 apply just as well to Unity. If you’re a regular reader here you’ve likely heard me harp on similar topics in the Flash world. Here are some of the most important things I’ve uncovered over the course of the day:

  • You should cache references to components whenever possible. Never call GameObject.Find() or gameObject.GetComponent() inside of an Update() method. These are very slow methods that get slower as the number of objects in your scene grows. Grab all the references you need in Start(), or add to them dynamically as you need them. This is one of the most frequently abused and broken rules in the Unity demo code, and stripping it out gave me an extra precious 5fps on my Android device.
  • The native OnGUI method may be a very convenient way to lay out a gui, but during gameplay should be avoided like the plague. It’s fine for static title screens, or scenes with little action, but even an empty OnGUI call is a nightmare for your framerate. For a detailed overview, check this link.
  • Provoking a garbage collection cycle is a kiss of death for your framerate. Try never to instantiate inside of an Update() method. Create as much as you can upfront and recycle what is practical. Object pools, and cached instances once again come to the rescue here.
]]>
http://www.scriptocalypse.com/?feed=rss2&p=96 1
Alien Apartment Demo updates http://www.scriptocalypse.com/?p=97 http://www.scriptocalypse.com/?p=97#respond Sun, 10 Apr 2011 00:56:12 +0000 http://www.scriptocalypse.com/?p=97 I’ve had quite a busy week digging deeper into Unity 3D. As such there’s a newly updated version available here (as a web player) and here as an APK that you can install on your Android device. The updated version of the web player may not look very different apart from the inclusion of a title screen and some extra GUI text at the top, but it will definitely sound different. The outside scene is a new model set, but aside from wandering about there’s nothing to do other than admire the scenery.

The real point of differentiation here is that the same codebase that compiled the web player also compiled the APK, and the APK has an onscreen gui control system that is completely absent on the web player. Yes, the Android version has a joystick, and A/B buttons onscreen.

So given what you see in this update, you might wonder where the time has gone in this. I’ll try to break it down as best I can:

~60% of my time has been devoted to learning the various ways to make and use GUIs
~20% of my time has been spent converting unsuitable JS code into C#
~20% of my time was everything else, including working with music and sound, experimenting with different ways to access and work with data in Unity’s ecosystem, and tweaking the control scheme from one that works well only on keyboards to one that is good both on a keyboard and on a touchscreen.

Why did the GUI explorations take up so much time, you might wonder? The main reason is because laying out a 2D GUI display using a tool that is geared exclusively for 3D content presents more challenges than you might first expect. There are several built-in solutions that may or may not satisfy your needs, depending on what they are. There are solutions kindly provided by the Unity community as a whole that also may or may not meet your needs precisely. There are also plugins and extensions to choose from such as EZ GUI. So which do you choose? And why? It’s a large topic. Here are just a few of the questions you have to ask yourself:

  • Will one of the standard tools be “good enough” here or do I need special functionality?
  • What’s the “safe zone?” in terms of screen resolution? Can I arrange my GUI elements to occupy only that space?
  • Should my GUI elements dynamically “float” to the sides of the screen if the resolution allows for it?
  • Are there special performance considerations? Will the OnGUI native methods be too costly and inflexible?

Ultimately, I think my current solution could be better. I’m not accounting for screen width on my mobile version just yet, and personally don’t have a tablet on which to test at the moment. I suspect that the A and B buttons will not be positioned correctly on devices with wildly different pixel densities than my own, and the title screen will likely be too small on a tablet. As I said, currently no attempt is made to correct for screen resolutions. This is one thing I hope to account for soon.

At this point I’d like to implement some pickups and perhaps an enemy or two as well.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=97 0
Unity 3D — Primitive Demo http://www.scriptocalypse.com/?p=95 http://www.scriptocalypse.com/?p=95#respond Wed, 06 Apr 2011 03:31:28 +0000 http://www.scriptocalypse.com/?p=95 I’ve decided to post my primitive demo of Unity 3D. There are a number of concepts at work here, and yet a few other snags that I hit along the way. You can view the demo here.

A few things had me tearing my hair out.

  • The alien could leave his house by walking towards the camera in the foyer. You cannot see the door, but the alien starts with his back turned to it. He could come back inside by approaching the front door, again behind him. If you wrecked the apartment before you left, then came back, the apartment stayed wrecked. (This is the desired behavior! So far, so good.)
  • The camera script that I used originally only accounted for one camera that followed the alien around. This wasn’t very user friendly in the small apartment. I wanted to have a more Resident Evil feel to the camera positioning and so I set up many different perspectives and used various invisible primitives as camera triggers.
  • After adding the multiple cameras, entering and leaving the house went completely to hell in a handbasket!

So what caused the problem with entering and leaving the apartment? It turns out that if more than one camera is “active” at a time, that really bizarre things can happen. Unity will apparently spend a great deal of time and energy trying to render a scene from many different perspectives that it doesn’t need to. This problem was masked when the application started up because I was careful to turn off the redundant cameras at the time. The problem was that when you came back into the apartment all the cameras “restored” and were all on by default. This caused all manner of problems. It completely hosed Chrome, and the .apk on my Droid phone would simply exhibit incredibly bizzare behavior such as the alien constantly flapping his arms. Once I got that problem taken care of, things worked as normal once again.

I hope soon to have an on-screen UI controller so that the app can be played on phones that don’t have a physical keyboard. That said, phones that do have a physical keyboard can play it just as it is.

]]>
http://www.scriptocalypse.com/?feed=rss2&p=95 0