[Dev Log] Ice Break

Recommended Posts

I'm gonna be pretty busy but wanted to make something so I'll be making a small game about chillin' out with some icebergs. Sail around, push some icebergs, it'll be real relaxing.




So far all I've done was make a Unity script to make some simple procedural icebergs. Pardon the weird timing, I was just starting/stopping the scene over and over.


Also Lu made me nice lil' a boat





Share this post

Link to post
Share on other sites

The colors came out a little weird in this gif


edit: better colors gif. I switched to perceptual pattern in PS and it almost doubled the size, but it looks much better!



I was having trouble extruding the 'bergs but it turns out Unity has some handy examples of how to do procedural mesh generation/deformation: https://www.assetstore.unity3d.com/en/#!/content/5141

Share this post

Link to post
Share on other sites

Speaking as someone who thoroughly enjoyed the sailing for it's own sake in Wind Waker, this sounds really  appealing.

Share this post

Link to post
Share on other sites

looks lovely- I appreciate the idea of a relaxing game where you just chill out a bit.

Share this post

Link to post
Share on other sites

Hey your vid reminded me of a talk I recently saw/enjoyed related to making things float in unity!



Yeah, I'm actually using Ziba's buoyancy plugin! I helped out a little with beta testing after he presented an early version of that talk at our local Unity group.

Share this post

Link to post
Share on other sites

I've been trying to make a song and failing pretty badly. If some musician out there wants to throw something together, I'd appreciate it!


I was thinking something along the lines of the slower part of the underwater level song from Mario 64 but with more xmas-y bells but I'm down for whatever.

Share this post

Link to post
Share on other sites



Update! I put in the final model from Lu, which looks great. Still having lots of weird physics issues, which I suspect are related to the mesh extrusion code I'm using (which is from Unity's procedural examples project). I see some z fighting on the side faces sometimes, so I think it's generating some extra tris that are breaking the collider.


That said, statistically it's far more likely that it's my fault.


edit: not pictured, icebergs colliding with each other on instantiation and flying off into the horizon, and icebergs colliding with themselves and jittering along the surface of the water.

Share this post

Link to post
Share on other sites

I intended to put this project up on github, but I forgot that I'm using a few plugins and such that'll make that a pain. So instead, here's the interesting part, which is the iceberg generation code. It's a little bit sloppy, as almost all my jam code is, but maybe someone will find it a useful jumping off point for procedural mesh generation.


Basically how it works is it creates a random number of triangles fanning out from the center. Those triangles have sides with random lengths, so you end up with an irregular polygon. From there, I extrude the polygon down to make a short polygonal prism (using an extrusion plugin in the Unity Procedural Examples).


This sometimes creates concave shapes, which isn't great for generating collision meshes; the only solution I can think of off the top of my head to that would be for each iceberg rigidbody to use a complex collider where each collider is a triangular prism built from the random triangles. This would also enable some fun destruction options potentially, but I have no idea how performant it'd be. I'm also still pretty sure there's a bug where it's generating some extra tris somewhere, but I haven't found it yet.


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class IcebergGenerator : MonoBehaviour {
    public int NumOuterPointsMin = 6;
    public int NumOuterPointsMax = 12;

    public float ExtrudeDepthMin = 1;
    public float ExtrudeDepthMax = 1;
    public float RadiusMin = 2;
    public float RadiusMax = 4;
    public int Width = 5;

    MeshFilter meshFilter;
    MeshCollider meshCollider;
    MeshRenderer meshRenderer;

    Vector3 centerPoint;
    Vector3 lastPoint;
    float lastAngle = 0;

    List<Vector3> verts = new List<Vector3>();
    List<Vector3> normals = new List<Vector3>();
    List<int> tris = new List<int>();
    List<Vector2> uvs = new List<Vector2>();

    void Awake()
        meshFilter = GetComponent<MeshFilter>();
        meshCollider = GetComponent<MeshCollider>();
        meshRenderer = GetComponent<MeshRenderer>();

        centerPoint = transform.position;
        lastPoint = centerPoint;


        Matrix4x4 worldToLocal = transform.worldToLocalMatrix;
        Matrix4x4[] m = new Matrix4x4[2];
        m[0] = worldToLocal;
        m[1] = worldToLocal * Matrix4x4.TRS(new Vector3(0, Random.Range(ExtrudeDepthMin, ExtrudeDepthMax), 0), transform.rotation, Vector3.one);
        Mesh mesh = new Mesh();
        MeshExtrusion.ExtrudeMesh(meshFilter.mesh, mesh, m, true);

        meshFilter.mesh = mesh;
        meshCollider.sharedMesh = mesh;

    void GenerateMesh()
        float start_time = Time.time;

        int outerPoints = Random.Range(NumOuterPointsMin, NumOuterPointsMax);

        verts = new List<Vector3>();
        normals = new List<Vector3>();
        tris = new List<int>();
        uvs = new List<Vector2>();

        //top center
        uvs.Add(new Vector2(centerPoint.x, centerPoint.y));

        int totalPoints = (outerPoints * 2) + 2;
        //generate verts
        for (int i = 1; i < outerPoints; i++)
            Vector3 current_point = Utils.GetPointOnCircle(centerPoint, (360 / outerPoints) * i, Random.Range(RadiusMin, RadiusMax));
            uvs.Add(new Vector2(current_point.x, current_point.y));

        //generate top tris
        for (int i = 1; i < outerPoints - 1; i++)
            tris.Add(i + 1);

        // Generate the mesh object.
        Mesh ret = new Mesh();
        ret.name = "IcebergMesh";
        ret.vertices = verts.ToArray();
        ret.triangles = tris.ToArray();
        ret.normals = normals.ToArray();
        ret.uv = uvs.ToArray();

        // Assign the mesh object and update it.
        meshFilter.mesh = ret;
        meshCollider.sharedMesh = ret;

Share this post

Link to post
Share on other sites

Thanks for posting that code! It's a cool read, and I think helped me understand UVs better (also sent me on a quest for tutorials 



Share this post

Link to post
Share on other sites

If you want some more useful info, there were a couple Unite talks this year that I found really helpful for figuring out Unity 3D stuff; the first is Elliot Mitchell (who runs our local Unity user group) talking about general 3D art optimizations, and the second is Joachim Holmer (who makes Shader Forge) talking about procedural mesh generation.



Share this post

Link to post
Share on other sites

Sorry bout the volume levels.


I would have loved to have VR support (probably just cardboard since that's all I have now), but I was having a buncha optimization issues with the floating physics and having ~150 weirdly shaped meshes in the water.


Also nice job escaping, I really never used the reverse so I didn't notice it was sorta broken.





edit: also I made a slightly better iceberg gif



Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now