Flippity-Do-Da: Mirroring a Complex Object in Unity

Oct
29

Flippity-Do-Da: Mirroring a Complex Object in Unity

First, there was this goal:

Simple!

Simple!

It was nothing special. Back then, the game looked like this:

2D over 3D

No, really

Then I added the hoop and field goal posts:

new goal

There used to be a back board for some reason

And the game then looked like this:

SCREENSHOT-635393114352671639

Still looking top-down on the geometry

When the time came to add goal art, there was a problem. The physics of the game were from a flat, top-down perspective and That would make it very hard to tell where to shoot the ball for a basket or field goal. The sprites had a z-height and shadow, but that wouldn’t work for the goals. They had to show some perspective, which doesn’t exist in a 2D flat orthographic top view. The solution was to “cheat” a bit (though no more so than a classic 8-bit game would) by skewing the goals slightly. This initially involved creating two goals: a right and a left. I had planned on finding a good way to mirror them eventually:

skewed goals

It looks perspectivey!

Well it wasn’t a simple thing to do, and this video explains why:

And here’s the code for my script to flip the goal (change names where appropriate):

using UnityEngine;
using System.Collections.Generic;

public class testGoalSceneScript : MonoBehaviour
{
	public List goListLeft = new List();
	public List goListRight = new List();

	private void buildChildList(List goList, Transform root)
	{
		foreach (Transform child in root)
		{
			goList.Add(child.gameObject);
			buildChildList(goList, child);
		}
	}

	// Use this for initialization
	void Start()
	{
		//the left goal parent object
		GameObject goalFather = new GameObject();
		goalFather.name = "3D GOAL-home";

		//the right goal parent object, aka the mirror flipped freak from another dimension parent object
		GameObject freakFather = new GameObject();
		freakFather.name = "3D GOAL-away";

		//instantiate from the master object 
		GameObject goalLeft = (GameObject)Instantiate(*!!!YOUR PREFAB GOES HERE!!!*);
		//no clone words please
		goalLeft.name = goalLeft.name.Replace("(Clone)", "");
		goalLeft.transform.position = new Vector3(0, 0, 0);
		//add to list
		goListLeft.Add(goalLeft);
		//and create child list
		buildChildList(goListLeft, goalLeft.transform);
		//set all parents to the parent object
		foreach (GameObject go in goListLeft)
		{
			go.transform.parent = goalFather.transform;
		}

		//now copy and correct all children in the left list and put em in the right list
		GameObject freak;
		foreach (GameObject go in goListLeft)
		{
			//create a horrible backwards freak copy
			freak = (GameObject)Instantiate(go);
			//no clone words please
			freak.name = freak.name.Replace("(Clone)", "");
			//add to the right list
			goListRight.Add(freak);
			//correct the angles: -y + 180 degrees
			freak.transform.eulerAngles = new Vector3(go.transform.eulerAngles.x, -go.transform.eulerAngles.y + 180, go.transform.eulerAngles.z);
			//correct the x position to -x
			freak.transform.position = new Vector3(-go.transform.position.x, go.transform.position.y, go.transform.position.z);
			//set the parent object to the flipped version parent
			freak.transform.parent = freakFather.transform;
		}
		//scooch it over so we can see it (optional)
		freakFather.transform.position = new Vector3(20, 0, 0);
	}

}

About rick

Founder of Tipping Goat and creator of Super Slam Dunk Touchdown. On Twitter @TippingGoat

Leave a comment

*