LoginSignup
4
1

More than 1 year has passed since last update.

【Unity】通信量削減に役立つビットパッキングクラス集

Last updated at Posted at 2022-09-24

概要

Unity で Photon を使ったゲームを作る際、Vector3 や Quaternion を手間なくビットパッキングできるクラスが欲しくなったので作りました。
不具合や改善点がありましたら、コメントしていただけると幸いです。

コード

クラス紹介

BitPacking.Vec3ToLong

Vec3ToLong はVector3をlongに非可逆圧縮・展開できるクラスです。他に Vec3ToInt, Vec2ToInt, Vec2ToShort を用意しています。

使用例.cs
// 最小単位, 中央座標, ループ, X座標に使うビット数, Y座標に使うビット数、Z座標に使うビット数を指定できる
// (符号付きの値を利用する際は、値をマイナスにする)
var posPacker = new BitPacking.Vec3ToLong(0.01f, Vector3.zero, false, -22, -20, -22);
// 圧縮
long data = posPacker.Build(transform.position);
// 展開
transform.position = posPacker.Expand(data);

ループを無効にした場合、オーバーフローを抑制します(マップの端より先に移動できなくなります)。
ループを有効にした場合、オーバーフローを許容します(マップの右端まで行くとマップの左端にワープする挙動になります)。

BitPackingQuaternion

BitPackingQuaternion は、QuaternionのEulerAnglesをintやlongに非可逆圧縮・展開できる拡張メソッド等を定義したクラスです。
方向の情報のみを圧縮・展開できる拡張メソッドも用意しています。

使用例.cs
//EulerAnglesをlongに圧縮する拡張メソッド。角度は 0.0005f 刻みになる
long data1 = transform.rotation.PackingToLong();
transform.rotation = data1.ExpandToQuaternion();
//EulerAnglesをintに圧縮する拡張メソッド。角度は 0.5f 刻みになる
int data2 = transform.rotation.PackingToInt();
transform.rotation = data2.ExpandToQuaternion();

// EulerAnglesの一つをshortに圧縮する拡張メソッド。角度は 0.01f 刻みになる
short data3 = transform.rotation.eulerAngles.y.AnglePackingToShort();
transform.rotation = data3.ExpandToQuaternion(Vector3.up);

/* 方向の情報のみを圧縮・展開できる拡張メソッド */
//EulerAnglesのX,Yをintに圧縮する拡張メソッド。角度は 0.01f 刻みになる
int data4 = transform.forward.DirectionPackingToInt();
transform.forward = data4.ExpandToDirection();
//EulerAnglesのX,Yをlongに圧縮する拡張メソッド。変換で僅かな誤差が生まれるものの高精度
long data5 = transform.forward.DirectionPackingToLong();
transform.forward = data5.ExpandToDirection();

BitPackingJoyStick

BitPackingJoyStick は、JoyStick等で扱われるVector2をushortにビットパッキングできる拡張メソッドを定義したクラスです。

使用例.cs
ushort data = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")).JoyStickPackingToUshort();
Debug.Log(data.ExpandToJoyStick());

BitPackingColor

BitPackingColor は、Color, Color32をintにビットパッキングできる拡張メソッドを定義したクラスです。

使用例.cs
int data = Color.yellow.PackingToInt();
Debug.Log(data.ExpandToColor());

BitPacking

BitPacking クラスには、long, int, short, byte に複数の値を組み込める関数を用意しています。

使用例.cs
// 各値をパッキングする際、必要になるビット数を指定する配列を用意する
// (符号付きの値を利用する際は、値をマイナスにする)
private static readonly int[] PlayerInfoBits = { 2, 20, -10 };

// int data に3つの値をパッキング
int data = BitPacking.BuildInt(PlayerInfoBits, 3, 65535, -512);
// パッキングした値を array に展開
int[] array = BitPacking.Expand(PlayerInfoBits, data);

32ビット以上の値をパッキングする際はBuildLong(int[] bits, params long[] values)ExpandToLongs(int[] bits, long packedData)関数を利用してください。
必要になるバイト数は2^nで求まりますが、BitPacking.MinValue(int bit)BitPacking.MaxValue(int bit)関数で求める事もできます。またオーバーフローさせたくない場合はBitPacking.Clamp(long value, int bit)関数で抑制できます。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1