Previous Post

How to Make 7 Days to Die in Unity Pt2 - Text Version

Next Post
no preview
DESCRIPTION

From the start I've wanted give Patreon's a little extra whereever possible. I've tried that with bonus videos but keeping those videos exclusive has proved to be a bit trickier than expected. But I thought I'd share this.

Below is the text I write for myself when making a video (I always put the video together before hand to try and minimise cut-worthy moments). It's gotten to the point where the text I write is pretty self-explanatory, and could stand as a good supplement to the video itself, so I thought I'd share with you guys. This is the text I wrote for the most recent video, part 2 of the How to Make 7 Days to Die in Unity series.

/////////////////////////////////////////////////////////////////////////////

// REMEMBER TO RESIZE YOUR CODE TEXT SO PEOPLE CAN READ IT IN THE VIDEO!!! //

/////////////////////////////////////////////////////////////////////////////

// Change sky colour to make terrain more visible.

// Change "0.5f" in PopulateTerrainMap to use the terrainsurface variable.

// While in PopulateTerrainMap, get rid of all that if bollocks and have terrainMap be set to;

// Set the value of this point in the terrainMap.

terrainMap[x, y, z] = (float)y - thisHeight;

// Replace EdgeTable with a 2D table of ints that represent indexes in the corner table, update the code in MarchCube to use the new table.

int[,] EdgeIndexes = new int[12, 2] {

    {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6}, {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}

};

// Get the vertices for the start and end of this edge.

Vector3 vert1 = position + CornerTable[EdgeIndexes[indice, 0]];

Vector3 vert2 = position + CornerTable[EdgeIndexes[indice, 1]];

// Create a function for returning terrain value.

float SampleTerrain (Vector3Int point) {

    return terrainMap[point.x, point.y, point.z];

}

// Replace the one call to terrainMap (in CreateMeshData) with a call to this function.

cube[i] = SampleTerrain(corner);

// Move the cube float array setup into MarchCube and use the new SampleTerrain funcion. Remove the cube setup from our CreateMeshData function.

void MarchCube (Vector3Int position) {

    // Sample terrain values at each corner of cube.

    float[] cube = new float[8];

    for (int i = 0; i < 8; i++) {

        cube[i] = SampleTerrain(position + CornerTable[i]);

    }

    // Get the configuration index of this cube.

    int configIndex = GetCubeConfiguration(cube);

// Add bool to choose between smooth and isometric style terrain.

public bool smoothTerrain;

// And add new code for smooth interpolation, wrapped in an if statement conditional on that smoothterrain value.

Vector3 vertPosition;

if (smoothTerrain) {

    // Get the terrain values at either of our current edge from the cube array we created above.

    float vert1Sample = cube[EdgeIndexes[indice, 0]];

    float vert2Sample = cube[EdgeIndexes[indice, 1]];

    // Calculate the difference between the two terrain values.

    float difference = vert2Sample - vert1Sample;

    // If the difference is 0, the terrain passes through the middle of the edge.

    if (difference == 0f)

        difference = terrainSurface;

    else

        difference = (terrainSurface - vert1Sample) / difference;

    // Calculate the point along the edge that the terrain passes through.

    vertPosition = vert1 + ((vert2 - vert1) * difference);

} else {

    // Get the midpoint of this edge.

    vertPosition = (vert1 + vert2) / 2f;

}

// Add new bool for flatshading.

public bool flatShadedTerrain;

// Create a function for returning the index of a vert (or adding it if it's not there)

int VertForIndice (Vector3 vert) {

    // Loop through all the verts currently in the vertices list.

    for (int i = 0; i < vertices.Count; i++) {

        // If we find one that matches the vert we have, return the index of that vert.

        if (vertices[i] == vert)

            return i;

    }

    // If we didn't find a match, add our vert to the list and return that latest index instead.

    vertices.Add(vert);

    return vertices.Count - 1;

}

// Wrap the end of MarchCube in an if statement to use that function (or not) based on the flatShaded bool.

// Add to our vertices and triangles list and incremement the edgeIndex.

if (flatShadedTerrain) {

    vertices.Add(vertPosition);

    triangles.Add(vertices.Count - 1);

} else

    triangles.Add(VertForIndice(vertPosition));

// Add a mesh collider component, get the component, and set the mesh in BuildMesh. Give the object a tag of "Terrain". Make sure to create the tag in the tags menu.

MeshCollider meshCollider;

meshCollider = GetComponent();

transform.tag = "Terrain";

// Child camera to a second gameobject and basic movement script using the following code.

public Camera cam;

void Update() {

    transform.position = Vector3.MoveTowards(transform.position, transform.position + (cam.transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal")), Time.deltaTime * 10f);

    cam.transform.Rotate(new Vector3(-Input.GetAxis("Mouse Y"), 0, 0));

    transform.Rotate(new Vector3(0, Input.GetAxis("Mouse X"), 0));

}

// Create a crosshair type thing to signify middle of screen.

// Add code to camera script update to raycast on mouseclick.

if (Input.GetMouseButtonDown(0)) {

    Ray ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 1f));

    RaycastHit hit;

    if (Physics.Raycast(ray, out hit)) {

        if (hit.transform.tag == "Terrain")

            Debug.Log("Left Clicked on Terrain");

    }

}

if (Input.GetMouseButtonDown(1)) {

    Ray ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 1f));

    RaycastHit hit;

    if (Physics.Raycast(ray, out hit)) {

        if (hit.transform.tag == "Terrain")

            Debug.Log("Right Clicked on Terrain");

    }

}

// Finally, create two new public functions in marching to deform terrain;

public void PlaceTerrain (Vector3 pos) {

    Vector3Int v3Int = new Vector3Int(Mathf.CeilToInt(pos.x), Mathf.CeilToInt(pos.y), Mathf.CeilToInt(pos.z));

    terrainMap[v3Int.x, v3Int.y, v3Int.z] = 0f;

    CreateMeshData();

}

public void RemoveTerrain (Vector3 pos) {

    Vector3Int v3Int = new Vector3Int(Mathf.FloorToInt(pos.x), Mathf.FloorToInt(pos.y), Mathf.FloorToInt(pos.z));

    terrainMap[v3Int.x, v3Int.y, v3Int.z] = 1f;

    CreateMeshData();

}

// And replace those Debug lines in the camera script with;

hit.transform.GetComponent().RemoveTerrain(hit.point);

hit.transform.GetComponent().PlaceTerrain(hit.point);

// Done!

b3agz PATREON 0 favs
VIEWS1
FILES1 file
POSTEDNov 23, 2019
ARCHIVEDNov 23, 2019