Add formal enemies, remaining formal partners and synthesized UI SFX
- UI SFX v3: procedurally synthesized one-shots (Tools/synth_ui_sfx.py) wired to buttons, rewards, errors and red dots via UiSfx, gated by the SFX setting. - Five formal enemies (Hornlet, Dashlet, Shellhorn, HornCaptain, GreatHorn): Hunyuan 50k -> 2000-tri XPbr, DGXA TokenRig, Idle/Walk/Attack, nested per type in PrototypeArena; PrototypeBattle.Enemy gains presentation-only Moving/Strikes. - Formal partners for all ten pets in the arena and portraits, including new VineSprite, ThunderLeopard and TideWhale. - Pipeline fixes: reject local TokenRig fallback, drop loose mesh islands, configurable Unity run_script timeout, companion static stage. - Also includes concurrent work from another tool in this working tree (FlameLion, enemy combat FX, challenge mode, home explorer, server updates). - Resources registered in Doc/ResDesc_*.md; verified on isolated :18081. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
"""Rigidly orient a generated character before baking/rigging, preserving UVs."""
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import bpy
|
||||
from mathutils import Matrix,Vector
|
||||
|
||||
p=argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('source',type=Path);p.add_argument('output',type=Path)
|
||||
p.add_argument('--blender-yaw',type=float,required=True)
|
||||
a=p.parse_args(sys.argv[sys.argv.index('--')+1:])
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.ops.import_scene.gltf(filepath=str(a.source.resolve()))
|
||||
if any(o.type=='ARMATURE' for o in bpy.data.objects):raise ValueError('Orient the static high source before rigging')
|
||||
rotation=Matrix.Rotation(math.radians(a.blender_yaw),4,'Z')
|
||||
roots=[o for o in bpy.context.scene.objects if o.parent is None]
|
||||
for o in roots:o.matrix_world=rotation@o.matrix_world
|
||||
bpy.context.view_layer.update()
|
||||
points=[o.matrix_world@v.co for o in bpy.context.scene.objects if o.type=='MESH' for v in o.data.vertices]
|
||||
mn=Vector([min(p[c] for p in points) for c in range(3)]);mx=Vector([max(p[c] for p in points) for c in range(3)])
|
||||
offset=Matrix.Translation(-Vector(((mn.x+mx.x)/2,(mn.y+mx.y)/2,mn.z)))
|
||||
for o in roots:o.matrix_world=offset@o.matrix_world
|
||||
a.output.parent.mkdir(parents=True,exist_ok=True)
|
||||
bpy.ops.export_scene.gltf(filepath=str(a.output.resolve()),export_format='GLB')
|
||||
record=dict(source=str(a.source),output=str(a.output),blender_yaw_degrees=a.blender_yaw,orientation_note='Verify final forward in Unity views: FBX handedness conversion must be included.',height=mx.z-mn.z,mesh_unchanged_except_rigid_transform=True)
|
||||
a.output.with_suffix('.orientation.json').write_text(json.dumps(record,indent=2),encoding='utf-8')
|
||||
print(json.dumps(record))
|
||||
Reference in New Issue
Block a user