Fun games at PAX

This weekend, my brother and I were at PAX East demoing Soda Drinker Pro (the worlds most advanced soda drinking simulator). Working the booth at an event like this is super fun, and you get to meet a lot of great people, but it’s tough to move around and try out some of the other games at the expo. Here are a few of them that i tried and liked:

Ember Strike: The Battle for Willow Lane

At first, this one looked like a basic match-3 game, but when I tried it out, I realized there was more to it than that. The basic mechanics are match-3, but it plays more like Puzzle Fighter, which is super fun. You can play it for free on Kongregate, and I recommend you try it out.

Echoes of Eridu

These guys were across from us at the Soda Drinker Pro booth, and I really enjoyed their game too. Their pitch is basically rogue-like multiplayer mega-man, which is a pretty sweet concept. It’s on kickstarter and steam greenlight now, so you should give it an upvote.

Trisector

This is one that I saw while having some drinks with some devs at an afterparty on Friday. It’s a side-scrolling space shootemup similar to Gladius, but it has destructible terrain, and has lots of explosions. It’s also one of the few indie games I saw that used a home-grown game engine. Really impressive.

Aerena – Clash of Champions

This is a turn-based strategy game where you can pit different characters against each other to destroy each other’s ships. I didn’t get to play too long, but it looked like it had some pretty good potential.

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg

Global game jam 2014 – Unity webcam part 2

Last post, I went over how to get data from the webcam and display it on a texture.

Now I’ll go over how I used some color utilities I found online to shift the color from the webcam around the color wheel. In order to move a color around the color wheel, I needed to convert the color from RGB (Red, green, blue) to HSB (Hue, saturation, brightness). I can’t remember where I found this, but below is a C# version of HSBColor that I had originally found in javascript:

public struct HSBColor
{
	public float h;
	public float s;
	public float b;
	public float a;
	
	public HSBColor(float h, float s, float b, float a)
	{
		this.h = h;
		this.s = s;
		this.b = b;
		this.a = a;
	}
	
	public HSBColor(float h, float s, float b)
	{
		this.h = h;
		this.s = s;
		this.b = b;
		this.a = 1f;
	}
	
	public HSBColor(Color col)
	{
		HSBColor temp = FromColor(col);
		h = temp.h;
		s = temp.s;
		b = temp.b;
		a = temp.a;
	}
	
	public static HSBColor FromColor(Color color)
	{
		HSBColor ret = new HSBColor(0f, 0f, 0f, color.a);
		
		float r = color.r;
		float g = color.g;
		float b = color.b;
		
		float max = Mathf.Max(r, Mathf.Max(g, b));
		
		if (max <= 0)
		{
			return ret;
		}
		
		float min = Mathf.Min(r, Mathf.Min(g, b));
		float dif = max - min;
		
		if (max > min)
		{
			if (g == max)
			{
				ret.h = (b - r) / dif * 60f + 120f;
			}
			else if (b == max)
			{
				ret.h = (r - g) / dif * 60f + 240f;
			}
			else if (b > g)
			{
				ret.h = (g - b) / dif * 60f + 360f;
			}
			else
			{
				ret.h = (g - b) / dif * 60f;
			}
			if (ret.h < 0)
			{
				ret.h = ret.h + 360f;
			}
		}
		else
		{
			ret.h = 0;
		}
		
		ret.h *= 1f / 360f;
		ret.s = (dif / max) * 1f;
		ret.b = max;
		
		return ret;
	}
	
	public static Color ToColor(HSBColor hsbColor)
	{
		float r = hsbColor.b;
		float g = hsbColor.b;
		float b = hsbColor.b;
		if (hsbColor.s != 0)
		{
			float max = hsbColor.b;
			float dif = hsbColor.b * hsbColor.s;
			float min = hsbColor.b - dif;
			
			float h = hsbColor.h * 360f;
			
			if (h < 60f)
			{
				r = max;
				g = h * dif / 60f + min;
				b = min;
			}
			else if (h < 120f)
			{
				r = -(h - 120f) * dif / 60f + min;
				g = max;
				b = min;
			}
			else if (h < 180f)
			{
				r = min;
				g = max;
				b = (h - 120f) * dif / 60f + min;
			}
			else if (h < 240f)
			{
				r = min;
				g = -(h - 240f) * dif / 60f + min;
				b = max;
			}
			else if (h < 300f)
			{
				r = (h - 240f) * dif / 60f + min;
				g = min;
				b = max;
			}
			else if (h <= 360f)
			{
				r = max;
				g = min;
				b = -(h - 360f) * dif / 60 + min;
			}
			else
			{
				r = 0;
				g = 0;
				b = 0;
			}
		}
		
		return new Color(Mathf.Clamp01(r),Mathf.Clamp01(g),Mathf.Clamp01(b),hsbColor.a);
	}
	
