├── .github └── workflows │ └── python-publish.yml ├── .gitignore ├── README.md ├── UnityPyLive2DExtractor.spec ├── UnityPyLive2DExtractor ├── __init__.py ├── __main__.py └── generated │ ├── Live2D │ └── Cubism │ │ ├── Core │ │ ├── Unmanaged │ │ │ └── __init__.py │ │ └── __init__.py │ │ ├── Framework │ │ ├── Expression │ │ │ └── __init__.py │ │ ├── HarmonicMotion │ │ │ └── __init__.py │ │ ├── Json │ │ │ └── __init__.py │ │ ├── LookAt │ │ │ └── __init__.py │ │ ├── Motion │ │ │ └── __init__.py │ │ ├── MotionFade │ │ │ └── __init__.py │ │ ├── MouthMovement │ │ │ └── __init__.py │ │ ├── Physics │ │ │ └── __init__.py │ │ ├── Pose │ │ │ └── __init__.py │ │ ├── Raycasting │ │ │ └── __init__.py │ │ ├── Tasking │ │ │ └── __init__.py │ │ ├── UserData │ │ │ └── __init__.py │ │ ├── Utils │ │ │ └── __init__.py │ │ └── __init__.py │ │ ├── Garage │ │ └── __init__.py │ │ ├── Rendering │ │ ├── Masking │ │ │ └── __init__.py │ │ └── __init__.py │ │ └── Samples │ │ ├── AsyncBenchmark │ │ └── __init__.py │ │ ├── LookAt │ │ └── __init__.py │ │ ├── Masking │ │ └── __init__.py │ │ ├── OriginalWorkflow │ │ ├── Demo │ │ │ └── __init__.py │ │ ├── Expression │ │ │ └── __init__.py │ │ └── Motion │ │ │ └── __init__.py │ │ └── Raycasting │ │ └── __init__.py │ └── __init__.py ├── external └── typetree_cubism.json ├── setup.py └── typetree_codegen.py /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build-and-release: 9 | if: "contains(github.event.head_commit.message, 'Version')" 10 | runs-on: windows-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Set up Python 14 | uses: actions/setup-python@v2 15 | with: 16 | python-version: '3.10' 17 | - name: Install dependencies 18 | run: | 19 | python -m pip install --upgrade pip 20 | python -m pip install --upgrade setuptools wheel build twine 21 | python -m pip install Pyinstaller 22 | python -m pip install -e . 23 | - name: Build package 24 | run: python -m build --no-isolation 25 | - name: Publish package 26 | env: 27 | TWINE_USERNAME: __token__ 28 | TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} 29 | run: | 30 | twine upload ./dist/*.whl --skip-existing 31 | twine upload ./dist/*.tar.gz --skip-existing 32 | - name: Build Windows executables 33 | run: | 34 | pyinstaller UnityPyLive2DExtractor.spec 35 | - name : Get Version 36 | id : get_version 37 | run : | 38 | $message = @(git log -1 --oneline --format=%s) 39 | $lines = $message.Split(' ') 40 | $version = $lines[1] 41 | 42 | Write-Output "::set-output name=version::$version" 43 | - name: Create Release 44 | id: create_release 45 | uses: actions/create-release@v1 46 | env: 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 48 | with: 49 | tag_name: ${{ steps.get_version.outputs.version }} 50 | release_name: Version ${{ steps.get_version.outputs.version }} 51 | - uses: actions/upload-release-asset@v1.0.1 52 | env: 53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | with: 55 | upload_url: ${{ steps.create_release.outputs.upload_url }} 56 | asset_path: dist/UnityPyLive2DExtractor.exe 57 | asset_name: UnityPyLive2DExtractor.exe 58 | asset_content_type: application/application/vnd.microsoft.portable-executable 59 | - uses: eregon/publish-release@v1 60 | env: 61 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 62 | with: 63 | release_id: ${{ steps.create_release.outputs.id }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | build/ 3 | dist/ 4 | __pycache__/ 5 | *.egg-info 6 | dump 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityPyLive2DExtractor 2 | [![Windows Build](https://github.com/mos9527/UnityPyLive2DExtractor/actions/workflows/python-publish.yml/badge.svg)](https://github.com/mos9527/UnityPyLive2DExtractor/blob/main/.github/workflows/python-publish.yml) 3 | [![Releases](https://img.shields.io/github/downloads/mos9527/UnityPyLive2DExtractor/total.svg)](https://GitHub.com/mos9527/UnityPyLive2DExtractor/releases/) 4 | [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) 5 | 6 | General purpose [Live2D](https://www.live2d.com/) Asset recovery tool built w/ [UnityPy](https://github.com/K0lb3/UnityPy) and [sssekai](https://github.com/mos9527/sssekai) 7 | 8 | As the name suggests, this project is heavily inspired by [Perfare/UnityLive2DExtractor](https://github.com/Perfare/UnityLive2DExtractor). With a few key differences: 9 | - All Live2D types are implemented with [dumped TypeTree](https://github.com/mos9527/UnityPyLive2DExtractor/blob/main/external/typetree_cubism.json) and [generated types](https://github.com/mos9527/UnityPyLive2DExtractor/blob/main/typetree_codegen.py). This should help with compatibility issues. 10 | - Do note, however, that you may need to update the TypeTree if the Live2D version changes. 11 | - Generate the TypeTree with [typetree_codegen](https://github.com/mos9527/UnityPyLive2DExtractor/blob/main/typetree_codegen.py) and replace the existing TypeTree at `UnityPyLive2DExtractor/generated` 12 | ```bash 13 | python typetree_codegen.py type_tree_cubism.json UnityPyLive2DExtractor/generated 14 | ``` 15 | - New (not necessarily better) asset discovery method. Though proven to be more reliable in some cases. 16 | 17 | ## Installation 18 | - Install the script from PyPI 19 | ```bash 20 | pip install UnityPyLive2DExtractor 21 | ``` 22 | - Or, you can use the pre-built executables for Windows from [Releases](https://github.com/mos9527/UnityPyLive2DExtractor/releases/). 23 | ## Usage 24 | ```bash 25 | UnityPyLive2DExtractor 26 | ``` 27 | Where `` is the path to your game's path, and `` is the directory to extract the Live2D assets to. 28 | ## References 29 | - https://github.com/Perfare/UnityLive2DExtractor 30 | - https://github.com/K0lb3/TypeTreeGenerator 31 | - https://github.com/K0lb3/UnityPy -------------------------------------------------------------------------------- /UnityPyLive2DExtractor.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | # https://github.com/K0lb3/UnityPy/issues/184 4 | import UnityPy, UnityPyLive2DExtractor, archspec, os 5 | unitypy_path = lambda path: os.path.join(os.path.dirname(UnityPy.__file__), path) 6 | archspec_path = lambda path: os.path.join(os.path.dirname(archspec.__file__), path) 7 | UnityPyLive2DExtractor_path = lambda path: os.path.join(os.path.dirname(UnityPyLive2DExtractor.__file__), path) 8 | a = Analysis( 9 | ['UnityPyLive2DExtractor/__main__.py'], 10 | pathex=[ 11 | ], 12 | binaries=[], 13 | datas=[ 14 | (unitypy_path('resources/*'), 'UnityPy/resources'), 15 | (UnityPyLive2DExtractor_path(''), 'UnityPyLive2DExtractor'), 16 | (archspec_path('json'), 'archspec/json'), 17 | ], 18 | hiddenimports=[], 19 | hookspath=[], 20 | hooksconfig={}, 21 | runtime_hooks=[], 22 | excludes=[], 23 | noarchive=False, 24 | optimize=0, 25 | ) 26 | pyz = PYZ(a.pure) 27 | 28 | exe = EXE( 29 | pyz, 30 | a.scripts, 31 | a.binaries, 32 | a.datas, 33 | [], 34 | name='UnityPyLive2DExtractor', 35 | debug=False, 36 | bootloader_ignore_signals=False, 37 | strip=False, 38 | upx=True, 39 | upx_exclude=[], 40 | runtime_tmpdir=None, 41 | console=True, 42 | disable_windowed_traceback=False, 43 | argv_emulation=False, 44 | target_arch=None, 45 | codesign_identity=None, 46 | entitlements_file=None, 47 | icon='NONE', 48 | ) -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = (0, 2, 0) 2 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/__main__.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os, io, json 3 | from zlib import crc32 4 | import UnityPy 5 | from typing import TypeVar 6 | from UnityPy.classes import ( 7 | MonoBehaviour, 8 | GameObject, 9 | Transform, 10 | PPtr, 11 | Texture2D, 12 | ) 13 | from UnityPy.enums import ClassIDType 14 | from UnityPy.files import ObjectReader 15 | from logging import getLogger 16 | import coloredlogs 17 | 18 | T = TypeVar("T") 19 | 20 | # from UnityPy.helpers import TypeTreeHelper 21 | # TypeTreeHelper.read_typetree_boost = False 22 | logger = getLogger("UnityPyLive2DExtractor") 23 | 24 | from UnityPyLive2DExtractor import __version__ 25 | from UnityPyLive2DExtractor.generated import TYPETREE_DEFS 26 | from UnityPyLive2DExtractor.generated.Live2D.Cubism.Core import CubismModel 27 | from UnityPyLive2DExtractor.generated.Live2D.Cubism.Rendering import CubismRenderer 28 | from UnityPyLive2DExtractor.generated.Live2D.Cubism.Framework.Physics import ( 29 | CubismPhysicsNormalizationTuplet, 30 | CubismPhysicsNormalization, 31 | CubismPhysicsParticle, 32 | CubismPhysicsOutput, 33 | CubismPhysicsInput, 34 | CubismPhysicsSubRig, 35 | CubismPhysicsRig, 36 | CubismPhysicsController, 37 | ) 38 | from sssekai.fmt.motion3 import to_motion3 39 | from sssekai.fmt.moc3 import read_moc3 40 | from sssekai.unity.AnimationClip import AnimationHelper 41 | 42 | 43 | def monkey_patch(cls): 44 | """ooh ooh aah aah""" 45 | 46 | def wrapper(func): 47 | setattr(cls, func.__name__, func) 48 | return func 49 | 50 | return wrapper 51 | 52 | 53 | @monkey_patch(CubismPhysicsNormalizationTuplet) 54 | def dump(self: CubismPhysicsNormalizationTuplet): 55 | return { 56 | "Maximum": self.Maximum, 57 | "Minimum": self.Minimum, 58 | "Default": self.Default, 59 | } 60 | 61 | 62 | @monkey_patch(CubismPhysicsNormalization) 63 | def dump(self: CubismPhysicsNormalization): 64 | return {"Position": self.Position.dump(), "Angle": self.Angle.dump()} 65 | 66 | 67 | @monkey_patch(CubismPhysicsParticle) 68 | def dump(self: CubismPhysicsParticle): 69 | return { 70 | "Position": {"X": self.InitialPosition.x, "Y": self.InitialPosition.y}, 71 | "Mobility": self.Mobility, 72 | "Delay": self.Delay, 73 | "Acceleration": self.Acceleration, 74 | "Radius": self.Radius, 75 | } 76 | 77 | 78 | @monkey_patch(CubismPhysicsOutput) 79 | def dump(self: CubismPhysicsOutput): 80 | return { 81 | "Destination": {"Target": "Parameter", "Id": self.DestinationId}, 82 | "VertexIndex": self.ParticleIndex, 83 | "Scale": self.AngleScale, 84 | "Weight": self.Weight, 85 | "Type": ["X", "Y", "Angle"][self.SourceComponent], 86 | "Reflect": self.IsInverted, 87 | } 88 | 89 | 90 | @monkey_patch(CubismPhysicsInput) 91 | def dump(self: CubismPhysicsInput): 92 | return { 93 | "Source": {"Target": "Parameter", "Id": self.SourceId}, 94 | "Weight": self.Weight, 95 | "Type": ["X", "Y", "Angle"][self.SourceComponent], 96 | "Reflect": self.IsInverted, 97 | } 98 | 99 | 100 | @monkey_patch(CubismPhysicsSubRig) 101 | def dump(self: CubismPhysicsSubRig): 102 | return { 103 | "Input": [x.dump() for x in self.Input], 104 | "Output": [x.dump() for x in self.Output], 105 | "Vertices": [x.dump() for x in self.Particles], 106 | "Normalization": self.Normalization.dump(), 107 | } 108 | 109 | 110 | @monkey_patch(CubismPhysicsRig) 111 | def dump(self: CubismPhysicsRig): 112 | return [ 113 | {"Id": "PhysicsSetting%d" % (i + 1), **rig.dump()} 114 | for i, rig in enumerate(self.SubRigs) 115 | ] 116 | 117 | 118 | @monkey_patch(CubismPhysicsController) 119 | def dump(self: CubismPhysicsController): 120 | return { 121 | "Version": 3, 122 | "Meta": { 123 | "PhysicsSettingCount": len(self._rig.SubRigs), 124 | "TotalInputCount": sum((len(x.Input) for x in self._rig.SubRigs)), 125 | "TotalOutputCount": sum((len(x.Output) for x in self._rig.SubRigs)), 126 | "VertexCount": sum((len(x.Particles) for x in self._rig.SubRigs)), 127 | "Fps": 60, 128 | "EffectiveForces": { 129 | "Gravity": {"X": 0, "Y": -1}, 130 | "Wind": {"X": 0, "Y": 0}, 131 | }, 132 | "PhysicsDictionary": [ 133 | {"Id": "PhysicsSetting%d" % (i + 1), "Name": "%d" % (i + 1)} 134 | for i, _ in enumerate(self._rig.SubRigs) 135 | ], 136 | }, 137 | "PhysicsSettings": self._rig.dump(), 138 | } 139 | 140 | 141 | @monkey_patch(CubismRenderer) 142 | def __hash__(self: CubismRenderer): 143 | return self._mainTexture.path_id 144 | 145 | 146 | @monkey_patch(CubismRenderer) 147 | def __eq__(self: CubismRenderer, other: CubismRenderer): 148 | return self.__hash__() == other.__hash__() 149 | 150 | 151 | from dataclasses import dataclass 152 | 153 | 154 | @dataclass 155 | class ExtractorFlags: 156 | live2d_variant: str = "cubism" 157 | 158 | 159 | FLAGS = ExtractorFlags() 160 | 161 | 162 | # XXX: Is monkey patching this into UnityPy a good idea? 163 | def read_from(reader: ObjectReader, **kwargs): 164 | """Import generated classes by MonoBehavior script class type and read from reader""" 165 | import importlib 166 | 167 | match reader.type: 168 | case ClassIDType.MonoBehaviour: 169 | mono: MonoBehaviour = reader.read(check_read=False) 170 | script = mono.m_Script.read() 171 | nameSpace = script.m_Namespace 172 | className = script.m_Name 173 | if script.m_Namespace: 174 | fullName = script.m_Namespace + "." + className 175 | else: 176 | fullName = className 177 | typetree = TYPETREE_DEFS.get(fullName, None) 178 | 179 | if typetree: 180 | result = reader.read_typetree(typetree) 181 | nameSpace = importlib.import_module( 182 | f".generated.{nameSpace}", package="UnityPyLive2DExtractor" 183 | ) 184 | clazz = getattr(nameSpace, className, None) 185 | instance = clazz(object_reader=reader, **result) 186 | return instance 187 | else: 188 | logger.debug(f"Missing definitions for {fullName}, skipping.") 189 | return mono 190 | case _: 191 | return reader.read(**kwargs) 192 | 193 | 194 | def read_from_ptr(ptr: PPtr[T], reader: ObjectReader) -> T: 195 | return read_from(ptr.deref(reader.assets_file)) 196 | 197 | 198 | def __main__(): 199 | parser = argparse.ArgumentParser( 200 | description="UnityPyLive2D Extractor v%d.%d.%d" % __version__ 201 | ) 202 | parser.add_argument("infile", help="Input file/directory to extract from") 203 | parser.add_argument("outdir", help="Output directory to extract to") 204 | parser.add_argument( 205 | "--log-level", 206 | help="Set logging level", 207 | default="DEBUG", 208 | choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], 209 | ) 210 | parser.add_argument( 211 | "--no-anim", help="Do not extract animations", action="store_true" 212 | ) 213 | args = parser.parse_args() 214 | coloredlogs.install( 215 | level=args.log_level, 216 | fmt="%(asctime)s %(name)s [%(levelname).4s] %(message)s", 217 | isatty=True, 218 | ) 219 | os.makedirs(args.outdir, exist_ok=True) 220 | logger.info("UnityPyLive2D Extractor v%d.%d.%d" % __version__) 221 | logger.info("Loading %s" % args.infile) 222 | env = UnityPy.load(args.infile) 223 | objs = [ 224 | read_from(reader) 225 | for reader in filter( 226 | lambda reader: reader.type == ClassIDType.MonoBehaviour, 227 | env.objects, 228 | ) 229 | ] 230 | logger.info("MonoBehaviours: %d" % len(objs)) 231 | candidates = [ 232 | read_from_ptr(obj.m_GameObject, obj) 233 | for obj in filter(lambda obj: isinstance(obj, CubismModel), objs) 234 | ] 235 | crc_cache = dict() 236 | # fmt: off 237 | for OBJ in candidates: 238 | OBJ: GameObject 239 | components = [read_from_ptr(ptr, OBJ) for ptr in OBJ.m_Components] 240 | NAME = OBJ.m_Name 241 | MOC : CubismModel = next(filter(lambda x: isinstance(x, CubismModel), components), None) 242 | PHY : CubismPhysicsController = next(filter(lambda x: isinstance(x, CubismPhysicsController), components), None) 243 | # ANI : Animator = next(filter(lambda x: isinstance(x, Animator), components), None) 244 | # RND : CubismRenderController = next(filter(lambda x: isinstance(x, CubismRenderController), components), None) 245 | logger.info(f"Processing {NAME}") 246 | outdir = os.path.join(args.outdir, NAME) 247 | os.makedirs(outdir, exist_ok=True) 248 | metadata = { 249 | "Version": 3, 250 | "FileReferences": { 251 | "Moc":"", 252 | "Textures": [], 253 | "Physics": "" 254 | }, 255 | } 256 | if MOC: 257 | fname = metadata["FileReferences"]["Moc"] = f"{NAME}.moc3" 258 | with open(os.path.join(outdir, fname), "wb") as f: 259 | moc = read_from_ptr(MOC._moc, MOC.object_reader) 260 | moc = bytes(moc._bytes) 261 | logger.info(".moc3: %d bytes" % f.write(moc)) 262 | try: 263 | parts, parameters = read_moc3(io.BytesIO(moc)) 264 | for s in parts: 265 | path = "Parts/" + s 266 | crc_cache[crc32(path.encode("utf-8"))] = path 267 | for s in parameters: 268 | path = "Parameters/" + s 269 | crc_cache[crc32(path.encode("utf-8"))] = path 270 | logger.info(".moc3: %d parts, %d parameters" % (len(parts), len(parameters))) 271 | except Exception as e: 272 | logger.warning("Failed to parse MOC3: %s" % e) 273 | logger.warning("This may indicate obfuscation or a different format") 274 | if PHY: 275 | fname = metadata["FileReferences"]["Physics"] = f"{NAME}.physics3.json" 276 | with open(os.path.join(outdir, fname), "w") as f: 277 | logger.info(".physics3.json: %d bytes" % f.write(json.dumps(PHY.dump(),indent=4))) 278 | # Renderers are bound to the meshes in the hierarchy 279 | def children_recursive(obj: GameObject): 280 | transform : Transform = obj.m_Transform.read() 281 | for child in transform.m_Children: 282 | child = read_from_ptr(child, obj) 283 | ch_obj = child.m_GameObject.read() 284 | yield ch_obj 285 | yield from children_recursive(ch_obj) 286 | # Mark referenced textures 287 | TEX = set() 288 | for child in children_recursive(OBJ): 289 | components = [read_from_ptr(ptr, child) for ptr in child.m_Components] 290 | RND : CubismRenderer = next(filter(lambda x: isinstance(x, CubismRenderer), components), None) 291 | if RND: 292 | TEX.add(RND) 293 | if TEX: 294 | metadata["FileReferences"]["Textures"] = [] 295 | for tex in TEX: 296 | tex : CubismRenderer 297 | tex : Texture2D = read_from_ptr(tex._mainTexture, tex) 298 | path = f"Textures/{tex.m_Name}.png" 299 | metadata["FileReferences"]["Textures"].append(path) 300 | path = os.path.join(outdir, path) 301 | os.makedirs(os.path.dirname(path), exist_ok=True) 302 | tex.image.save(path) 303 | logger.info(f"[texture]: {tex.m_Name}") 304 | # XXX: Lexical. But why? 305 | metadata["FileReferences"]["Textures"].sort() 306 | path = f"{NAME}.model3.json" 307 | json.dump(metadata, open(os.path.join(outdir,path), "w"), indent=4) 308 | logger.info(f"[metadata]: {path}") 309 | # fmt: on 310 | if not args.no_anim: 311 | for reader in filter( 312 | lambda reader: reader.type == ClassIDType.AnimationClip, env.objects 313 | ): 314 | clip = reader.read() 315 | helper = AnimationHelper.from_clip(clip) 316 | motion3 = to_motion3(helper, crc_cache, clip) 317 | path = f"Animation/{clip.m_Name}.motion3.json" 318 | logger.info(f"[motion3]: {path}") 319 | path = os.path.join(args.outdir, path) 320 | os.makedirs(os.path.dirname(path), exist_ok=True) 321 | json.dump(motion3, open(path, "w"), indent=4) 322 | 323 | 324 | if __name__ == "__main__": 325 | __main__() 326 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Core/Unmanaged/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Core.Unmanaged 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class ByteExtensionMethods(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class CubismCoreDll(MonoBehaviour): 11 | pass 12 | @typetree_defined 13 | class CubismUnmanagedByteArrayView(MonoBehaviour): 14 | pass 15 | @typetree_defined 16 | class CubismUnmanagedCanvasInformation(MonoBehaviour): 17 | pass 18 | @typetree_defined 19 | class CubismUnmanagedDrawables(MonoBehaviour): 20 | pass 21 | @typetree_defined 22 | class CubismUnmanagedFloatArrayView(MonoBehaviour): 23 | pass 24 | @typetree_defined 25 | class CubismUnmanagedIntArrayView(MonoBehaviour): 26 | pass 27 | @typetree_defined 28 | class CubismUnmanagedMemory(MonoBehaviour): 29 | pass 30 | @typetree_defined 31 | class CubismUnmanagedMoc(MonoBehaviour): 32 | pass 33 | @typetree_defined 34 | class CubismUnmanagedModel(MonoBehaviour): 35 | pass 36 | @typetree_defined 37 | class CubismUnmanagedParameters(MonoBehaviour): 38 | pass 39 | @typetree_defined 40 | class CubismUnmanagedParts(MonoBehaviour): 41 | pass 42 | @typetree_defined 43 | class CubismUnmanagedUshortArrayView(MonoBehaviour): 44 | pass 45 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Core/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Core 3 | 4 | from .... import * 5 | 6 | @typetree_defined 7 | class ArrayExtensionMethods(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class ComponentExtensionMethods(MonoBehaviour): 11 | pass 12 | @typetree_defined 13 | class CubismCanvasInformation(MonoBehaviour): 14 | pass 15 | @typetree_defined 16 | class CubismDrawable(MonoBehaviour): 17 | _unmanagedIndex : int 18 | _screenColor : ColorRGBA 19 | @typetree_defined 20 | class CubismDynamicDrawableData(MonoBehaviour): 21 | pass 22 | @typetree_defined 23 | class CubismLogging(MonoBehaviour): 24 | pass 25 | @typetree_defined 26 | class CubismMoc(MonoBehaviour): 27 | _bytes : List[int] 28 | @typetree_defined 29 | class CubismModel(MonoBehaviour): 30 | _moc : PPtr[CubismMoc] 31 | @typetree_defined 32 | class CubismParameter(MonoBehaviour): 33 | _unmanagedIndex : int 34 | Value : float 35 | @typetree_defined 36 | class CubismPart(MonoBehaviour): 37 | _unmanagedIndex : int 38 | Opacity : float 39 | @typetree_defined 40 | class CubismTaskableModel(MonoBehaviour): 41 | pass 42 | @typetree_defined 43 | class CubismTaskQueue(MonoBehaviour): 44 | pass 45 | @typetree_defined 46 | class GameObjectExtensionMethods(MonoBehaviour): 47 | pass 48 | @typetree_defined 49 | class ICubismTask(MonoBehaviour): 50 | pass 51 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Expression/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Expression 3 | 4 | from ..... import * 5 | from .....Live2D.Cubism.Core import CubismParameter 6 | from .....Live2D.Cubism.Framework import CubismParameterBlendMode 7 | from ..... import SerializableExpressionParameter 8 | 9 | @typetree_defined 10 | class CubismExpressionData(MonoBehaviour): 11 | Type : str 12 | FadeInTime : float 13 | FadeOutTime : float 14 | Parameters : List[SerializableExpressionParameter] 15 | @typetree_defined 16 | class CubismExpressionList(MonoBehaviour): 17 | CubismExpressionObjects : List[PPtr[CubismExpressionData]] 18 | @typetree_defined 19 | class CubismExpressionController(MonoBehaviour): 20 | ExpressionsList : PPtr[CubismExpressionList] 21 | UseLegacyBlendCalculation : bool 22 | CurrentExpressionIndex : int 23 | @typetree_defined 24 | class CubismExpressionParameterValue(MonoBehaviour): 25 | Parameter : PPtr[CubismParameter] 26 | AdditiveValue : float 27 | MultiplyValue : float 28 | OverwriteValue : float 29 | @typetree_defined 30 | class CubismPlayingExpression(MonoBehaviour): 31 | Type : str 32 | FadeInTime : float 33 | FadeOutTime : float 34 | Weight : float 35 | ExpressionUserTime : float 36 | ExpressionStartTime : float 37 | ExpressionEndTime : float 38 | Destinations : List[PPtr[CubismParameter]] 39 | Value : List[float] 40 | Blend : List[int] 41 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/HarmonicMotion/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.HarmonicMotion 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismHarmonicMotionController(MonoBehaviour): 8 | BlendMode : int 9 | ChannelTimescales : List[float] 10 | @typetree_defined 11 | class CubismHarmonicMotionDirection(MonoBehaviour): 12 | value__ : int 13 | @typetree_defined 14 | class CubismHarmonicMotionParameter(MonoBehaviour): 15 | Channel : int 16 | Direction : int 17 | NormalizedOrigin : float 18 | NormalizedRange : float 19 | Duration : float 20 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Json/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Json 3 | 4 | from ..... import * 5 | from ..... import PhysicsDictionaryItem 6 | from ..... import SerializableCombinedParameterIds 7 | from ..... import SerializableCurve 8 | from ..... import SerializableEffectiveForces 9 | from ..... import SerializableExpression 10 | from ..... import SerializableExpressionParameter 11 | from ..... import SerializableFileReferences 12 | from ..... import SerializableGroup 13 | from ..... import SerializableHitArea 14 | from ..... import SerializableInput 15 | from ..... import SerializableMeta 16 | from ..... import SerializableMotions 17 | from ..... import SerializableNormalization 18 | from ..... import SerializableNormalizationValue 19 | from ..... import SerializableOutput 20 | from ..... import SerializableParameter 21 | from ..... import SerializableParameterGroups 22 | from ..... import SerializableParameters 23 | from ..... import SerializableParts 24 | from ..... import SerializablePhysicsSettings 25 | from ..... import SerializableUserData 26 | from ..... import SerializableVector2 27 | from ..... import SerializableVertex 28 | 29 | @typetree_defined 30 | class CubismBuiltinPickers(MonoBehaviour): 31 | pass 32 | @typetree_defined 33 | class CubismDisplayInfo3Json(MonoBehaviour): 34 | Version : int 35 | Parameters : List[SerializableParameters] 36 | ParameterGroups : List[SerializableParameterGroups] 37 | Parts : List[SerializableParts] 38 | CombinedParameters : List[SerializableCombinedParameterIds] 39 | @typetree_defined 40 | class CubismExp3Json(MonoBehaviour): 41 | Type : str 42 | FadeInTime : float 43 | FadeOutTime : float 44 | Parameters : List[SerializableExpressionParameter] 45 | @typetree_defined 46 | class CubismJsonParser(MonoBehaviour): 47 | pass 48 | @typetree_defined 49 | class CubismModel3Json(MonoBehaviour): 50 | Version : int 51 | FileReferences : SerializableFileReferences 52 | Groups : List[SerializableGroup] 53 | HitAreas : List[SerializableHitArea] 54 | @typetree_defined 55 | class CubismMotion3Json(MonoBehaviour): 56 | Version : int 57 | Meta : SerializableMeta 58 | Curves : List[SerializableCurve] 59 | UserData : List[SerializableUserData] 60 | @typetree_defined 61 | class CubismPhysics3Json(MonoBehaviour): 62 | Version : int 63 | Meta : SerializableMeta 64 | PhysicsSettings : List[SerializablePhysicsSettings] 65 | @typetree_defined 66 | class CubismPose3Json(MonoBehaviour): 67 | Type : str 68 | FadeInTime : float 69 | @typetree_defined 70 | class CubismUserData3Json(MonoBehaviour): 71 | Version : int 72 | Meta : SerializableMeta 73 | UserData : List[SerializableUserData] 74 | @typetree_defined 75 | class Value(MonoBehaviour): 76 | pass 77 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/LookAt/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.LookAt 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismLookAxis(MonoBehaviour): 8 | value__ : int 9 | @typetree_defined 10 | class CubismLookController(MonoBehaviour): 11 | BlendMode : int 12 | _target : PPtr[Object] 13 | Center : PPtr[Transform] 14 | Damping : float 15 | @typetree_defined 16 | class CubismLookParameter(MonoBehaviour): 17 | Axis : int 18 | Factor : float 19 | @typetree_defined 20 | class CubismLookTargetBehaviour(MonoBehaviour): 21 | pass 22 | @typetree_defined 23 | class ICubismLookTarget(MonoBehaviour): 24 | pass 25 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Motion/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Motion 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismMotionController(MonoBehaviour): 8 | LayerCount : int 9 | @typetree_defined 10 | class CubismMotionLayer(MonoBehaviour): 11 | pass 12 | @typetree_defined 13 | class CubismMotionPriority(MonoBehaviour): 14 | pass 15 | @typetree_defined 16 | class CubismMotionState(MonoBehaviour): 17 | pass 18 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/MotionFade/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.MotionFade 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismFadeMotionData(MonoBehaviour): 8 | MotionName : str 9 | ModelFadeInTime : float 10 | ModelFadeOutTime : float 11 | FadeInTime : float 12 | FadeOutTime : float 13 | ParameterIds : List[str] 14 | ParameterCurves : List[AnimationCurve] 15 | ParameterFadeInTimes : List[float] 16 | ParameterFadeOutTimes : List[float] 17 | MotionLength : float 18 | @typetree_defined 19 | class CubismFadeMotionList(MonoBehaviour): 20 | MotionInstanceIds : List[int] 21 | CubismFadeMotionObjects : List[PPtr[CubismFadeMotionData]] 22 | @typetree_defined 23 | class CubismFadeController(MonoBehaviour): 24 | CubismFadeMotionList : PPtr[CubismFadeMotionList] 25 | @typetree_defined 26 | class CubismFadeCurveType(MonoBehaviour): 27 | value__ : int 28 | @typetree_defined 29 | class CubismFadeMath(MonoBehaviour): 30 | pass 31 | @typetree_defined 32 | class CubismFadePlayingMotion(MonoBehaviour): 33 | StartTime : float 34 | EndTime : float 35 | FadeInStartTime : float 36 | Speed : float 37 | Motion : PPtr[CubismFadeMotionData] 38 | IsLooping : bool 39 | @typetree_defined 40 | class CubismFadeStateObserver(MonoBehaviour): 41 | pass 42 | @typetree_defined 43 | class ICubismFadeState(MonoBehaviour): 44 | pass 45 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/MouthMovement/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.MouthMovement 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismAudioMouthInput(MonoBehaviour): 8 | AudioInput : PPtr[AudioSource] 9 | SamplingQuality : int 10 | Gain : float 11 | Smoothing : float 12 | @typetree_defined 13 | class CubismAudioSamplingQuality(MonoBehaviour): 14 | value__ : int 15 | @typetree_defined 16 | class CubismAutoMouthInput(MonoBehaviour): 17 | Timescale : float 18 | @typetree_defined 19 | class CubismMouthController(MonoBehaviour): 20 | BlendMode : int 21 | MouthOpening : float 22 | @typetree_defined 23 | class CubismMouthParameter(MonoBehaviour): 24 | pass 25 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Physics/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Physics 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismPhysics(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class CubismPhysicsInput(MonoBehaviour): 11 | SourceId : str 12 | ScaleOfTranslation : Vector2f 13 | AngleScale : float 14 | Weight : float 15 | SourceComponent : int 16 | IsInverted : bool 17 | @typetree_defined 18 | class CubismPhysicsNormalizationTuplet(MonoBehaviour): 19 | Maximum : float 20 | Minimum : float 21 | Default : float 22 | @typetree_defined 23 | class CubismPhysicsNormalization(MonoBehaviour): 24 | Position : CubismPhysicsNormalizationTuplet 25 | Angle : CubismPhysicsNormalizationTuplet 26 | @typetree_defined 27 | class CubismPhysicsOutput(MonoBehaviour): 28 | DestinationId : str 29 | ParticleIndex : int 30 | TranslationScale : Vector2f 31 | AngleScale : float 32 | Weight : float 33 | SourceComponent : int 34 | IsInverted : bool 35 | @typetree_defined 36 | class CubismPhysicsParticle(MonoBehaviour): 37 | InitialPosition : Vector2f 38 | Mobility : float 39 | Delay : float 40 | Acceleration : float 41 | Radius : float 42 | @typetree_defined 43 | class CubismPhysicsSubRig(MonoBehaviour): 44 | Name : str 45 | Input : List[CubismPhysicsInput] 46 | Output : List[CubismPhysicsOutput] 47 | Particles : List[CubismPhysicsParticle] 48 | Normalization : CubismPhysicsNormalization 49 | @typetree_defined 50 | class CubismPhysicsRig(MonoBehaviour): 51 | SubRigs : List[CubismPhysicsSubRig] 52 | Gravity : Vector2f 53 | Wind : Vector2f 54 | Fps : float 55 | @typetree_defined 56 | class CubismPhysicsController(MonoBehaviour): 57 | _rig : CubismPhysicsRig 58 | @typetree_defined 59 | class CubismPhysicsMath(MonoBehaviour): 60 | pass 61 | @typetree_defined 62 | class CubismPhysicsSourceComponent(MonoBehaviour): 63 | value__ : int 64 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Pose/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Pose 3 | 4 | from ..... import * 5 | from .....Live2D.Cubism.Core import CubismPart 6 | 7 | @typetree_defined 8 | class CubismPoseController(MonoBehaviour): 9 | defaultPoseIndex : int 10 | @typetree_defined 11 | class CubismPosePart(MonoBehaviour): 12 | GroupIndex : int 13 | PartIndex : int 14 | Link : List[str] 15 | @typetree_defined 16 | class CubismPoseData(MonoBehaviour): 17 | PosePart : PPtr[CubismPosePart] 18 | Part : PPtr[CubismPart] 19 | LinkParts : List[PPtr[CubismPart]] 20 | Opacity : float 21 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Raycasting/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Raycasting 3 | 4 | from ..... import * 5 | from .....Live2D.Cubism.Core import CubismDrawable 6 | 7 | @typetree_defined 8 | class CubismRaycastable(MonoBehaviour): 9 | Precision : int 10 | @typetree_defined 11 | class CubismRaycastablePrecision(MonoBehaviour): 12 | value__ : int 13 | @typetree_defined 14 | class CubismRaycaster(MonoBehaviour): 15 | pass 16 | @typetree_defined 17 | class CubismRaycastHit(MonoBehaviour): 18 | Drawable : PPtr[CubismDrawable] 19 | Distance : float 20 | LocalPosition : Vector3f 21 | WorldPosition : Vector3f 22 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Tasking/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Tasking 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismBuiltinAsyncTaskHandler(MonoBehaviour): 8 | pass 9 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/UserData/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.UserData 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismUserDataBody(MonoBehaviour): 8 | Id : str 9 | Value : str 10 | @typetree_defined 11 | class CubismUserDataTag(MonoBehaviour): 12 | _value : str 13 | _body : CubismUserDataBody 14 | @typetree_defined 15 | class CubismUserDataTargetType(MonoBehaviour): 16 | value__ : int 17 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/Utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework.Utils 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismMath(MonoBehaviour): 8 | pass 9 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Framework/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Framework 3 | 4 | from .... import * 5 | 6 | @typetree_defined 7 | class ComponentExtensionMethods(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class CubismAutoEyeBlinkInput(MonoBehaviour): 11 | Mean : float 12 | MaximumDeviation : float 13 | Timescale : float 14 | @typetree_defined 15 | class CubismDisplayInfoParameterName(MonoBehaviour): 16 | Name : str 17 | DisplayName : str 18 | @typetree_defined 19 | class CubismDisplayInfoPartName(MonoBehaviour): 20 | Name : str 21 | DisplayName : str 22 | @typetree_defined 23 | class CubismDontMoveOnReimportAttribute(MonoBehaviour): 24 | pass 25 | @typetree_defined 26 | class CubismEyeBlinkController(MonoBehaviour): 27 | BlendMode : int 28 | EyeOpening : float 29 | @typetree_defined 30 | class CubismEyeBlinkParameter(MonoBehaviour): 31 | pass 32 | @typetree_defined 33 | class CubismHitDrawable(MonoBehaviour): 34 | Name : str 35 | @typetree_defined 36 | class CubismMoveOnReimportCopyComponentsOnly(MonoBehaviour): 37 | pass 38 | @typetree_defined 39 | class CubismParameterBlendMode(MonoBehaviour): 40 | value__ : int 41 | @typetree_defined 42 | class CubismParameterExtensionMethods(MonoBehaviour): 43 | pass 44 | @typetree_defined 45 | class CubismParametersInspector(MonoBehaviour): 46 | pass 47 | @typetree_defined 48 | class CubismParameterStore(MonoBehaviour): 49 | pass 50 | @typetree_defined 51 | class CubismPartsInspector(MonoBehaviour): 52 | pass 53 | @typetree_defined 54 | class CubismUpdateController(MonoBehaviour): 55 | pass 56 | @typetree_defined 57 | class CubismUpdateExecutionOrder(MonoBehaviour): 58 | pass 59 | @typetree_defined 60 | class ICubismUpdatable(MonoBehaviour): 61 | pass 62 | @typetree_defined 63 | class ObjectExtensionMethods(MonoBehaviour): 64 | pass 65 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Garage/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Garage 3 | 4 | from .... import * 5 | 6 | @typetree_defined 7 | class CheckMaskLimit(MonoBehaviour): 8 | _clipping : PPtr[GameObject] 9 | _prefabCounter : PPtr[object] # XXX: Fallback of PPtr 10 | _maskCounter : PPtr[object] # XXX: Fallback of PPtr 11 | _size : float 12 | @typetree_defined 13 | class CubismCollisionDetection(MonoBehaviour): 14 | _text : PPtr[object] # XXX: Fallback of PPtr 15 | @typetree_defined 16 | class CubismFollowing(MonoBehaviour): 17 | _target : PPtr[Transform] 18 | _offset : Vector3f 19 | @typetree_defined 20 | class CubismFollowingCollider(MonoBehaviour): 21 | pass 22 | @typetree_defined 23 | class CubismSetTextures(MonoBehaviour): 24 | pass 25 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Rendering/Masking/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Rendering.Masking 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class CubismMaskCommandBuffer(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class CubismMaskTexture(MonoBehaviour): 11 | _size : int 12 | _subdivisions : int 13 | _renderTextureCount : int 14 | @typetree_defined 15 | class CubismMaskController(MonoBehaviour): 16 | _maskTexture : PPtr[CubismMaskTexture] 17 | @typetree_defined 18 | class CubismMaskMaskedJunction(MonoBehaviour): 19 | pass 20 | @typetree_defined 21 | class CubismMaskProperties(MonoBehaviour): 22 | Texture : PPtr[CubismMaskTexture] 23 | @typetree_defined 24 | class CubismMaskRenderer(MonoBehaviour): 25 | pass 26 | @typetree_defined 27 | class CubismMaskRendererExtensionMethods(MonoBehaviour): 28 | pass 29 | @typetree_defined 30 | class CubismMaskTile(MonoBehaviour): 31 | Channel : float 32 | Column : float 33 | Row : float 34 | Size : float 35 | RenderTextureIndex : int 36 | HeadOfChannelsIndex : int 37 | Index : int 38 | @typetree_defined 39 | class CubismMaskTilePool(MonoBehaviour): 40 | pass 41 | @typetree_defined 42 | class CubismMaskTransform(MonoBehaviour): 43 | Offset : Vector2f 44 | Scale : float 45 | @typetree_defined 46 | class ICubismMaskCommandSource(MonoBehaviour): 47 | pass 48 | @typetree_defined 49 | class ICubismMaskTextureCommandSource(MonoBehaviour): 50 | pass 51 | @typetree_defined 52 | class IntExtensionMethods(MonoBehaviour): 53 | pass 54 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Rendering/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Rendering 3 | 4 | from .... import * 5 | 6 | @typetree_defined 7 | class ArrayExtensionMethods(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class CubismBuiltinMaterials(MonoBehaviour): 11 | pass 12 | @typetree_defined 13 | class CubismBuiltinShaders(MonoBehaviour): 14 | pass 15 | @typetree_defined 16 | class CubismRenderer(MonoBehaviour): 17 | _localSortingOrder : int 18 | _color : ColorRGBA 19 | _isOverwrittenDrawableMultiplyColors : bool 20 | _isOverwrittenDrawableScreenColors : bool 21 | _multiplyColor : ColorRGBA 22 | _screenColor : ColorRGBA 23 | _mainTexture : PPtr[Texture2D] 24 | _sortingMode : int 25 | _sortingOrder : int 26 | _renderOrder : int 27 | _depthOffset : float 28 | _opacity : float 29 | @typetree_defined 30 | class CubismPartColorsEditor(MonoBehaviour): 31 | _childDrawableRenderers : List[PPtr[CubismRenderer]] 32 | _childParts : List[PPtr["CubismPartColorsEditor"]] 33 | _isOverwrittenPartMultiplyColors : bool 34 | _isOverwrittenPartScreenColors : bool 35 | _multiplyColor : ColorRGBA 36 | _screenColor : ColorRGBA 37 | @typetree_defined 38 | class CubismRenderController(MonoBehaviour): 39 | Opacity : float 40 | _lastOpacity : float 41 | _isOverwrittenModelMultiplyColors : bool 42 | _isOverwrittenModelScreenColors : bool 43 | _modelMultiplyColor : ColorRGBA 44 | _modelScreenColor : ColorRGBA 45 | _sortingLayerId : int 46 | _sortingMode : int 47 | _sortingOrder : int 48 | CameraToFace : PPtr[Camera] 49 | _drawOrderHandler : PPtr[Object] 50 | _opacityHandler : PPtr[Object] 51 | _multiplyColorHandler : PPtr[Object] 52 | _screenColorHandler : PPtr[Object] 53 | _depthOffset : float 54 | @typetree_defined 55 | class CubismShaderVariables(MonoBehaviour): 56 | pass 57 | @typetree_defined 58 | class CubismSortingMode(MonoBehaviour): 59 | value__ : int 60 | @typetree_defined 61 | class CubismSortingModeExtensionMethods(MonoBehaviour): 62 | pass 63 | @typetree_defined 64 | class ICubismBlendColorHandler(MonoBehaviour): 65 | pass 66 | @typetree_defined 67 | class ICubismDrawOrderHandler(MonoBehaviour): 68 | pass 69 | @typetree_defined 70 | class ICubismOpacityHandler(MonoBehaviour): 71 | pass 72 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/AsyncBenchmark/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.AsyncBenchmark 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class AsyncToggler(MonoBehaviour): 8 | EnableAsync : bool 9 | @typetree_defined 10 | class BenchmarkController(MonoBehaviour): 11 | TargetFrameRate : int 12 | ReachedElapsedTimeUi : PPtr[object] # XXX: Fallback of PPtr 13 | InstancesCountUi : PPtr[object] # XXX: Fallback of PPtr 14 | @typetree_defined 15 | class FpsCounter(MonoBehaviour): 16 | FpsUi : PPtr[object] # XXX: Fallback of PPtr 17 | @typetree_defined 18 | class FrameRateMeasurer(MonoBehaviour): 19 | TargetFrameRate : int 20 | @typetree_defined 21 | class FrameRateUiHolder(MonoBehaviour): 22 | HasShownFrameRate : bool 23 | HasShownElapsedTime : bool 24 | HighestFrameRateUi : PPtr[object] # XXX: Fallback of PPtr 25 | LowestFrameRateUi : PPtr[object] # XXX: Fallback of PPtr 26 | ElapsedTimeUi : PPtr[object] # XXX: Fallback of PPtr 27 | @typetree_defined 28 | class ModelSpawner(MonoBehaviour): 29 | ModelPrefab : PPtr[GameObject] 30 | ModelCountUi : PPtr[object] # XXX: Fallback of PPtr 31 | @typetree_defined 32 | class TotalElapsedTime(MonoBehaviour): 33 | ElapsedTime : int 34 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/LookAt/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.LookAt 3 | 4 | from ..... import * 5 | 6 | @typetree_defined 7 | class Billboarder(MonoBehaviour): 8 | CameraToFace : PPtr[Camera] 9 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/Masking/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.Masking 3 | 4 | from ..... import * 5 | from .....Live2D.Cubism.Rendering.Masking import CubismMaskTexture 6 | 7 | @typetree_defined 8 | class MaskTexturePreview(MonoBehaviour): 9 | MaskTexture : PPtr[CubismMaskTexture] 10 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/OriginalWorkflow/Demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.OriginalWorkflow.Demo 3 | 4 | from ...... import * 5 | 6 | @typetree_defined 7 | class CubismLookTarget(MonoBehaviour): 8 | pass 9 | @typetree_defined 10 | class CubismSampleController(MonoBehaviour): 11 | _bodyAnimation : PPtr[AnimationClip] 12 | _tapBodyMotions : List[PPtr[AnimationClip]] 13 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/OriginalWorkflow/Expression/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.OriginalWorkflow.Expression 3 | 4 | from ...... import * 5 | 6 | @typetree_defined 7 | class CubismExpressionPreview(MonoBehaviour): 8 | pass 9 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/OriginalWorkflow/Motion/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.OriginalWorkflow.Motion 3 | 4 | from ...... import * 5 | 6 | @typetree_defined 7 | class CubismMotionPreview(MonoBehaviour): 8 | Animation : PPtr[AnimationClip] 9 | -------------------------------------------------------------------------------- /UnityPyLive2DExtractor/generated/Live2D/Cubism/Samples/Raycasting/__init__.py: -------------------------------------------------------------------------------- 1 | # Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py 2 | # Python definition for Live2D.Cubism.Samples.Raycasting 3 | 4 | from ..... import * 5 | from .....Live2D.Cubism.Core import CubismModel 6 | 7 | @typetree_defined 8 | class RaycastHitDisplay(MonoBehaviour): 9 | Model : PPtr[CubismModel] 10 | ResultsText : PPtr[object] # XXX: Fallback of PPtr 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | 3 | sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) 4 | import setuptools, UnityPyLive2DExtractor 5 | 6 | with open("README.md", "r", encoding="utf-8") as fh: 7 | long_description = fh.read() 8 | 9 | setuptools.setup( 10 | name="UnityPyLive2DExtractor", 11 | version="%d.%d.%d" % UnityPyLive2DExtractor.__version__, 12 | author="greats3an", 13 | author_email="greats3an@gmail.com", 14 | description="General purpose, single-file Unity Live2D Asset recovery tool", 15 | long_description=long_description, 16 | long_description_content_type="text/markdown", 17 | url="https://github.com/mos9527/UnityPyLive2DExtractor", 18 | packages=setuptools.find_packages(), 19 | classifiers=[ 20 | "Programming Language :: Python :: 3", 21 | "License :: OSI Approved :: Apache Software License", 22 | "Operating System :: OS Independent", 23 | ], 24 | install_requires=["sssekai>=0.7.12"], 25 | entry_points={ 26 | "console_scripts": [ 27 | "UnityPyLive2DExtractor = UnityPyLive2DExtractor.__main__:__main__" 28 | ] 29 | }, 30 | python_requires=">=3.10", 31 | ) 32 | -------------------------------------------------------------------------------- /typetree_codegen.py: -------------------------------------------------------------------------------- 1 | """Simple codegen for typetree classes 2 | 3 | - Supports nested types 4 | - Supports inheritance 5 | - Automatically resolves import order and dependencies 6 | - Generated classes support nested types, and will be initialized with the correct types even with nested dicts 7 | 8 | NOTE: 9 | - Cannot resolve namespace conflicts if the same class name is defined in multiple namespaces 10 | - Missing type definitions are marked with # XXX: Fallback of {org_type} and typedefed as object 11 | - Circular inheritance is checked and raises RecursionError 12 | - The output order (imports, classes) are deterministic and lexicographically sorted 13 | - The output is emitted in lieu of the Namespace structure of the TypeTree dump, presented as Python modules in directories 14 | 15 | USAGE: 16 | 17 | python typetree_codegen.py 18 | """ 19 | 20 | # From https://github.com/K0lb3/UnityPy/blob/master/generators/ClassesGenerator.py 21 | BASE_TYPE_MAP = { 22 | "char": "str", 23 | "short": "int", 24 | "int": "int", 25 | "long long": "int", 26 | "unsigned short": "int", 27 | "unsigned int": "int", 28 | "unsigned long long": "int", 29 | "UInt8": "int", 30 | "UInt16": "int", 31 | "UInt32": "int", 32 | "UInt64": "int", 33 | "SInt8": "int", 34 | "SInt16": "int", 35 | "SInt32": "int", 36 | "SInt64": "int", 37 | "Type*": "int", 38 | "FileSize": "int", 39 | "float": "float", 40 | "double": "float", 41 | "bool": "bool", 42 | "string": "str", 43 | "TypelessData": "bytes", 44 | # -- Extra 45 | "Byte[]": "bytes", 46 | "Byte": "int", 47 | "String": "str", 48 | "Int32": "int", 49 | "Single": "float", 50 | "Color": "ColorRGBA", 51 | "Vector2": "Vector2f", 52 | "Vector3": "Vector3f", 53 | "Vector4": "Vector4f", 54 | } 55 | # XXX: Can't use attrs here since subclassing MonoBehavior and such - though defined by the typetree dump 56 | # seem to be only valid if the class isn't a property of another class 57 | # In which case the MonoBehavior attributes are inherited by the parent class and does not 58 | # initialize the property class 59 | # XXX: Need some boilerplate to handle this 60 | HEADER = "\n".join( 61 | [ 62 | "# fmt: off", 63 | "# Auto-generated by https://github.com/mos9527/UnityPyLive2DExtractor/tree/main/UnityPyLive2DExtractor/typetree_codegen.py", 64 | "" "from typing import List, Union, Optional, TypeVar", 65 | "from UnityPy.classes import *", 66 | "from UnityPy.classes.math import (ColorRGBA, Matrix3x4f, Matrix4x4f, Quaternionf, Vector2f, Vector3f, Vector4f, float3, float4,)", 67 | '''T = TypeVar("T") 68 | def typetree_defined(clazz : T) -> T: 69 | """dataclass-like decorator for typetree classess with nested type support 70 | 71 | limitations: 72 | - the behavior is similar to slotted dataclasses where shared attributes are inherited 73 | but allows ommiting init of the parent if kwargs are not sufficient 74 | - generally supports nested types, however untested and could be slow 75 | - and ofc, zero type checking and safeguards :/ 76 | """ 77 | RESERVED_KWS = {'object_reader'} 78 | # Allow these to be propogated to the props 79 | def __init__(self, **d): 80 | def enusre_reserved(obj): 81 | for k in RESERVED_KWS: 82 | if hasattr(obj, k) and k in d: 83 | setattr(obj, k, d[k]) 84 | return obj 85 | def reduce_init(clazz, **d): 86 | types : dict = clazz.__annotations__ 87 | for k, sub in types.items(): 88 | if type(sub) == str: 89 | sub = eval(sub) # attrs turns these into strings...why? 90 | reduce_arg = getattr(sub, "__args__", [None])[0] 91 | if isinstance(d[k], list): 92 | if hasattr(reduce_arg, "__annotations__") or hasattr(reduce_arg, "__args__"): 93 | setattr(self, k, [enusre_reserved(reduce_arg(**x)) for x in d[k]]) 94 | else: 95 | setattr(self, k, [enusre_reserved(reduce_arg(x)) for x in d[k]]) 96 | elif isinstance(d[k], dict) and hasattr(sub, "__annotations__"): 97 | setattr(self, k, enusre_reserved(sub(**d[k]))) 98 | else: 99 | if isinstance(d[k], dict): 100 | setattr(self, k, enusre_reserved(sub(**d[k]))) 101 | else: 102 | setattr(self, k, enusre_reserved(sub(d[k]))) 103 | for __base__ in clazz.__bases__: 104 | types : dict = __base__.__annotations__ 105 | args = {k:d[k] for k in types if k in d} 106 | if len(args) == len(types): 107 | super(clazz, self).__init__(**args) 108 | reduce_init(__base__, **d) 109 | for k in args: 110 | if not k in RESERVED_KWS: del d[k] 111 | reduce_init(clazz, **d) 112 | enusre_reserved(self) 113 | def __repr__(self) -> str: 114 | return f"{clazz.__name__}({', '.join([f'{k}={getattr(self, k)!r}' for k in self.__annotations__])})" 115 | clazz.__init__ = __init__ 116 | clazz.__repr__ = __repr__ 117 | return clazz 118 | ''', 119 | ] 120 | ) 121 | from collections import defaultdict 122 | from dataclasses import dataclass 123 | import argparse, json 124 | 125 | 126 | @dataclass 127 | class CodegenFlags: 128 | pass 129 | 130 | 131 | FLAGS = CodegenFlags() 132 | 133 | 134 | def translate_name(m_Name: str, **kwargs): 135 | m_Name = m_Name.replace("<>", "__generic_") # Generic templates 136 | m_Name = m_Name.replace("<", "_").replace(">", "_") # Templated 137 | m_Name = m_Name.replace("=", "_") # Special chars 138 | return m_Name 139 | 140 | 141 | from UnityPy import classes 142 | from logging import getLogger 143 | from coloredlogs import install 144 | 145 | logger = getLogger("codegen") 146 | 147 | 148 | def translate_type( 149 | m_Type: str, 150 | strip=False, 151 | fallback=True, 152 | typenames: dict = dict(), 153 | parent: str = "", 154 | **kwargs, 155 | ): 156 | if m_Type in BASE_TYPE_MAP: 157 | return BASE_TYPE_MAP[m_Type] 158 | if getattr(classes, m_Type, None): 159 | return m_Type 160 | if m_Type in typenames: 161 | if m_Type == parent: 162 | return f'"{m_Type}"' 163 | else: 164 | return m_Type 165 | if m_Type.endswith("[]"): 166 | m_Type = translate_type(m_Type[:-2], strip, fallback, typenames, parent) 167 | if not strip: 168 | return f"List[{m_Type}]" 169 | else: 170 | return m_Type 171 | if m_Type.startswith("PPtr<"): 172 | m_Type = translate_type(m_Type[5:-1], strip, fallback, typenames, parent) 173 | if not strip: 174 | return f"PPtr[{m_Type}]" 175 | else: 176 | return m_Type 177 | if fallback: 178 | logger.warning(f"Unknown type {m_Type}, using fallback") 179 | return "object" 180 | else: 181 | if m_Type == parent: 182 | return f'"{m_Type}"' 183 | else: 184 | return m_Type 185 | 186 | 187 | def declare_field(name: str, type: str, org_type: str = None): 188 | if type not in {"object", "List[object]", "PPtr[object]"}: 189 | return f"{name} : {type}" 190 | else: 191 | return f"{name} : {type} # XXX: Fallback of {org_type}" 192 | 193 | 194 | from io import TextIOWrapper 195 | 196 | 197 | def topsort(graph: dict): 198 | # Sort the keys in topological order 199 | # We don't assume the guarantee otherwise 200 | graph = {k: list(sorted(v)) for k, v in graph.items()} 201 | vis = defaultdict(lambda: 0) 202 | topo = list() 203 | 204 | def dfs(u): 205 | vis[u] = 1 206 | for v in graph.get(u, []): 207 | if vis[v] == 1: 208 | return False 209 | if vis[v] == 0 and not dfs(v): 210 | return False 211 | vis[u] = 2 212 | topo.append(u) 213 | return True 214 | 215 | flag = 1 216 | for clazz in graph: 217 | if not vis[clazz]: 218 | flag &= dfs(clazz) 219 | assert flag, "circular dependency detected. bogus typetree dump" 220 | return topo 221 | 222 | 223 | def process_namespace( 224 | namespace: str, 225 | typetree_defs: dict, 226 | f: TextIOWrapper, 227 | import_root: str = "", 228 | import_defs: dict = dict(), 229 | ): 230 | def emit_line(*lines: str): 231 | for line in lines: 232 | f.write(line) 233 | f.write("\n") 234 | if not lines: 235 | f.write("\n") 236 | 237 | namespace = namespace or "" 238 | logger.info(f"Subpass 1: Generating class dependency graph for {namespace}") 239 | emit_line("# Auto-generated by UnityPyLive2DExtractor/typetree_codegen.py") 240 | emit_line(f"# Python definition for {namespace}", "") 241 | if import_root: 242 | emit_line(f"from {import_root} import *") 243 | for clazz, parent in import_defs.items(): 244 | emit_line(f"from {import_root or '.'}{parent or ''} import {clazz}") 245 | 246 | emit_line() 247 | # Emit by topo order 248 | graph = { 249 | clazz: { 250 | translate_type(field["m_Type"], strip=True, fallback=False) 251 | for field in fields 252 | # Don't care about built-ins 253 | } 254 | for clazz, fields in typetree_defs.items() 255 | } 256 | for u, vs in graph.items(): 257 | # This is circular - but allowed 258 | # We can have a class that references itself 259 | if u in vs: 260 | vs.remove(u) 261 | topo = topsort(graph) 262 | clazzes = list() 263 | 264 | logger.info(f"Subpass 2: Generating code for {namespace}") 265 | dp = defaultdict(lambda: -1) 266 | for clazz in topo: 267 | fields = typetree_defs.get(clazz, None) 268 | if not fields: 269 | logger.debug( 270 | f"Class {clazz} has no fields defined in TypeTree dump, skipped" 271 | ) 272 | continue 273 | 274 | def deduce_type(i: int): 275 | # XXX: Upstream needs to fix this 276 | if fields[i]["m_Type"].endswith("[]"): 277 | assert fields[i + 1]["m_Type"] == "Array" 278 | return fields[i + 3]["m_Type"] + "[]" 279 | else: 280 | return fields[i]["m_Type"] 281 | 282 | # Heuristic: If there is a lvl1 field, it's a subclass 283 | lvl1 = list(filter(lambda field: field["m_Level"] == 1, fields)) 284 | clazz = translate_name(clazz) 285 | clazzes.append(clazz) 286 | clazz_fields = list() 287 | emit_line(f"@typetree_defined") 288 | if lvl1: 289 | parent = translate_type(fields[0]["m_Type"], strip=True, fallback=False) 290 | emit_line(f"class {clazz}({parent}):") 291 | # Generated typedefs are guaranteed to be flat in hierarchy 292 | # Recursive ones are defined by previous/topo order 293 | if dp[parent] == -1: 294 | # Reuse parent's fields with best possible effort 295 | # This is a heuristic and may not be correct 296 | if pa_dep1 := getattr(classes, parent, None): 297 | dp[parent] = len(pa_dep1.__annotations__) 298 | else: 299 | raise RecursionError("Circular inheritance detected") 300 | pa_dep1 = dp[parent] 301 | cur_dep1 = pa_dep1 302 | for nth, (i, field) in enumerate( 303 | filter(lambda x: x[1]["m_Level"] == 1, enumerate(fields)) 304 | ): 305 | if nth < pa_dep1: 306 | # Skip parent fields at lvl1 307 | continue 308 | raw_type = deduce_type(i) 309 | name, type = field["m_Name"], translate_type( 310 | raw_type, typenames=typetree_defs | import_defs, parent=clazz 311 | ) 312 | emit_line(f"\t{declare_field(name, type, raw_type)}") 313 | clazz_fields.append((name, type, raw_type)) 314 | cur_dep1 += 1 315 | dp[clazz] = cur_dep1 316 | else: 317 | # No inheritance 318 | emit_line(f"class {clazz}:") 319 | for i, field in enumerate(fields): 320 | raw_type = deduce_type(i) 321 | name, type = field["m_Name"], translate_type( 322 | raw_type, typenames=typetree_defs | import_defs, parent=clazz 323 | ) 324 | emit_line(f"\t{declare_field(name, type, raw_type)}") 325 | clazz_fields.append((name, type)) 326 | if not clazz_fields: 327 | # Empty class. Consider MRO 328 | emit_line("\tpass") 329 | 330 | 331 | import os, shutil 332 | from typing import Dict 333 | 334 | 335 | def __main__(): 336 | parser = argparse.ArgumentParser() 337 | parser.add_argument( 338 | "infile", 339 | type=str, 340 | help="Input TypeTree Dump in JSON format. Dump with https://github.com/K0lb3/TypeTreeGenerator", 341 | ) 342 | parser.add_argument("outdir", type=str, help="Output directory") 343 | parser.add_argument("--log-level", default="INFO", help="Set logging level") 344 | args = parser.parse_args() 345 | install(level=args.log_level) 346 | 347 | shutil.rmtree(args.outdir, ignore_errors=True) 348 | logger.info(f"Reading from {args.infile}") 349 | TYPETREE_DEFS = json.load(open(args.infile, "r")) 350 | namespaces = defaultdict(dict) 351 | namespacesT = defaultdict(None) 352 | logger.info("Pass 1: Building namespace") 353 | for key in TYPETREE_DEFS: 354 | fullkey = key.split(".") 355 | if len(fullkey) == 1: 356 | namespace, clazz = None, fullkey[0] 357 | else: 358 | namespace, clazz = fullkey[:-1], fullkey[-1] 359 | namespace = ".".join(namespace) 360 | namespaces[namespace][clazz] = TYPETREE_DEFS[key] 361 | if clazz not in namespacesT: 362 | namespacesT[clazz] = namespace 363 | else: 364 | logger.error( 365 | f"Class {clazz} already defined in {namespacesT[clazz]} but found again in {namespace}" 366 | ) 367 | logger.error( 368 | f"Need manual intervention to resolve the conflict. Using first definition for now." 369 | ) 370 | logger.info("Pass 2: Generating import graph") 371 | # Build import graph 372 | namespaceDeps = defaultdict(set) 373 | for namespace, typetree_defs in namespaces.items(): 374 | for clazz, fields in typetree_defs.items(): 375 | for field in fields: 376 | type = translate_type(field["m_Type"], strip=True, fallback=False) 377 | if type in namespacesT and namespacesT[type] != namespace: 378 | namespaceDeps[namespace].add(type) 379 | handles: Dict[str, TextIOWrapper] = dict() 380 | 381 | def __open(fname: str): 382 | fname = os.path.join(args.outdir, fname) 383 | if fname not in handles: 384 | os.makedirs(os.path.dirname(fname), exist_ok=True) 385 | handles[fname] = open(fname, "w") 386 | return handles[fname] 387 | 388 | logger.info("Pass 3: Emitting namespace as Python modules") 389 | __open("__init__.py").write(HEADER) 390 | # XXX: This part can be trivally parallelized 391 | for namespace, typetree_defs in sorted( 392 | namespaces.items(), key=lambda x: x[0].count(".") if x[0] else 0 393 | ): 394 | # CubismTaskHandler -> generated/__init__.py 395 | # Live2D.Cubism.Core.CubismMoc -> generated/Live2D/Cubism/Core/__init__.py 396 | deps = {k: namespacesT[k] for k in namespaceDeps[namespace]} 397 | deps = dict(sorted(deps.items())) 398 | if namespace: 399 | ndots = namespace.count(".") + 2 400 | dotss = "." * ndots 401 | f = __open(os.path.join(*namespace.split("."), "__init__.py")) 402 | process_namespace(namespace, typetree_defs, f, dotss, deps) 403 | else: 404 | f = __open("__init__.py") 405 | process_namespace(namespace, typetree_defs, f, import_defs=deps) 406 | __open("__init__.py").write( 407 | "\nTYPETREE_DEFS = " + json.dumps(TYPETREE_DEFS, indent=4) 408 | ) 409 | logger.info("All done. Going home.") 410 | 411 | 412 | if __name__ == "__main__": 413 | __main__() 414 | --------------------------------------------------------------------------------