Make unity materials from TXMT files.

This adds the StandardMaterial TXMT from the game. We use a simple
Lambert surface shader to handle its rendering. Unfortunately since
there's no easy way in unity to make a surface shader with different
alpha modes based on the shader feature this means we need a shader
per each type of alpha mode: Opaque, CutOut and Blend.

This does lead to some duplicated code in the shaders in terms of the
properties but the body of the shader is stored in a common .cginc
file that gets pulled in with a #include
This commit is contained in:
Ammar Askar 2023-07-17 00:17:32 -04:00
parent 4dd3c17be3
commit 838a642854
21 changed files with 399 additions and 132 deletions

78
Assets/Materials/TestMaterial.mat generated Normal file
View file

@ -0,0 +1,78 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: TestMaterial
m_Shader: {fileID: 4800000, guid: 8ef2a4b74e9c86d45a4a2d758d117fa9, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

8
Assets/Materials/TestMaterial.mat.meta generated Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b990ae719e319924392204ae3a9245d4
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -216,102 +216,6 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &113393938
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 113393942}
- component: {fileID: 113393941}
- component: {fileID: 113393940}
- component: {fileID: 113393939}
m_Layer: 0
m_Name: MeshTestObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &113393939
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 113393938}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4df44336fd79e674ba53b9237a8c84c7, type: 3}
m_Name:
m_EditorClassIdentifier:
PackageToLoad: TestAssets/Scenegraph/teapot_model.package
ModelName: teapot_tslocator_gmdc
--- !u!23 &113393940
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 113393938}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &113393941
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 113393938}
m_Mesh: {fileID: 0}
--- !u!4 &113393942
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 113393938}
m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0}
--- !u!1 &1415389648
GameObject:
m_ObjectHideFlags: 0
@ -395,3 +299,49 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2090051043
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2090051045}
- component: {fileID: 2090051044}
m_Layer: 0
m_Name: ScenegraphGMDCTestScript
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2090051044
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2090051043}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4df44336fd79e674ba53b9237a8c84c7, type: 3}
m_Name:
m_EditorClassIdentifier:
PackageToLoad: TestAssets/Scenegraph/teapot_model.package
ModelName: teapot_tslocator_gmdc
PrimitiveToShow: teapot
--- !u!4 &2090051045
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2090051043}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -1.6537418, y: -9.371458, z: 0.046380997}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View file

@ -1,4 +1,10 @@
using OpenTS2.Files.Formats.DBPF.Scenegraph.Block;
using System;
using System.Collections.Generic;
using OpenTS2.Common;
using OpenTS2.Files.Formats.DBPF;
using OpenTS2.Files.Formats.DBPF.Scenegraph.Block;
using UnityEngine;
using UnityEngine.Rendering;
namespace OpenTS2.Content.DBPF.Scenegraph
{
@ -7,5 +13,73 @@ namespace OpenTS2.Content.DBPF.Scenegraph
public MaterialDefinitionBlock MaterialDefinition { get; }
public ScenegraphMaterialDefinitionAsset(MaterialDefinitionBlock material) => (MaterialDefinition) = (material);
private string GetProperty(string key, string defaultValue = null)
{
if (MaterialDefinition.MaterialProperties.TryGetValue(key, out var value))
{
return value;
}
if (defaultValue == null)
throw new KeyNotFoundException($"{key} not in material properties and no default given");
return defaultValue;
}
public Material GetAsUnityMaterial()
{
return MaterialDefinition.Type switch
{
MaterialType.StandardMaterial => GetStandardMaterial(),
_ => throw new ArgumentOutOfRangeException()
};
}
private static readonly int AlphaCutOff = Shader.PropertyToID("_AlphaCutOff");
private static readonly int AlphaMultiplier = Shader.PropertyToID("_AlphaMultiplier");
private Material GetStandardMaterial()
{
Shader shader;
// Decide which shader to use based on the alpha blending and alpha testing.
if (GetProperty("stdMatAlphaTestEnabled", defaultValue: "0") == "1")
{
shader = Shader.Find("OpenTS2/StandardMaterial/AlphaCutOut");
}
else if (GetProperty("stdMatAlphaBlendMode", defaultValue: "none") == "blend")
{
shader = Shader.Find("OpenTS2/StandardMaterial/AlphaBlended");
}
else
{
shader = Shader.Find("OpenTS2/StandardMaterial/Opaque");
}
var material = new Material(shader);
// Adjust the material properties based on the corresponding keys.
foreach (var property in MaterialDefinition.MaterialProperties)
{
switch (property.Key)
{
case "stdMatAlphaRefValue":
var alphaCutoffValue = int.Parse(property.Value);
material.SetFloat(AlphaCutOff, alphaCutoffValue / 255.0f);
break;
case "stdMatBaseTextureName":
var textureName = property.Value;
var texture = ContentProvider.Get().GetAsset<ScenegraphTextureAsset>(
new ResourceKey(textureName + "_txtr", GroupIDs.Scenegraph, TypeIDs.SCENEGRAPH_TXTR)
);
material.mainTexture = texture.GetSelectedImageAsUnityTexture(ContentProvider.Get());
break;
case "stdMatAlphaMultiplier":
material.SetFloat(AlphaMultiplier, float.Parse(property.Value));
break;
}
}
return material;
}
}
}