	public Color ToColor()
	{
		return ToColor(this);
	}
	
	public override string ToString()
	{
		return "H:" + h + " S:" + s + " B:" + b;
	}
	
	public static HSBColor Lerp(HSBColor a, HSBColor b, float t)
	{
		float h,s;
		
		//check special case black (color.b==0): interpolate neither hue nor saturation!
		//check special case grey (color.s==0): don't interpolate hue!
		if(a.b==0){
			h=b.h;
			s=b.s;
		}else if(b.b==0){
			h=a.h;
			s=a.s;
		}else{
			if(a.s==0){
				h=b.h;
			}else if(b.s==0){
				h=a.h;
			}else{
				// works around bug with LerpAngle
				float angle = Mathf.LerpAngle(a.h * 360f, b.h * 360f, t);
				while (angle < 0f)
					angle += 360f;
				while (angle > 360f)
					angle -= 360f;
				h=angle/360f;
			}
			s=Mathf.Lerp(a.s,b.s,t);
		}
		return new HSBColor(h, s, Mathf.Lerp(a.b, b.b, t), Mathf.Lerp(a.a, b.a, t));
	}
	

}

The other half of this is a set of color utilities that I found. It’s just a set of static methods which allow you to shift a color around the color wheel by a certain percentage:

public class ColorUtils {

	public static Color GetComplimentaryColor(Color rgb) {
		return GetShiftedColor (rgb, .5f);
	}

	public static Color GetShiftedColor(Color rgb, float shift){
		var hsbColor = new HSBColor (rgb);
		
		var shiftedHue = HueShift (hsbColor.h, shift);
		hsbColor.h = shiftedHue;

		return hsbColor.ToColor ();
	}

	public static Color SetValues(Color color, float? saturation, float? brightness){
		var c = color;
		if (saturation.HasValue) {
			c = SetSaturation(c, saturation.Value);
		}
		if (brightness.HasValue) {
			c = SetBrightness(c, brightness.Value);
		}
		return c;
	}

	public static Color SetSaturation(Color color, float saturation){

		var hsb = new HSBColor (color);
		hsb.s = saturation;
		return hsb.ToColor ();
	}

	public static Color SetBrightness(Color color, float brightness){
		
		var hsb = new HSBColor (color);
		hsb.b = brightness;
		return hsb.ToColor ();
	}


	static float HueShift(float h, float shiftAmount) 
	{ 
		h+=shiftAmount; 
		while (h>=360.0f) h-=360.0f; 
		while (h<0.0f) h+=360.0f; 
		return h; 
	}

}

The last part is a custom playmaker FSM action. The webcam color is set to a playmaker variable earlier in the FSM, but this script basically applies the webcam color, as well as any complimentary colors to any object in the scene which has a particular tag. The object must have particular materials attached to it called “Color1″, “Color2″, and “Color3″.

[ActionCategory("Custom")]
	public class SetColorsAction : FsmStateAction {

		[RequiredField]
		[UIHint(UIHint.Variable)]
		public FsmColor colorVariable;

		private GameObject[] _objectsToSet;

		public FsmFloat saturation;
		public FsmFloat brightness;

		[Tooltip("Repeat every frame.")]
		public bool everyFrame;


		public override void Reset()
		{
			_objectsToSet = GameObject.FindGameObjectsWithTag ("DynamicMaterials");
			base.Reset();
			colorVariable = new FsmColor{UseVariable=true};
			saturation = .3f;
			brightness = .5f;
		}
		
		public override void OnEnter()
		{
			DoSetColors ();
			if (!everyFrame) {
				Debug.Log ("test");
				
				Finish();
			}
		}

		public override void OnUpdate(){
			DoSetColors ();
		}

		public void DoSetColors(){
			foreach(var go in _objectsToSet){
				if(go.renderer.isVisible){
					foreach (var m in go.renderer.materials) {
						
						if(m.name.Contains("Color1")){
							var originalColor = m.GetColor("_Color");
							var c = ColorUtils.SetValues(colorVariable.Value, saturation.Value, brightness.Value);
							
							
						}
						
						if(m.name.Contains("Color2")){
							var c = ColorUtils.GetShiftedColor(colorVariable.Value, .33f);
							c = ColorUtils.SetValues(c, saturation.Value, brightness.Value);
							m.SetColor("_Color", c);
							
						}
						
						if(m.name.Contains("Color3")){
							var c = ColorUtils.GetShiftedColor(colorVariable.Value, .66f);
							c = ColorUtils.SetValues(c, saturation.Value, brightness.Value);
							m.SetColor("_Colour", c);
							
						}
					}
				}

			}

		}
	}

