public static void ParseActions(byte[] actions, int id, out SlamObservation observation)
        {
            int offset    = 0;
            var covisible = new List <SlamObservation.CovisibleInfo>();

            observation = new SlamObservation(covisible)
            {
                Orientation = Quaternion.identity,
            };
            SlamPoint obsPoint = observation;

            obsPoint.id    = id;
            obsPoint.color = Color.gray;
            while (offset != actions.Length)
            {
                Debug.Assert(offset <= actions.Length, $"[SlamObservationPackageObject.ParseActions] offset ({offset}) out of range");
                ActionType type = (ActionType)actions[offset++];
                if (type == ActionType.Create)
                {
                    obsPoint.isNew = true;
                }
                if (type == ActionType.Create || type == ActionType.Move)
                {
                    obsPoint.position       = BitConverterEx.ToVector3(actions, offset, ref offset);
                    observation.Orientation = BitConverterEx.ToQuaternion(actions, offset, ref offset);
                }
                if (type == ActionType.Tint)
                {
                    obsPoint.color = BitConverterEx.ToRGBColor32(actions, offset, ref offset);
                }
                if (type == ActionType.Remove)
                {
                    obsPoint.color     = Color.red;
                    obsPoint.isRemoved = true;
                }
                if (type == ActionType.Connect)
                {
                    covisible.Add(
                        new SlamObservation.CovisibleInfo()
                    {
                        id = BitConverterEx.ToInt32(actions, offset, ref offset),
                        sharedPointsCount = BitConverterEx.ToInt32(actions, offset, ref offset)
                    });
                }
                if (type == ActionType.Message)
                {
                    int countOfMsgBytes = BitConverterEx.ToInt32(actions, offset, ref offset);
                    if (countOfMsgBytes >= MAX_MESSAGE_LENGTH_IN_BYTES)
                    {
                        throw new Exception();
                    }
                    obsPoint.message = countOfMsgBytes > 0 ? Encoding.ASCII.GetString(actions, offset, countOfMsgBytes) : "";
                    offset          += sizeof(byte) * MAX_MESSAGE_LENGTH_IN_BYTES;
                }
            }
            observation.Point = obsPoint;
        }