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;
}
}
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;
}
}
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.
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?
Top comments (0)