The Game Jam was a great experience, and while I’m not sure using a webcam to paint objects is really viable for a game, I ended up learning a lot in the process. Let me know in the comments if you have any questions, or any good ideas for how this sort of thing could be used in a game!

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg

Global game jam 2014 – Unity WebCam

Last weekend, my brother Will and I participated in the 2014 global game jam at the MIT location in Boston. I had a great time and met a lot of awesome people. It was amazing seeing what some of the teams were able to come up with in 48 hours. You can see the final presentations from the teams here:

http://www.twitch.tv/mitgamelab/b/498481144

(Will and I are on at the 35 minute mark.)

The theme of the Game Jam was “We don’t see things as they are, we see them as we are”, so we decided to take that very literally, and made a game called “Find yourself inside yourself”, where you have to navigate a trippy maze trying to find yourself. The game heavily relied on the webcam, which was used to dynamically set colors for the in-game scenery, as well as determine the behavior for the monsters in the game. Here’s how it worked:

Here’s the start method of the behavior which was placed on an empty game object in the scene:

void Start () {
 CamColors = new List<Color> ();
//load the webcamtexture, and stop it if it's already running
 _webcamTexture = new WebCamTexture ();
 _webcamTexture.Stop ();
 Textures = GameObject.FindGameObjectsWithTag ("WebCamTexture");
 foreach (var t in Textures) {

 t.renderer.materials[0].mainTexture = _webcamTexture;
 }

_webcamTexture.Play ();
 TopColors = new List<Color32> ();
 InvokeRepeating ("GetPixels", 0, RefreshInterval);
 }

The WebCamTexture tag denotes anything that I want to use when displaying the contents of the webcam. I was only able to get the webcam image to display on a unity primitive (sphere, plane, etc)

Below is the bit which figures out the coloring.

	public void GetPixels(){
		if (_webcamTexture == null) {
			return;
		}

		CamColors.Clear ();
		TopColors.Clear ();

                //get an array of pixel colors
		var colors = _webcamTexture.GetPixels ();
		var count = 0;

                //running through all 600k pixels every few seconds didn't perform very well, so we're only taking every 200th pixel color (good enough for the gamejam)
		var skip = 200;
		var histogram = new Dictionary<Color, int> ();
		for (int i = 0; i < colors.Length; i+=skip) {
			var c = colors[i];
                        //only take the color if it's not really bright or really dark. This makes for more interesting colors than whites and blacks
			if(c.grayscale < .8f && c.grayscale > .1f){
				CamColors.Add(c);
				if(!histogram.ContainsKey(c)){
					histogram1 = 1;
				} else {
					histogram1++;
				}
			}

		}

                //do an inverse sort on the dictionary in order to figure out which colors are the most popular. If I had more time, I'd group the colors somehow and get more of an average color from the webcam, but it's a gameJam, and you never have time.
		var colorList = histogram.ToList ();
		colorList.Sort (delegate(KeyValuePair<Color, int> pair1, KeyValuePair<Color, int> pair2) {
			return pair2.Value.CompareTo(pair1.Value);
		});

                //save the top 100 colors from the histogram
		var topColors = colorList
			.Take (100);
		foreach (var c in topColors) {
			TopColors.Add(c.Key);
		}

	}

This method figures out (roughly) what the 100 most popular colors in the webcam image are.

Any ideas for how this could be done more efficiently? How I could have gotten a better color result? Let me know in the comments!

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg

NGUI dynamic table contents

If you’re looking to have dynamic tables in your UI and you’re using NGUI for Unity3d, here’s how I’ve been able to do it:

In this example I have a table that contains a data driven list of available levels for a level select screen.

