unitytk 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unitytk-0.2.2/unitytk.egg-info → unitytk-0.3.0}/PKG-INFO +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_articulated_rig_runtime.py +2 -4
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_audio_events_integration.py +3 -3
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_base_test.py +78 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_blender_render_effects_e2e.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_blender_shadow_plane_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_blender_shot_metadata_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_clip_name_contract_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_controller_runtime_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_deploy_templates.py +99 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_embedded_dependencies_integration.py +2 -2
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_emissive_groups_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_fade_window_preservation.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_keyed_visibility.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_lightmap_metadata_integration.py +852 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_maya_surface_materials_integration.py +120 -62
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_multi_section_audio_integration.py +2 -2
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_render_effects_e2e.py +2 -2
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_render_opacity_controller.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_render_opacity_e2e.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_render_opacity_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_shadow_plane_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_shadow_plane_runtime_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_shared_material_standalone.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_shot_metadata_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_shots_audio_sidebyside_integration.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_standalone_enduser.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_temp_projects.py +26 -3
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/__init__.py +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/AudioEvent/AudioEventController.cs +49 -4
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup/EmissiveGroupsLit.shader +36 -1
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableCubeUV.hlsl +119 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableCubeUV.hlsl.meta +7 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableLit.shader +373 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableLit.shader.meta +9 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverablePmrem.cs +307 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverablePmrem.cs.meta +11 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableShading.cs +460 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableShading.cs.meta +11 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableToneMap.shader +65 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableToneMap.shader.meta +9 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableToneMapFeature.cs +53 -0
- unitytk-0.3.0/unitytk/templates/LightmapMetadata/DeliverableToneMapFeature.cs.meta +11 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/LightmapMetadata/LightmapMetadataController.cs +496 -48
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/M3trik.Unitytk.asmdef +8 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/MayaSurface/MayaSurfaceMaterialImporter.cs +69 -16
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/README.md +68 -26
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane/ShadowPlaneController.cs +19 -16
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/UnitytkSettings.cs +80 -15
- {unitytk-0.2.2 → unitytk-0.3.0/unitytk.egg-info}/PKG-INFO +1 -1
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk.egg-info/SOURCES.txt +12 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/LICENSE +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/MANIFEST.in +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/docs/README.md +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/pyproject.toml +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/setup.cfg +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_asset_delivery.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_bool_to_fade_curve.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_launcher.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_run_tests.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/test/test_scene_builder.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/asset_delivery.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/launcher.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/scene_builder.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/template_deployer.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/ArticulatedRigController.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/ArticulatedRigController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/ArticulatedRigPointerGrab.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/ArticulatedRigPointerGrab.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/ArticulationRecord.g.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/ArticulationRecord.g.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR/ArticulatedRigXRGrab.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR/ArticulatedRigXRGrab.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR/ArticulatedRigXRSetup.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR/ArticulatedRigXRSetup.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR/M3trik.Unitytk.XR.asmdef +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR/M3trik.Unitytk.XR.asmdef.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig/XR.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ArticulatedRig.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/AudioEvent/AudioEventController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/AudioEvent.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup/EmissiveGroupController.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup/EmissiveGroupController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup/EmissiveGroups.hlsl +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup/EmissiveGroups.hlsl.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup/EmissiveGroupsLit.shader.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/EmissiveGroup.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/LightmapMetadata/LightmapMetadataController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/LightmapMetadata.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/M3trik.Unitytk.asmdef.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/MayaSurface/MayaSurfaceMaterialImporter.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/MayaSurface.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/README.md.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/RenderEffects/RenderEffectsController.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/RenderEffects/RenderEffectsController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/RenderEffects.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane/ShadowPlane.shader +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane/ShadowPlane.shader.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane/ShadowPlaneController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane/ShadowPlaneHorizon.hlsl +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane/ShadowPlaneHorizon.hlsl.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShadowPlane.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShotMetadata/ShotMetadataController.cs +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShotMetadata/ShotMetadataController.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/ShotMetadata.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/UnitytkSettings.cs.meta +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk/templates/__init__.py +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk.egg-info/dependency_links.txt +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk.egg-info/requires.txt +0 -0
- {unitytk-0.2.2 → unitytk-0.3.0}/unitytk.egg-info/top_level.txt +0 -0
|
@@ -1671,7 +1671,7 @@ def _run_unity(test, temp_dir, execute_method, prepare, timeout=600):
|
|
|
1671
1671
|
verifier; returns the parsed results (or skips on the license wall)."""
|
|
1672
1672
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
1673
1673
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
1674
|
-
project_path =
|
|
1674
|
+
project_path = TempProjects.project(temp_dir)
|
|
1675
1675
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
1676
1676
|
test.skipTest(UnityEnv.project_creation_reason())
|
|
1677
1677
|
results_path = os.path.join(temp_dir, "unity_results.json")
|
|
@@ -1865,9 +1865,7 @@ class TestArticulatedRigRuntime(unittest.TestCase):
|
|
|
1865
1865
|
for name in _bundle_assets()
|
|
1866
1866
|
}
|
|
1867
1867
|
self.assertEqual(got, expected, "Unity named a deployed asset differently")
|
|
1868
|
-
package = TemplateDeployer.package_dir(
|
|
1869
|
-
os.path.join(self.temp_dir, "UnityProject")
|
|
1870
|
-
)
|
|
1868
|
+
package = TemplateDeployer.package_dir(TempProjects.project(self.temp_dir))
|
|
1871
1869
|
rewritten = []
|
|
1872
1870
|
for name in _bundle_assets():
|
|
1873
1871
|
path = os.path.join(package, *name.split("/")) + ".meta"
|
|
@@ -499,7 +499,7 @@ class TestAudioEventsIntegration(unittest.TestCase):
|
|
|
499
499
|
# as the sibling integration tests.
|
|
500
500
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
501
501
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
502
|
-
project_path =
|
|
502
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
503
503
|
|
|
504
504
|
logger.info(f"Creating Unity project: {project_path}")
|
|
505
505
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
@@ -805,7 +805,7 @@ class TestAudioCarrierPrecedence(unittest.TestCase):
|
|
|
805
805
|
|
|
806
806
|
@classmethod
|
|
807
807
|
def setUpClass(cls):
|
|
808
|
-
cls.temp_dir = TempProjects.allocate("
|
|
808
|
+
cls.temp_dir = TempProjects.allocate("carrier_precedence")
|
|
809
809
|
|
|
810
810
|
@BlenderEnv.skip_unless_available()
|
|
811
811
|
@EnvSkip.unless(_unity_available(), "no Unity editor found")
|
|
@@ -821,7 +821,7 @@ class TestAudioCarrierPrecedence(unittest.TestCase):
|
|
|
821
821
|
)
|
|
822
822
|
|
|
823
823
|
launcher = UnityLauncher()
|
|
824
|
-
project =
|
|
824
|
+
project = TempProjects.project(self.temp_dir)
|
|
825
825
|
if not launcher.create_project(project, batch_mode=True):
|
|
826
826
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
827
827
|
delivered = os.path.join(project, "Assets", "Delivered")
|
|
@@ -42,6 +42,7 @@ from base_test import (
|
|
|
42
42
|
MayaEnv,
|
|
43
43
|
SuiteOptions,
|
|
44
44
|
TemplateSources,
|
|
45
|
+
TempProjects,
|
|
45
46
|
TestAssets,
|
|
46
47
|
UnityEnv,
|
|
47
48
|
UserPropsProbe,
|
|
@@ -486,6 +487,83 @@ class UnityEnvTest(unittest.TestCase):
|
|
|
486
487
|
self.assertEqual(result.errors, [])
|
|
487
488
|
self.assertEqual(result.testsRun, 3)
|
|
488
489
|
|
|
490
|
+
def test_make_urp_fails_fast_on_a_project_too_deep_for_the_editor(self):
|
|
491
|
+
"""The editor is not long-path aware: past MAX_PATH its package imports
|
|
492
|
+
fail, URP's Autodesk Interactive graph resolves to nothing, and the
|
|
493
|
+
material suite read the fallback pick as a product bug (2026-10-19)."""
|
|
494
|
+
deep = "C:\\" + "d" * (260 - UnityEnv.URP_IMPORT_DEPTH - 3) # one past the limit
|
|
495
|
+
|
|
496
|
+
class Case(unittest.TestCase):
|
|
497
|
+
def test_deep(self):
|
|
498
|
+
UnityEnv.make_urp(self, None, deep, "unused.log")
|
|
499
|
+
|
|
500
|
+
result = _run_case(Case)
|
|
501
|
+
self.assertEqual(result.errors, [])
|
|
502
|
+
self.assertEqual(len(result.failures), 1)
|
|
503
|
+
self.assertIn("UNITYTK_TEMP_PROJECTS", result.failures[0][1])
|
|
504
|
+
|
|
505
|
+
def test_the_depth_gate_covers_every_shader_graph_urp_ships(self):
|
|
506
|
+
"""The gate measured the Autodesk Interactive graph; URP's Arnold
|
|
507
|
+
transparent graph sits 25 characters deeper, so a 107-character project
|
|
508
|
+
passed it, that graph failed to import, URP's Arnold mapper left
|
|
509
|
+
aiStandardSurface on plain Lit and the material suite failed on every
|
|
510
|
+
run from the in-repo base (2026-10-19). Measured against each installed
|
|
511
|
+
editor's bundled URP, not a list of the graphs the suites use today."""
|
|
512
|
+
from unitytk import UnityFinder
|
|
513
|
+
|
|
514
|
+
packages = [
|
|
515
|
+
p
|
|
516
|
+
for p in map(UnityEnv.bundled_urp, UnityFinder.find_editors().values())
|
|
517
|
+
if os.path.isdir(p)
|
|
518
|
+
]
|
|
519
|
+
if not packages:
|
|
520
|
+
self.skipTest(EnvSkip.reason(UnityEnv.NO_BUNDLED_URP))
|
|
521
|
+
deepest = UnityEnv.URP_IMPORT_DEPTH - len(UnityEnv.URP_PACKAGE_CACHE)
|
|
522
|
+
for package in packages:
|
|
523
|
+
for dirpath, dirnames, filenames in os.walk(package):
|
|
524
|
+
# A folder ending "~" (samples, docs) or hidden is never imported.
|
|
525
|
+
dirnames[:] = [d for d in dirnames if not d.endswith("~") and not d.startswith(".")]
|
|
526
|
+
for name in filenames:
|
|
527
|
+
if name.endswith((".shadergraph", ".shadersubgraph")):
|
|
528
|
+
below = os.path.join(dirpath, name)[len(package):]
|
|
529
|
+
self.assertLessEqual(len(below), deepest, below)
|
|
530
|
+
|
|
531
|
+
@unittest.skipUnless(
|
|
532
|
+
os.name == "nt", "MAX_PATH is the Windows editor's limit; no Unity runs here"
|
|
533
|
+
)
|
|
534
|
+
def test_every_suite_fits_a_urp_project_under_the_default_base(self):
|
|
535
|
+
"""A plain ``run_tests.py --all`` builds its projects under the in-repo
|
|
536
|
+
base, where ``<run>\\urp\\UnityProject`` put the material suite's URP
|
|
537
|
+
project at 107 characters: past the gate, so every URP suite failed at
|
|
538
|
+
once (2026-10-19). Every suite's prefix, not only today's URP suites:
|
|
539
|
+
any of them may call ``make_urp`` on its project, or add a ``"urp"`` one."""
|
|
540
|
+
prefixes = set()
|
|
541
|
+
# The allocator's own tests allocate into a sandboxed base, retired prefixes included.
|
|
542
|
+
for path in _source_files(".py", exclude=("test_temp_projects.py", "test_run_tests.py")):
|
|
543
|
+
with open(path, encoding="utf-8", errors="replace") as fh:
|
|
544
|
+
tree = ast.parse(fh.read(), filename=path)
|
|
545
|
+
for node in ast.walk(tree):
|
|
546
|
+
if (
|
|
547
|
+
isinstance(node, ast.Call)
|
|
548
|
+
and isinstance(node.func, ast.Attribute)
|
|
549
|
+
and node.func.attr == "allocate"
|
|
550
|
+
and getattr(node.func.value, "id", None) == "TempProjects"
|
|
551
|
+
and node.args
|
|
552
|
+
and isinstance(node.args[0], ast.Constant)
|
|
553
|
+
and isinstance(node.args[0].value, str)
|
|
554
|
+
):
|
|
555
|
+
prefixes.add(node.args[0].value)
|
|
556
|
+
self.assertGreater(len(prefixes), 10, "the suites' allocations were not found")
|
|
557
|
+
# TempArtifacts' tag: the clock (16 hex digits), the pid in hex (6: Linux's
|
|
558
|
+
# pid_max ceiling; Windows ids run below it) and 4 random digits.
|
|
559
|
+
tag = "f" * (16 + 6 + 4)
|
|
560
|
+
budget = 259 - UnityEnv.URP_IMPORT_DEPTH
|
|
561
|
+
for prefix in sorted(prefixes):
|
|
562
|
+
run = os.path.join(TempProjects.DEFAULT_BASE, f"{prefix}_{tag}")
|
|
563
|
+
for project in (TempProjects.project(run), TempProjects.project(run, "urp")):
|
|
564
|
+
with self.subTest(project=project):
|
|
565
|
+
self.assertLessEqual(len(project), budget, project)
|
|
566
|
+
|
|
489
567
|
|
|
490
568
|
class SuiteOptionsTest(unittest.TestCase):
|
|
491
569
|
"""The opt-in switches are named once, neutrally."""
|
|
@@ -351,7 +351,7 @@ class TestBlenderRenderEffectsE2E(unittest.TestCase):
|
|
|
351
351
|
self.skipTest("Blender results not available -- test_01 must run first")
|
|
352
352
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
353
353
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
354
|
-
project_path =
|
|
354
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
355
355
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
356
356
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
357
357
|
assets_path = os.path.join(project_path, "Assets")
|
|
@@ -606,7 +606,7 @@ class TestBlenderShadowPlaneIntegration(unittest.TestCase):
|
|
|
606
606
|
blender = self._blender()
|
|
607
607
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
608
608
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
609
|
-
project_path =
|
|
609
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
610
610
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
611
611
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
612
612
|
|
|
@@ -232,7 +232,7 @@ class TestBlenderShotMetadataIntegration(unittest.TestCase):
|
|
|
232
232
|
self.skipTest("Blender results not available -- test_01 must run first")
|
|
233
233
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
234
234
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
235
|
-
project_path =
|
|
235
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
236
236
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
237
237
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
238
238
|
|
|
@@ -264,7 +264,7 @@ class TestClipNameContract(unittest.TestCase):
|
|
|
264
264
|
|
|
265
265
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
266
266
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
267
|
-
project_path =
|
|
267
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
268
268
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
269
269
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
270
270
|
|
|
@@ -181,7 +181,7 @@ class TestControllerRuntimeIntegration(unittest.TestCase):
|
|
|
181
181
|
"""Drive both controllers in a real Unity; capture the readback."""
|
|
182
182
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
183
183
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
184
|
-
project_path =
|
|
184
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
185
185
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
186
186
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
187
187
|
|
|
@@ -127,6 +127,12 @@ class DeployTemplateTest(unittest.TestCase):
|
|
|
127
127
|
"EmissiveGroup/EmissiveGroupController.cs",
|
|
128
128
|
"EmissiveGroup/EmissiveGroups.hlsl",
|
|
129
129
|
"EmissiveGroup/EmissiveGroupsLit.shader",
|
|
130
|
+
"LightmapMetadata/DeliverableCubeUV.hlsl",
|
|
131
|
+
"LightmapMetadata/DeliverableLit.shader",
|
|
132
|
+
"LightmapMetadata/DeliverablePmrem.cs",
|
|
133
|
+
"LightmapMetadata/DeliverableShading.cs",
|
|
134
|
+
"LightmapMetadata/DeliverableToneMap.shader",
|
|
135
|
+
"LightmapMetadata/DeliverableToneMapFeature.cs",
|
|
130
136
|
"LightmapMetadata/LightmapMetadataController.cs",
|
|
131
137
|
"M3trik.Unitytk.asmdef",
|
|
132
138
|
"MayaSurface/MayaSurfaceMaterialImporter.cs",
|
|
@@ -182,6 +188,63 @@ class DeployTemplateTest(unittest.TestCase):
|
|
|
182
188
|
f"{include} is not beside {shader}",
|
|
183
189
|
)
|
|
184
190
|
|
|
191
|
+
@staticmethod
|
|
192
|
+
def _shader_pass(text, name):
|
|
193
|
+
"""The ``Pass { ... }`` block of shader *text* named *name*, or None."""
|
|
194
|
+
at = text.find(f'Name "{name}"')
|
|
195
|
+
if at < 0:
|
|
196
|
+
return None
|
|
197
|
+
start = [m.start() for m in re.finditer(r"\bPass\s*\{", text[:at])][-1]
|
|
198
|
+
depth = 0
|
|
199
|
+
for i in range(text.index("{", start), len(text)):
|
|
200
|
+
depth += {"{": 1, "}": -1}.get(text[i], 0)
|
|
201
|
+
if depth == 0:
|
|
202
|
+
return text[start : i + 1]
|
|
203
|
+
return None
|
|
204
|
+
|
|
205
|
+
def test_forward_only_urp_shaders_draw_in_both_prepasses(self):
|
|
206
|
+
"""A URP shader drawn by a ``UniversalForwardOnly`` pass also draws in
|
|
207
|
+
the depth prepass and the depth-normals prepass (SSAO, any feature
|
|
208
|
+
asking for normals), as URP's Unlit does: under depth priming the
|
|
209
|
+
forward pass tests depth for equality, so a shader missing the prepass's
|
|
210
|
+
pass drew nothing there. Each carries the instance and eye macros
|
|
211
|
+
single-pass instanced XR needs (its own, or those of URP's own pass it
|
|
212
|
+
includes); the normals pass writes the packed normals a Deferred
|
|
213
|
+
renderer asks for."""
|
|
214
|
+
def walk(ref, prefix=""):
|
|
215
|
+
for child in ref.iterdir():
|
|
216
|
+
if child.is_dir():
|
|
217
|
+
yield from walk(child, prefix + child.name + "/")
|
|
218
|
+
elif child.name.endswith(".shader"):
|
|
219
|
+
yield prefix + child.name, child.read_text(encoding="utf-8")
|
|
220
|
+
|
|
221
|
+
forward_only = {
|
|
222
|
+
name: text
|
|
223
|
+
for name, text in walk(resources.files(TEMPLATE_PACKAGE))
|
|
224
|
+
if re.search(r'"LightMode"\s*=\s*"UniversalForwardOnly"', text)
|
|
225
|
+
}
|
|
226
|
+
self.assertEqual(
|
|
227
|
+
sorted(forward_only),
|
|
228
|
+
["EmissiveGroup/EmissiveGroupsLit.shader", "LightmapMetadata/DeliverableLit.shader"],
|
|
229
|
+
)
|
|
230
|
+
for name, text in forward_only.items():
|
|
231
|
+
for prepass in ("DepthOnly", "DepthNormalsOnly"):
|
|
232
|
+
block = self._shader_pass(text, prepass)
|
|
233
|
+
self.assertIsNotNone(block, f"{name} has no {prepass} pass")
|
|
234
|
+
self.assertRegex(block, rf'"LightMode"\s*=\s*"{prepass}"', f"{name} {prepass}")
|
|
235
|
+
self.assertRegex(block, r"ZWrite\s+On", f"{name} {prepass}")
|
|
236
|
+
if "universal/Shaders/UnlitDepthNormalsPass.hlsl" in block:
|
|
237
|
+
continue # URP's own pass, macros and all
|
|
238
|
+
for macro in (
|
|
239
|
+
"UNITY_VERTEX_INPUT_INSTANCE_ID",
|
|
240
|
+
"UNITY_VERTEX_OUTPUT_STEREO",
|
|
241
|
+
"UNITY_SETUP_INSTANCE_ID",
|
|
242
|
+
"UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO",
|
|
243
|
+
):
|
|
244
|
+
self.assertIn(macro, block, f"{name} {prepass}: no {macro}")
|
|
245
|
+
normals = self._shader_pass(text, "DepthNormalsOnly")
|
|
246
|
+
self.assertIn("_GBUFFER_NORMALS_OCT", normals, f"{name} DepthNormalsOnly")
|
|
247
|
+
|
|
185
248
|
# ---------------------------------------------------------------- components
|
|
186
249
|
def test_components_derive_from_the_bundle(self):
|
|
187
250
|
"""One required core plus one optional component per top-level folder,
|
|
@@ -366,6 +429,42 @@ class DeployTemplateTest(unittest.TestCase):
|
|
|
366
429
|
self.assertIn("M3trik.Unitytk", data["references"])
|
|
367
430
|
self.assertEqual(data["defineConstraints"], ["UNITYTK_XRI"])
|
|
368
431
|
|
|
432
|
+
def test_the_urp_define_starts_where_the_full_screen_pass_can_run_the_look(self):
|
|
433
|
+
"""``UNITYTK_URP`` compiles ``DeliverableLook``, which sets
|
|
434
|
+
``FullScreenPassRendererFeature.fetchColorBuffer`` and draws through
|
|
435
|
+
core's ``Blit.hlsl`` ``Vert``. Both arrived with URP 2022.3's backport
|
|
436
|
+
of the feature's fixes (in 14.0.9; 14.0.0-14.0.7 have no such field and
|
|
437
|
+
never set the ``_BlitScaleBias`` that vertex reads). A lower floor fails
|
|
438
|
+
the whole package's compile on those versions, not just the look."""
|
|
439
|
+
data = json.loads(bundle_ref("M3trik.Unitytk.asmdef").read_text(encoding="utf-8"))
|
|
440
|
+
urp = [d for d in data["versionDefines"] if d["define"] == "UNITYTK_URP"]
|
|
441
|
+
self.assertEqual(len(urp), 1, data["versionDefines"])
|
|
442
|
+
self.assertEqual(urp[0]["name"], "com.unity.render-pipelines.universal")
|
|
443
|
+
self.assertEqual(urp[0]["expression"], "14.0.9")
|
|
444
|
+
# A reference URP does not have is skipped: a Built-in project compiles.
|
|
445
|
+
self.assertIn("Unity.RenderPipelines.Universal.Runtime", data["references"])
|
|
446
|
+
|
|
447
|
+
def test_the_full_screen_pass_is_named_as_both_urps_declare_it(self):
|
|
448
|
+
"""URP 14 declares ``FullScreenPassRendererFeature`` in the global
|
|
449
|
+
namespace, URP 17 in ``UnityEngine.Rendering.Universal`` (its
|
|
450
|
+
``[MovedFrom("")]``). Only the short name, under a ``using`` of that
|
|
451
|
+
namespace, compiles on both: the qualified name failed the whole
|
|
452
|
+
package's compile on URP 14, where ``UNITYTK_URP`` starts."""
|
|
453
|
+
def walk(ref, prefix=""):
|
|
454
|
+
for child in ref.iterdir():
|
|
455
|
+
if child.is_dir():
|
|
456
|
+
yield from walk(child, prefix + child.name + "/")
|
|
457
|
+
elif child.name.endswith(".cs"):
|
|
458
|
+
yield prefix + child.name, child.read_text(encoding="utf-8")
|
|
459
|
+
|
|
460
|
+
named = []
|
|
461
|
+
for name, text in walk(resources.files(TEMPLATE_PACKAGE)):
|
|
462
|
+
self.assertNotIn("Universal.FullScreenPassRendererFeature", text, name)
|
|
463
|
+
if re.search(r"\bFullScreenPassRendererFeature\b", text):
|
|
464
|
+
named.append(name)
|
|
465
|
+
self.assertIn("using UnityEngine.Rendering.Universal;", text, name)
|
|
466
|
+
self.assertEqual(named, ["LightmapMetadata/DeliverableToneMapFeature.cs"])
|
|
467
|
+
|
|
369
468
|
def test_status_sees_subfolder_files(self):
|
|
370
469
|
"""A missing file inside a component's subfolder is a partial deploy
|
|
371
470
|
of that component, named by its bundle-relative name."""
|
|
@@ -377,7 +377,7 @@ class TestEmbeddedDependenciesIntegration(unittest.TestCase):
|
|
|
377
377
|
|
|
378
378
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
379
379
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
380
|
-
project =
|
|
380
|
+
project = TempProjects.project(self.temp_dir)
|
|
381
381
|
if not launcher.create_project(project, batch_mode=True):
|
|
382
382
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
383
383
|
delivered = os.path.join(project, *ASSET_DIR.split("/"))
|
|
@@ -596,7 +596,7 @@ class TestEmbeddedRequestPolicy(unittest.TestCase):
|
|
|
596
596
|
ptk.FbxMedia.embed(bare, sources[stem], files=[(f"{embed}.wav", clip)])
|
|
597
597
|
|
|
598
598
|
launcher = UnityLauncher()
|
|
599
|
-
project =
|
|
599
|
+
project = TempProjects.project(self.temp_dir)
|
|
600
600
|
if not launcher.create_project(project, batch_mode=True):
|
|
601
601
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
602
602
|
CarrierFbx.wav(
|
|
@@ -292,7 +292,7 @@ class TestEmissiveGroupsIntegration(unittest.TestCase):
|
|
|
292
292
|
|
|
293
293
|
editor = os.environ.get("UNITYTK_TEST_EDITOR")
|
|
294
294
|
launcher = UnityLauncher(editor) if editor else UnityLauncher()
|
|
295
|
-
project_path =
|
|
295
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
296
296
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
297
297
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
298
298
|
|
|
@@ -244,7 +244,7 @@ class TestFadeWindowPreservation(unittest.TestCase):
|
|
|
244
244
|
self.skipTest("FBX missing — test_01 must run first")
|
|
245
245
|
|
|
246
246
|
launcher = UnityLauncher()
|
|
247
|
-
project_path =
|
|
247
|
+
project_path = TempProjects.project(self.temp_dir)
|
|
248
248
|
if not launcher.create_project(project_path, batch_mode=True):
|
|
249
249
|
self.skipTest(UnityEnv.project_creation_reason())
|
|
250
250
|
|
|
@@ -406,7 +406,7 @@ class TestKeyedVisibility(unittest.TestCase):
|
|
|
406
406
|
@classmethod
|
|
407
407
|
def setUpClass(cls):
|
|
408
408
|
cls.temp_dir = TempProjects.allocate("keyed_vis_test")
|
|
409
|
-
cls.project_path =
|
|
409
|
+
cls.project_path = TempProjects.project(cls.temp_dir)
|
|
410
410
|
cls.results = None
|
|
411
411
|
logger.info(f"Temp dir: {cls.temp_dir}")
|
|
412
412
|
|