View file

@ -1,39 +1,41 @@
using System;
using System.Collections;
using System.Collections.Generic;
using OpenTS2.Common;
using OpenTS2.Content;
using OpenTS2.Content.DBPF.Scenegraph;
using OpenTS2.Files;
using OpenTS2.Files.Formats.DBPF;
using UnityEngine;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ScenegraphGMDCTest : MonoBehaviour
{
public string PackageToLoad = "TestAssets/Scenegraph/teapot_model.package";
public string ModelName = "teapot_tslocator_gmdc";
public string PrimitiveToShow = "teapot";
private void Start()
{
Debug.Log($"Loading package from {PackageToLoad}");
var contentProvider = ContentProvider.Get();
contentProvider.AddPackage(PackageToLoad);
// Load base game assets.
contentProvider.AddPackages(
Filesystem.GetPackagesInDirectory(Filesystem.GetDataPathForProduct(ProductFlags.BaseGame) + "/Res/Sims3D"));
var scenegraphModel = contentProvider.GetAsset<ScenegraphModelAsset>(
new ResourceKey(ModelName, 0x1C0532FA, TypeIDs.SCENEGRAPH_GMDC));
new ResourceKey("ufoCrash_tslocator_gmdc", 0x1C0532FA, TypeIDs.SCENEGRAPH_GMDC));
Debug.Log($"scenegraphModel: {scenegraphModel.GlobalTGI}");
Debug.Log($"primitives: {string.Join(" ", scenegraphModel.Primitives.Keys)}");
if (scenegraphModel.Primitives.ContainsKey(PrimitiveToShow))
{
GetComponent<MeshFilter>().mesh = scenegraphModel.Primitives[PrimitiveToShow];
}
else
{
GetComponent<MeshFilter>().mesh = scenegraphModel.StaticBoundMesh;
}
RenderPrimitive(scenegraphModel, "ufocrash_body", "ufocrash_body_txmt");
RenderPrimitive(scenegraphModel, "ufocrash_cabin", "ufocrash_cabin_txmt");
RenderPrimitive(scenegraphModel, "neighborhood_roundshadow", "neighborhood_roundshadow_txmt");
}
}
private void RenderPrimitive(ScenegraphModelAsset modelAsset, string primitive, string materialDefinition)
{
var rendered = new GameObject(primitive, typeof(MeshFilter), typeof(MeshRenderer));
rendered.transform.Rotate(-90, 0, 0);
rendered.GetComponent<MeshFilter>().mesh = modelAsset.Primitives[primitive];
var material = ContentProvider.Get()
.GetAsset<ScenegraphMaterialDefinitionAsset>(new ResourceKey(materialDefinition, GroupIDs.Scenegraph,
TypeIDs.SCENEGRAPH_TXMT));
rendered.GetComponent<MeshRenderer>().material = material.GetAsUnityMaterial();
}
}