Create a UITable within your panel, and set the columns/padding/etc. Create a prefab to represent one of the items in your UI, and set it to a member variable of your UI script.

public GameObject AvailableLevelPrefab;

In the code that populates the table, create a reference to the table GameObject, loop over the items that you want to include in the table, and instantiate a prefab for each level.

//table game object
var levelsPanel = GameObject.Find("LevelsTable");
foreach(var level in levelsForPlanet){
 var levelUIFragment = Instantiate(AvailableLevelPrefab, levelsPanel.transform.position, levelsPanel.transform.rotation) as GameObject;

//change the level name according to how you want the table items sorted.
 levelUIFragment.name = level.SceneName;

//parent the table item to the table game object
 levelUIFragment.transform.parent = levelsPanel.transform;
 //parenting the item will change its scale. Change it back to whatever it was before
 levelUIFragment.transform.localScale = Vector3.one;
//once the table item exists, you can alter the UI elements so that they match the item. 
//in this case, I'm changing the property of a button so that when clicked, it will bring the player to the correct level
var buttonGameObject = levelUIFragment.transform.Find("Button");
 var button = buttonGameObject.GetComponent<SelectLevelButton>();
 button.PlanetName = level.SceneName;
 }

//once everything is instantiated, call the reposition method in the levels panel
 levelsPanel.GetComponent<UITable>().Reposition();

I’ve used this method a few times, and it seems to work pretty well. Anyone out there have any other methods for creating data-driven UI?

Edit: Cody just commented with an easier way to add the item to the table. Most everything stays the same, but instead of instantiating the prefab, parenting, and changing the scale, NGUI has a helper method that does all of that for you. This is how it would look:

var levelUIFragment = NGUITools.AddChild(levelsPanel, AvailableLevelPrefab);

Thanks for the tip Cody!

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg

Cluster Missile

One of the in-game weapons I want to have for the player is some sort of cluster missile – basically, you fire one projectile, and it explodes and creates a couple more projectiles, which explode, and so on. I’m trying to document how I do this, so here goes:

I created a simple projectile in blender that sorta looks like a missile (it’s really just a cylinder with the center vert pulled out of one of the ends. I imported the model and created an empty game object to contain the model. This way, it’s easy to transform the model and attach custom scripts to it.

  • ClusterMissileEmpty
    • ClusterMissileModel

The empty object has the actual script attached to it. You can find it here: http://pastebin.com/yZpRyJkq

Basically, each missile spawns copies of itself and rotates the copies. I’ll probably add some sort of explosion effect, and change the model so that it doesn’t look so terrible.

Here’s what it looks like:

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg

Scrap Rocket (working title)

A couple of months ago, I started working on a new game using Unity3d. It’s a little late in the process, but I figure I should start documenting the process of making the game – hopefully I’ll be able to look back on it and see the progress I’ve made on the game.

So here’s what I’ve made so far:

  • A working spacepod which can be controlled on a touchscreen
  • The start of a couple of levels
  • A few enemies with basic AI
  • A title/level select screen which is missing a bunch of functionality,  but I think it looks fairly decent.
  • The main game mechanic – which is the ability for the spacepod to tow scrap back to the start of the level
  • An equipment selection mechanic
  • A few different weapons
  • A shield for the spacepod

I’m probably forgetting some stuff, but there will be more posts to come. Here are a few initial screenshots:

Scrap Rocket Title Screen

Level 1

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg

Embiggen with Tasker

Embiggen user Tim just asked me if there was a way to use Tasker with Embiggen, and it turns out there is. Lets say we wanted to have the contents of a text message show up in Embiggen when you get a text message. Here’s what you do:

  1. Create a profile that listens for an incoming text message (New profile -> Event -> Phone -> Received Text)
  2. Create a new Send Intent task with the following settings:

Extra:
Text:%SMSRB

Package:
com.briercan.embiggen
(com.briercan.embiggenplus if you’re using Embiggen Plus)

Class:
com.briercan.embiggen.BigWordsActivity
(com.briercan.embiggenplus.BigWordsActivity if you’re using Embiggen Plus)

It should look something like this:

If you want to show different text for the app, just use a different variable in the Extras field instead of %SMSRB. For example, if you want the name of the person who texted you, put the following in the Extras field:

Text:%SMSRF

I hope this helps! Post a comment if you have any questions or if you have a good idea for how to use Tasker with Embiggen!

Share and Enjoy:
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • Twitter
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Digg