DEV Community

loading...

My Struct Crashed Unity3D Editor!

clpsplug profile image Collapsed PLUG Updated on ・2 min read

Unity is great when you want to make something small. But is it only me that find myself in messy code when I do bigger project on it???

Recently, I've got an opportunity to work on a relatively big project on Unity. So I thought I try my best to separate my game's logic into different classes and structs (which don't inherit MonoBehavior.)

Background

My mission is to build a hexagonal map. Red Blob Games has an excellent post about implementing hexagonal grids. I thought coding it would be a helpful exercise to do without any hints (except for the article itself.)

The first thing I implemented was the value object for a point in the cube coordinate. It'd be an immutable value, so I opted for struct. I did something like this (which is just an MCVE:)

public struct SomeStruct {
    public int Property 
    { 
        get {
            return Property;
        }
        set {
            Property = value;
        }
    }

    public SomeStruct(int p)
    {
        this.Property = p;
    }
}
Enter fullscreen mode Exit fullscreen mode

To test it, I hooked it up to one of my MonoBehavior scripts and created an instance. Then -

Yikes, I just crashed Unity3D editor

The editor disappeared. I looked everywhere for it; then the macOS crash reporter came in. According to the report, Unity SEGFAULTed.

I had a case where I crashed Unity3D due to recursion in my code in the past, and I have successfully tracked the offending method by exporting it as a debug-build for iOS because the shipped program has comments which method is which.

So I did the same thing, and surprisingly, the iOS app didn't crash.

Solution

iOS app does not crash, and Xcode won't point out the offending line until the app crashes, so it's useless. Because Unity crashes when I run my game, Debug.Log will never help. Even breakpoints in JetBrains Rider won't help because the way Unity crashes.

I eventually just gave up and fell back to the old-school method. I put a bunch of 'print-to-file' lines that prints where the line is in which file. I was feeling that something is going pretty absurd at this point.

I finally got to track down the problem; the log stopped right in my struct's constructor. The constructor was the culprit!

I fiddled around the property and found that we weren't allowed to access the backing field for each property in the constructor (and that's why I couldn't make Property auto property.)

The following is the working code:

public struct SomeStruct {
    public int Property { get; set; }

    public SomeStruct(int p): this() // initialize the base class first
    {
        Property = p;
    }
}
Enter fullscreen mode Exit fullscreen mode

The resulting HexMap Library

It was almost smooth sailing afterward. I managed to fill the hex grid with sprites with my library. It's available here.

GitHub logo Clpsplug / hexagonal_map

Hexagonal map and cells data structure helper based on https://www.redblobgames.com/grids/hexagons/

Hexagonal Map Coordinates Helper

Red Blob Games Websiteで 説明されている立方体座標・QR座標のC#での実装
This C# code implements Cube- and QR-based coordinates described in Red Blob Games Website.

Usage

Coordinates

There are 2 coordinates supported - Cube and QR(Axial.)
Constructors of those value objects are private, and you must make through specific methods, fromCube and fromQR respectively.

The supported coordinates makes creating concentric hexagonal map easy. Better supports for map that spreads in the form of a rectaingle are planned through offset coordinates.

Note that whether your hexagonal map is pointy-topped or flat-topped is completely up to you These coordinates should work fine under both circumstances.

Also note that you MUST NOT directly change the value for the coordinates. You can't. If you want to modify the value and save it somewhere else, just create new coordinate object with modified value.

Cube Coordinates

Let's take a cube grid and slice out a diagonal plane…

What I still don't get

The mystery is, why didn't iOS app crash? My code tried to access where it shouldn't and crashed. Is it because Unity converted it to C++ on export where such restriction doesn't seem to exist?

Discussion (0)

pic
Editor guide