1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Readers for the data files of Unity players: the SerializedFiles a built game keeps its scenes and assets in, and
//! the objects inside them (scenes, meshes, textures, materials, shader programs, terrains, Animator data).
//!
//! A built Unity game keeps its scenes and assets in *SerializedFiles* (`globalgamemanagers`, `*.assets`, `levelN`),
//! with the bulk data (textures, meshes, audio) in `.resS` stream files beside them. A player build strips the type
//! trees that say how each class is laid out, so objects are decoded with a *type tree package* (a TPK file) that the
//! caller supplies. The crate was written against Unity 2019.4 and Unity 6 players (SkateBIRD, Sledding Game, PEAK);
//! what it refuses to read is named in each module.
//!
//! ```no_run
//! use std::path::Path;
//! use unity_formats::{TypeTreePackage, listing::list, mesh::UnityMeshData, player::Player};
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let package = TypeTreePackage::parse(&std::fs::read("typetrees.tpk")?)?;
//! let player = Player::open(Path::new("Game_Data"), package)?;
//! for scene in player.scenes()? {
//! println!("{}: {}", scene.file, scene.name);
//! }
//! for entry in list(&player, Some(&["Mesh"]))?.entries.iter().take(3) {
//! let mesh = UnityMeshData::read(&player, &entry.object)?;
//! println!("{}: {} vertices", mesh.name, mesh.vertex_count);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! The modules:
//!
//! - [`bundle`]: UnityFS bundles (AssetBundles, Addressables content, a player's `data.unity3d`): the block table and
//! directory, nodes read by range.
//! - [`serialized`]: the SerializedFile container: header, types, the object table, script references, external
//! files. Strict and version-gated: only container versions verified against real data are read.
//! - [`tpk`]: a type tree package (the TPK format), the class layouts per Unity version that a player build strips
//! from its files. The caller supplies the package; none is bundled.
//! - [`typetree`]: decoding an object's bytes by its class's type tree into a [`Value`] tree.
//! - [`value`]: the decoded value tree.
//! - [`version`]: Unity version strings.
//! - [`resource`]: streamed resources (`.resS`), the bulk data that objects point at.
//! - [`player`]: a player's data folder: its files, pointers resolved across them, its quality levels, its build's
//! scene list and render pipeline.
//! - [`scene`]: a scene's hierarchy (GameObjects, Transforms composed to world matrices) and its renderers, lights,
//! cameras, colliders and terrains, with the scene's ambient and fog settings.
//! - [`mesh`]: meshes (vertex streams, compressed meshes, index buffers, submeshes, skins and blend shapes).
//! - [`texture`]: textures (formats, mip chains, sampler state).
//! - [`program`]: a shader's compiled programs (variants, constant-buffer layouts, bind slots, code).
//! - [`animator`]: Avatars and AnimatorControllers (state machines, blend trees, transitions).
//! - [`clip`]: AnimationClips (curves decoded to keys with tangents).
//! - [`listing`]: a player's objects by class and name, read from the object tables.
//! - [`material`]: materials as stored (shader, saved properties, keywords).
//! - [`shader`]: a Shader's render state as stored (subshaders, passes, blend, depth and stencil state).
//! - [`terrain`]: terrains as stored (heightmap, holes, splat layers and alphamaps, trees).
//! - [`pipeline`]: the lighting and shadow settings of a Universal Render Pipeline asset.
//!
//! Reads are bounds-checked, and a file the readers do not understand is refused with an [`Error`] that names what
//! was found and where.
// Every module reads stored bytes (the files themselves, or values decoded from them), so a panic is a defect: indexes
// are `get`s, sums are checked or saturating, and numbers are narrowed with `try_from`. Tests index freely.
pub use ;
pub use TypeTreePackage;
pub use TypeTree;
pub use Value;
pub use UnityVersion;
/// The README's code blocks, compiled as doc tests so they cannot drift from the API.
;
/// Why a read was refused.
/// A read's result.
pub type Result<T, E = Error> = Result;
/// A double narrowed to the nearest `f32`: the rounding is the intent, so the truncation lint does not apply.
pub
/// Count one more of `key` in `counts`, stopping at `u64::MAX`.
pub
pub