View file

@ -46,7 +46,7 @@ namespace OpenTS2.Files.Formats.DBPF
/// </summary>
public const uint Local = 0xFFFFFFFF;
public const uint DIR = 0xE86B1EEF;
public const uint Scenegraph = 0x1C050000;
public const uint Scenegraph = 0x1C0532FA;
public const uint Pop = 0xFF23C3BF;
}
}

View file

@ -163,23 +163,24 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
var numberOfPrimitives = reader.ReadUInt32();
var primitives = new MeshPrimitive[numberOfPrimitives];
Debug.Log($"numberOfPrimitives: {numberOfPrimitives}");
for (var i = 0; i < numberOfPrimitives; i++)
{
reader.ReadUInt32();
var primitiveType = reader.ReadUInt32();
var componentIndex = reader.ReadUInt32();
var primitiveName = reader.ReadVariableLengthPascalString();
Debug.Log($"primitive name: {primitiveName}");
var faces = ReadIndices(reader, blockTypeInfo.Version);
// marked as opacity amount in simswiki
// TODO: this is actually the draw order for transparent objects. Lower values here mean the object
// should be drawn first. This is used for example in hot tubs where the shadow is drawn first, then
// the water, then the foam.
// marked as opacity amount in simswiki
reader.ReadInt32();
if (blockTypeInfo.Version > 1)
{
ReadIndices(reader, blockTypeInfo.Version);
var remappedBoneIndices = ReadIndices(reader, blockTypeInfo.Version);
}
primitives[i] = new MeshPrimitive

View file

@ -5,6 +5,11 @@ using UnityEngine;
namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
{
public enum MaterialType
{
StandardMaterial
}
public class MaterialDefinitionBlock : ScenegraphDataBlock
{
public const uint TYPE_ID = 0x49596978;
@ -13,6 +18,16 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
public ScenegraphResource Resource { get; }
/// <summary>
/// The human-friendly name of the material.
/// </summary>
public string MaterialName { get; }
/// <summary>
/// The type of the material.
/// </summary>
public MaterialType Type { get; }
/// <summary>
/// A dictionary mapping material properties such as "reflectivity" -> "0.5" and
/// "stdMatCullMode" -> "cullClockwise".
@ -25,8 +40,10 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
public string[] TextureNames { get; }
public MaterialDefinitionBlock(PersistTypeInfo blockTypeInfo, ScenegraphResource resource,
string materialName, MaterialType type,
Dictionary<string, string> materialProperties, string[] textureNames) : base(blockTypeInfo)
=> (Resource, MaterialProperties, TextureNames) = (resource, materialProperties, textureNames);
=> (Resource, MaterialName, Type, MaterialProperties, TextureNames) =
(resource, materialName, type, materialProperties, textureNames);
}
public class MaterialDefinitionBlockReader : IScenegraphDataBlockReader<MaterialDefinitionBlock>
@ -39,7 +56,7 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
var resource = ScenegraphResource.Deserialize(reader);
var materialName = reader.ReadVariableLengthPascalString();
var definitionName = reader.ReadVariableLengthPascalString();
var definitionType = reader.ReadVariableLengthPascalString();
var numberOfProperties = reader.ReadInt32();
var properties = new Dictionary<string, string>(numberOfProperties);
@ -55,7 +72,17 @@ namespace OpenTS2.Files.Formats.DBPF.Scenegraph.Block
textures[i] = reader.ReadVariableLengthPascalString();
}
return new MaterialDefinitionBlock(blockTypeInfo, resource, properties, textures);
return new MaterialDefinitionBlock(blockTypeInfo, resource, materialName,
GetTypeFromTypeName(definitionType), properties, textures);
}
private static MaterialType GetTypeFromTypeName(string materialType)
{
return materialType switch
{
"StandardMaterial" => MaterialType.StandardMaterial,
_ => throw new ArgumentException($"Unknown material type: {materialType}")
};
}
}
}

