読者です 読者をやめる 読者になる 読者になる

【Unity】構造体属性

C#では union がなかったが、似ている機能があります

StructLayout属性

構造体のレイアウトを指定可能にします

FieldOffset属性

変数を指定位置に配置します

[FieldOffset(バイト)]

ARGBを保持するクラスを作成します

using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
class Color
{
    [FieldOffset(0)] public uint val;
    [FieldOffset(3)] public byte a;
    [FieldOffset(2)] public byte r;
    [FieldOffset(1)] public byte g;
    [FieldOffset(0)] public byte b;
}

こんな感じに使えます

class Test
{
    static void Main()
    {
        Color color = new Color();
        color.val = 0x12345678;
        Console.WriteLine("A(0x{0:X})",color.a);
        Console.WriteLine("R(0x{0:X})",color.r);
        Console.WriteLine("G(0x{0:X})",color.g);
        Console.WriteLine("B(0x{0:X})",color.b);
    }
}
出力
A(0x12)
R(0x34)
G(0x56)
B(0x78)

注意点

派生クラスに使用するとデータが壊れます

クラスを継承関係にします

using System.Runtime.InteropServices;
class Foo
{
    public string text;
}
[StructLayout(LayoutKind.Explicit)]
class Color : Foo
{
    [FieldOffset(0)] public uint val;
    [FieldOffset(3)] public byte a;
    [FieldOffset(2)] public byte r;
    [FieldOffset(1)] public byte g;
    [FieldOffset(0)] public byte b;
}

こんな感じ使ったら

class Test
{
    static void Main()
    {
        Color color = new Color();
        color.val = 0x12345678;
        color.text = "HelloWorld!!";
        Console.WriteLine("A(0x{0:X})",color.a);
        Console.WriteLine("R(0x{0:X})",color.r);
        Console.WriteLine("G(0x{0:X})",color.g);
        Console.WriteLine("B(0x{0:X})",color.b);
    }
}
出力 ( 実行するたびに違います )
A(0xBF)
R(0xF3)
G(0x40)
B(0x10)