// <auto-generated>
//  automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>

namespace MyGame.Example
{

using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;

public struct StructOfStructs : IFlatbufferObject
{
  private Struct __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
  public StructOfStructs __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public MyGame.Example.Ability A { get { return (new MyGame.Example.Ability()).__assign(__p.bb_pos + 0, __p.bb); } }
  public MyGame.Example.Test B { get { return (new MyGame.Example.Test()).__assign(__p.bb_pos + 8, __p.bb); } }
  public MyGame.Example.Ability C { get { return (new MyGame.Example.Ability()).__assign(__p.bb_pos + 12, __p.bb); } }

  public static Offset<MyGame.Example.StructOfStructs> CreateStructOfStructs(FlatBufferBuilder builder, uint a_Id, uint a_Distance, short b_A, sbyte b_B, uint c_Id, uint c_Distance) {
    builder.Prep(4, 20);
    builder.Prep(4, 8);
    builder.PutUint(c_Distance);
    builder.PutUint(c_Id);
    builder.Prep(2, 4);
    builder.Pad(1);
    builder.PutSbyte(b_B);
    builder.PutShort(b_A);
    builder.Prep(4, 8);
    builder.PutUint(a_Distance);
    builder.PutUint(a_Id);
    return new Offset<MyGame.Example.StructOfStructs>(builder.Offset);
  }
  public StructOfStructsT UnPack() {
    var _o = new StructOfStructsT();
    this.UnPackTo(_o);
    return _o;
  }
  public void UnPackTo(StructOfStructsT _o) {
    _o.A = this.A.UnPack();
    _o.B = this.B.UnPack();
    _o.C = this.C.UnPack();
  }
  public static Offset<MyGame.Example.StructOfStructs> Pack(FlatBufferBuilder builder, StructOfStructsT _o) {
    if (_o == null) return default(Offset<MyGame.Example.StructOfStructs>);
    var _a_id = _o.A.Id;
    var _a_distance = _o.A.Distance;
    var _b_a = _o.B.A;
    var _b_b = _o.B.B;
    var _c_id = _o.C.Id;
    var _c_distance = _o.C.Distance;
    return CreateStructOfStructs(
      builder,
      _a_id,
      _a_distance,
      _b_a,
      _b_b,
      _c_id,
      _c_distance);
  }
}

public class StructOfStructsT
{
  [Newtonsoft.Json.JsonProperty("a")]
  public MyGame.Example.AbilityT A { get; set; }
  [Newtonsoft.Json.JsonProperty("b")]
  public MyGame.Example.TestT B { get; set; }
  [Newtonsoft.Json.JsonProperty("c")]
  public MyGame.Example.AbilityT C { get; set; }

  public StructOfStructsT() {
    this.A = new MyGame.Example.AbilityT();
    this.B = new MyGame.Example.TestT();
    this.C = new MyGame.Example.AbilityT();
  }
}


}