8
Assets/Shaders/StandardMaterial.meta generated Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 63ba9bfd5ea0a9c48aabe8e47c56a9a0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,20 @@
Shader "OpenTS2/StandardMaterial/AlphaBlended"
{
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
_AlphaMultiplier ("Alpha Multiplier", Range(0.0, 1.0)) = 1.0
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
CGPROGRAM
#pragma surface surf Lambert fullforwardshadows alpha:blend
#include "Assets/Shaders/StandardMaterial/shader_body.cginc"
ENDCG
}
FallBack "Diffuse"
}

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0b96ca1818f768545967888a745b08e5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,22 @@
Shader "OpenTS2/StandardMaterial/AlphaCutOut"
{
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
_AlphaMultiplier ("Alpha Multiplier", Range(0.0, 1.0)) = 1.0
_AlphaCutOff ("AlphaCutOff", Float) = 1.0
}
SubShader
{
Tags { "RenderType"="AlphaTest" "Queue"="AlphaTest" }
CGPROGRAM
#pragma surface surf Lambert fullforwardshadows alphatest:_AlphaCutOff
#include "Assets/Shaders/StandardMaterial/shader_body.cginc"
ENDCG
}
FallBack "Diffuse"
}

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 4d0461340a185194c81b99c57ca9c084
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,20 @@
Shader "OpenTS2/StandardMaterial/Opaque"
{
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
_AlphaMultiplier ("Alpha Multiplier", Range(0.0, 1.0)) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Geometry" }
CGPROGRAM
#pragma surface surf Lambert fullforwardshadows
#include "Assets/Shaders/StandardMaterial/shader_body.cginc"
ENDCG
}
FallBack "Diffuse"
}

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 687258d81ac22d0468c2f8b31c25f43d
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,20 @@
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
float _AlphaMultiplier;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
c.a *= _AlphaMultiplier;
o.Albedo = c.rgb;
o.Alpha = c.a;
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3f6adc2fd04f41d6aa8d4c83890b61a9
timeCreated: 1689689303

View file

@ -3,8 +3,9 @@ using OpenTS2.Common;
using OpenTS2.Content;
using OpenTS2.Content.DBPF.Scenegraph;
using OpenTS2.Files.Formats.DBPF;
using OpenTS2.Files.Formats.DBPF.Scenegraph.Block;
public class ScenegraphMaterailDefinitionCodecTest
public class ScenegraphMaterialDefinitionCodecTest
{
[SetUp]
public void SetUp()
@ -20,6 +21,9 @@ public class ScenegraphMaterailDefinitionCodecTest
.GetAsset<ScenegraphMaterialDefinitionAsset>(new ResourceKey("ufocrash_cabin_txmt", 0x1C0532FA,
TypeIDs.SCENEGRAPH_TXMT));
Assert.That(materialAsset.MaterialDefinition.MaterialName, Is.EqualTo("ufocrash_cabin"));
Assert.That(materialAsset.MaterialDefinition.Type, Is.EqualTo(MaterialType.StandardMaterial));
Assert.That(materialAsset.MaterialDefinition.MaterialProperties.Count, Is.GreaterThan(0));
Assert.That(materialAsset.MaterialDefinition.MaterialProperties["reflectivity"], Is.EqualTo("0.025"));

View file

@ -4,7 +4,7 @@
"com.unity.ide.rider": "2.0.7",
"com.unity.ide.visualstudio": "2.0.14",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.31",
"com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.4.8",
"com.unity.ugui": "1.0.0",

View file

@ -51,7 +51,7 @@
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.31",
"version": "1.1.33",
"depth": 0,
"source": "registry",
"dependencies": {