-
Notifications
You must be signed in to change notification settings - Fork 41
Using Meshes in Unity (Minecraft Version)
Cleaning the maps: In order to use the scans from Project Tango in Unity, the meshes need to be simple enough and small enough to be processed quickly. They also need to be smooth if you so choose to use the meshes as they are. Once you have the mesh files combined and cleaned in a MeshLab project (See: Mapping Hints and Tips), use Filters -> Point Set -> Surface Reconstruction: Poisson with both "Octree Depth" and "Solver Divide" settings in the low teens. This will create a smooth model that has some holes and obstacles for the Unity character to avoid. To make the model manageable for Unity and for the "voxelizer," use Filters -> Remeshing, Simplification and Reconstruction with target faces set at about 10000. Export this model as an OBJ file.
Minecraftifying (optional): Use this cool tool to make your models look as if they were made in Minecraft. Adjust the density slider to your own discretion, but be warned: the high density slider will increase your face count and model size. Use the size slider to determine the space between blocks: for the Minecraft look, set the slider all the way to the right then pull it back as little as possible. Use the options menu to select the "OBJ" file type, and click "Group voxels as single object." Lastly, after saving the file, you will need to import it into Meshlab and flip all of the faces. Use the "Select Connected Components in a Region" tool from the Edit menu and then Filter -> Normals, Curvatures and Orientation -> Invert Faces Orientation. Export this mesh as an OBJ file, and you're all set for Unity!
Creating the game: Follow the instructions from this tutorial to create a simple Unity game of a ball rolling in a plane. Only the first 5 videos are necessary for this tutorial, but I highly recommend watching the whole thing.
Creating a texture: To prevent your mesh from looking like a big white blob, we can use textures to give the scans personality. For a simple black and white depth look, use this path. Otherwise, you will need to import the mesh into a more comprehensive program, such as Maya, to create a UV map by hand. Coloring the vertices in MeshLab is relatively simple. Go to Filters -> Color Creation and Processing -> Per Vertex Color Function and check Preview. For the x,y, and z functions play around with entering equations in the form of A*y +B where A and B are integers. These numbers depend on the size and shape of your mesh, which vary greatly. If you use the "Minecraftifying" trick below, replace "y" with "z" in the functions, as the axis have changed. If all of the functions x,y, and z are the same, the mesh will be black and white. Leave the alpha box at 255 unless you want a semi-transparent mesh. Once your mesh looks the way you want it to, press "Apply." Go into Filters -> Texture -> Parametrization: Trivial Per-Triangle and change the texture dimension to 2048. Press "Apply." Though outwardly nothing will have changed, the coordinates for the texture have been generated. Next, Filters -> Texture -> Transfer Vertex Attributes to Texture (between 2 meshes) with the height and width set to 2048 will save the texture file to the directory that you saved the mesh in. Finally, re-export the mesh as an OBJ file for Unity.
Importing the map: In Unity's Asset menu, click "Import New Asset" and navigate to your OBJ file, either the Minecraft version or the smoothed one. Click on the file in the Projects window and in the Inspector uncheck "Import Materials." Drag the file from the Projects window into the Hierarchy window. Click the triangle next to the mesh name in the Hierarchy window and open "default." In the Inspector window, click "Add Component" and navigate to Physics -> Mesh Collider. If you look in the Scene window, you will see that the mesh is the wrong size - and in the wrong place - for the game. Use the scale tool and the translate tool to align the floor of your mesh with the plane in the game. Click on "Ground" in the Hierarchy window and uncheck the box by its name. Your game is all ready to go! If you would like to include the texture you created earlier, simply import the .png file as an asset and drag it to the mesh's shader. If you do not see the shader, make sure you are selecting the mesh itself and not its parent gameObject.
Over the Shoulder Camera for Unity: The camera in the video below is modified from the stationary one provided in the tutorial. Replace the Main Camera script with this:
using UnityEngine;
using System.Collections;
public class CameraMovement : MonoBehaviour {
public GameObject player;
private Vector3 offset;
public float rotationSpeed;
void Start () {
offset = transform.position;
}
void LateUpdate () {
Vector3 vvector = new Vector3(player.rigidbody.velocity.normalized.x, 0.0f, player.rigidbody.velocity.normalized.z);
if (player.rigidbody.velocity != Vector3.zero) {
//BEHIND
transform.position = Vector3.Slerp (transform.position, (player.transform.position - (vvector * 2.0f)), Time.deltaTime * rotationSpeed);
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (player.transform.position - transform.position), rotationSpeed * Time.deltaTime);
/* IN FRONT
transform.position = Vector3.Slerp (transform.position, (player.transform.position + (vvector * 2.0f)), Time.deltaTime * rotationSpeed);
Vector3 newLookV = player.transform.position - transform.position;
newLookV = new Vector3(-newLookV.x, newLookV.y, -newLookV.z);
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (newLookV), rotationSpeed * Time.deltaTime);
*/
} else {
}
}
}
And replace the player movement script with this so that the axes of movement are independent:
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public float speed;
private float jump = 0.0f;
public Camera gameCamera;
// This is called before physics are applied and once per frame.
void FixedUpdate () {
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal , 0.0f, moveVertical);
Vector3 adjustedMovement = gameCamera.transform.TransformDirection(movement);
adjustedMovement.y = jump;
rigidbody.AddForce(adjustedMovement * speed * Time.deltaTime);
}
void Update () {
if (Input.GetKey("space")) {
jump = 5.0f;
} else {
jump = 0.0f;
}
}
void OnTriggerEnter(Collider other) {
if (other.gameObject.tag == "PickUp") {
other.gameObject.SetActive(false);
}
}
}
The jump variable was added as a sort of "cheat" to get out of tight spots and jump over holes.
The smoothest settings are with player speed at 100 and camera rotation speed at 5.
3 different ways to modify the mesh: 2 different types of textures: