测试修复安卓打包

This commit is contained in:
SepComet 2026-03-17 11:28:33 +08:00
parent 224db4cd5c
commit 59f1d02a18
23 changed files with 583 additions and 258 deletions

2
.gitignore vendored
View File

@ -77,8 +77,6 @@ crashlytics-build.properties
/Assets/StreamingAssets /Assets/StreamingAssets
/Assets/StreamingAssets.meta /Assets/StreamingAssets.meta
/Assets/StreamingAssets
/UI参考 /UI参考
/AGENTS.md /AGENTS.md
/bin /bin

View File

@ -2,15 +2,11 @@
<UnityGameFramework> <UnityGameFramework>
<ResourceBuilder> <ResourceBuilder>
<Settings> <Settings>
<<<<<<< Updated upstream <InternalResourceVersion>0</InternalResourceVersion>
<InternalResourceVersion>5</InternalResourceVersion>
=======
<InternalResourceVersion>4</InternalResourceVersion>
>>>>>>> Stashed changes
<Platforms>33</Platforms> <Platforms>33</Platforms>
<AssetBundleCompression>1</AssetBundleCompression> <AssetBundleCompression>1</AssetBundleCompression>
<CompressionHelperTypeName>UnityGameFramework.Runtime.DefaultCompressionHelper</CompressionHelperTypeName> <CompressionHelperTypeName>UnityGameFramework.Runtime.DefaultCompressionHelper</CompressionHelperTypeName>
<AdditionalCompressionSelected>True</AdditionalCompressionSelected> <AdditionalCompressionSelected>False</AdditionalCompressionSelected>
<ForceRebuildAssetBundleSelected>False</ForceRebuildAssetBundleSelected> <ForceRebuildAssetBundleSelected>False</ForceRebuildAssetBundleSelected>
<BuildEventHandlerTypeName>StarForce.Editor.StarForceBuildEventHandler</BuildEventHandlerTypeName> <BuildEventHandlerTypeName>StarForce.Editor.StarForceBuildEventHandler</BuildEventHandlerTypeName>
<OutputDirectory>C:/UnityProjects/VampireLike/bin/AssetBundles</OutputDirectory> <OutputDirectory>C:/UnityProjects/VampireLike/bin/AssetBundles</OutputDirectory>

View File

@ -1,7 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 5461b0fc87a2ab04fbcfd898d18f6107 guid: 5461b0fc87a2ab04fbcfd898d18f6107
labels:
- ResourceExclusive
TextScriptImporter: TextScriptImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@ -2,28 +2,19 @@
<UnityGameFramework> <UnityGameFramework>
<ResourceCollection> <ResourceCollection>
<Resources> <Resources>
<Resource Name="Configs" FileSystem="GameData" LoadType="0" Packed="True" <Resource Name="Configs" FileSystem="GameData" LoadType="0" Packed="True" ResourceGroups="Base" />
ResourceGroups="Base" /> <Resource Name="DataTables" FileSystem="GameData" LoadType="0" Packed="True" ResourceGroups="Base" />
<Resource Name="DataTables" FileSystem="GameData" LoadType="0" Packed="True"
ResourceGroups="Base" />
<Resource Name="Entities" FileSystem="Resources" LoadType="0" Packed="True" /> <Resource Name="Entities" FileSystem="Resources" LoadType="0" Packed="True" />
<Resource Name="Fonts" FileSystem="UI" LoadType="0" Packed="True" ResourceGroups="Base" /> <Resource Name="Fonts" FileSystem="UI" LoadType="0" Packed="True" ResourceGroups="Base" />
<Resource Name="Localization/Dictionaries" Variant="en-us" FileSystem="UI" LoadType="0" <Resource Name="Localization/Dictionaries" Variant="en-us" FileSystem="UI" LoadType="0" Packed="True" ResourceGroups="Base" />
Packed="True" ResourceGroups="Base" /> <Resource Name="Localization/Dictionaries" Variant="ko-kr" FileSystem="UI" LoadType="0" Packed="True" ResourceGroups="Base" />
<Resource Name="Localization/Dictionaries" Variant="ko-kr" FileSystem="UI" LoadType="0" <Resource Name="Localization/Dictionaries" Variant="zh-cn" FileSystem="UI" LoadType="0" Packed="True" ResourceGroups="Base" />
Packed="True" ResourceGroups="Base" /> <Resource Name="Localization/Dictionaries" Variant="zh-tw" FileSystem="UI" LoadType="0" Packed="True" ResourceGroups="Base" />
<Resource Name="Localization/Dictionaries" Variant="zh-cn" FileSystem="UI" LoadType="0"
Packed="True" ResourceGroups="Base" />
<Resource Name="Localization/Dictionaries" Variant="zh-tw" FileSystem="UI" LoadType="0"
Packed="True" ResourceGroups="Base" />
<Resource Name="Materials" FileSystem="Resources" LoadType="0" Packed="True" /> <Resource Name="Materials" FileSystem="Resources" LoadType="0" Packed="True" />
<Resource Name="Meshes" FileSystem="Resources" LoadType="0" Packed="True" /> <Resource Name="Meshes" FileSystem="Resources" LoadType="0" Packed="True" />
<Resource Name="Music/About" FileSystem="Resources" LoadType="0" Packed="True" <Resource Name="Music/About" FileSystem="Resources" LoadType="0" Packed="True" ResourceGroups="Music" />
ResourceGroups="Music" /> <Resource Name="Music/Background" FileSystem="Resources" LoadType="0" Packed="True" ResourceGroups="Music" />
<Resource Name="Music/Background" FileSystem="Resources" LoadType="0" Packed="True" <Resource Name="Music/Menu" FileSystem="Resources" LoadType="0" Packed="True" ResourceGroups="Music" />
ResourceGroups="Music" />
<Resource Name="Music/Menu" FileSystem="Resources" LoadType="0" Packed="True"
ResourceGroups="Music" />
<Resource Name="Scenes" FileSystem="Resources" LoadType="0" Packed="True" /> <Resource Name="Scenes" FileSystem="Resources" LoadType="0" Packed="True" />
<Resource Name="SceneSettings" LoadType="0" Packed="False" /> <Resource Name="SceneSettings" LoadType="0" Packed="False" />
<Resource Name="Sounds" FileSystem="Resources" LoadType="0" Packed="True" /> <Resource Name="Sounds" FileSystem="Resources" LoadType="0" Packed="True" />
@ -50,11 +41,9 @@
<Asset Guid="0ed73dc47f4cb38489020d05e9f02c99" ResourceName="Materials" /> <Asset Guid="0ed73dc47f4cb38489020d05e9f02c99" ResourceName="Materials" />
<Asset Guid="0f995b3145e0e7247a42da6cef1dbf23" ResourceName="Materials" /> <Asset Guid="0f995b3145e0e7247a42da6cef1dbf23" ResourceName="Materials" />
<Asset Guid="1046dcb12e547564d8b54bd15419a787" ResourceName="Entities" /> <Asset Guid="1046dcb12e547564d8b54bd15419a787" ResourceName="Entities" />
<Asset Guid="1053b0070685be347ab58587156842dc" ResourceName="Localization/Dictionaries" <Asset Guid="1053b0070685be347ab58587156842dc" ResourceName="Localization/Dictionaries" ResourceVariant="zh-tw" />
ResourceVariant="zh-tw" />
<Asset Guid="1478894bc9a1ed241b05b0862a7b8bce" ResourceName="Textures" /> <Asset Guid="1478894bc9a1ed241b05b0862a7b8bce" ResourceName="Textures" />
<Asset Guid="14869ac0d4433f04db1704e39d03412e" ResourceName="Localization/Dictionaries" <Asset Guid="14869ac0d4433f04db1704e39d03412e" ResourceName="Localization/Dictionaries" ResourceVariant="en-us" />
ResourceVariant="en-us" />
<Asset Guid="156d241f796508c4da4fc354a7fbf5a8" ResourceName="UI/UISprites/Common" /> <Asset Guid="156d241f796508c4da4fc354a7fbf5a8" ResourceName="UI/UISprites/Common" />
<Asset Guid="185f97f18bd603a478461ce9c08bd039" ResourceName="Materials" /> <Asset Guid="185f97f18bd603a478461ce9c08bd039" ResourceName="Materials" />
<Asset Guid="18dc0cd2c080841dea60987a38ce93fa" ResourceName="URPAssets" /> <Asset Guid="18dc0cd2c080841dea60987a38ce93fa" ResourceName="URPAssets" />
@ -103,8 +92,7 @@
<Asset Guid="578af1667322bab45b652b79a40bb4fb" ResourceName="Materials" /> <Asset Guid="578af1667322bab45b652b79a40bb4fb" ResourceName="Materials" />
<Asset Guid="583ff7026dac91849b7c7b2468ba456b" ResourceName="Materials" /> <Asset Guid="583ff7026dac91849b7c7b2468ba456b" ResourceName="Materials" />
<Asset Guid="5b5a6a737c460eb4abc105d6583d405e" ResourceName="Fonts" /> <Asset Guid="5b5a6a737c460eb4abc105d6583d405e" ResourceName="Fonts" />
<Asset Guid="5dcd89912e222bf4c87f76db4044bc5e" ResourceName="Localization/Dictionaries" <Asset Guid="5dcd89912e222bf4c87f76db4044bc5e" ResourceName="Localization/Dictionaries" ResourceVariant="ko-kr" />
ResourceVariant="ko-kr" />
<Asset Guid="5ebb46af6f16ae94e87f64a7dc0a49cb" ResourceName="Entities" /> <Asset Guid="5ebb46af6f16ae94e87f64a7dc0a49cb" ResourceName="Entities" />
<Asset Guid="62af9e5c8f39cfa49af9e10ccf42f1da" ResourceName="UI/UISprites/Common" /> <Asset Guid="62af9e5c8f39cfa49af9e10ccf42f1da" ResourceName="UI/UISprites/Common" />
<Asset Guid="638ff8ae4a0d15047839cd265d3bc296" ResourceName="Music/Background" /> <Asset Guid="638ff8ae4a0d15047839cd265d3bc296" ResourceName="Music/Background" />
@ -144,8 +132,7 @@
<Asset Guid="97b1f8b25cca2bc458cb9d6127c8d186" ResourceName="Materials" /> <Asset Guid="97b1f8b25cca2bc458cb9d6127c8d186" ResourceName="Materials" />
<Asset Guid="99d811b0183246646a2ce8df996f4bca" ResourceName="Fonts" /> <Asset Guid="99d811b0183246646a2ce8df996f4bca" ResourceName="Fonts" />
<Asset Guid="9afa958d6d8235941b9badb42aae4370" ResourceName="Meshes" /> <Asset Guid="9afa958d6d8235941b9badb42aae4370" ResourceName="Meshes" />
<Asset Guid="9be2e1e45f4edd74c8764538ad306b78" ResourceName="Localization/Dictionaries" <Asset Guid="9be2e1e45f4edd74c8764538ad306b78" ResourceName="Localization/Dictionaries" ResourceVariant="zh-cn" />
ResourceVariant="zh-cn" />
<Asset Guid="9d193ac5b4294e0e9ba6e867320944b7" ResourceName="Entities" /> <Asset Guid="9d193ac5b4294e0e9ba6e867320944b7" ResourceName="Entities" />
<Asset Guid="9ddab293e2a8af3499dac05f5fd6169c" ResourceName="Meshes" /> <Asset Guid="9ddab293e2a8af3499dac05f5fd6169c" ResourceName="Meshes" />
<Asset Guid="9f5bba6d2f5c95049a59fcb56df2d38f" ResourceName="UI/UIItems" /> <Asset Guid="9f5bba6d2f5c95049a59fcb56df2d38f" ResourceName="UI/UIItems" />

View File

@ -0,0 +1,84 @@
float2 UnpackUV(float uv)
{
float2 output;
output.x = floor(uv / 4096);
output.y = uv - 4096 * output.x;
return output * 0.001953125;
}
fixed4 GetColor(half d, fixed4 faceColor, fixed4 outlineColor, half outline, half softness)
{
half faceAlpha = 1-saturate((d - outline * 0.5 + softness * 0.5) / (1.0 + softness));
half outlineAlpha = saturate((d + outline * 0.5)) * sqrt(min(1.0, outline));
faceColor.rgb *= faceColor.a;
outlineColor.rgb *= outlineColor.a;
faceColor = lerp(faceColor, outlineColor, outlineAlpha);
faceColor *= faceAlpha;
return faceColor;
}
float3 GetSurfaceNormal(float4 h, float bias)
{
bool raisedBevel = step(1, fmod(_ShaderFlags, 2));
h += bias+_BevelOffset;
float bevelWidth = max(.01, _OutlineWidth+_BevelWidth);
// Track outline
h -= .5;
h /= bevelWidth;
h = saturate(h+.5);
if(raisedBevel) h = 1 - abs(h*2.0 - 1.0);
h = lerp(h, sin(h*3.141592/2.0), _BevelRoundness);
h = min(h, 1.0-_BevelClamp);
h *= _Bevel * bevelWidth * _GradientScale * -2.0;
float3 va = normalize(float3(1.0, 0.0, h.y - h.x));
float3 vb = normalize(float3(0.0, -1.0, h.w - h.z));
return cross(va, vb);
}
float3 GetSurfaceNormal(float2 uv, float bias, float3 delta)
{
// Read "height field"
float4 h = {tex2D(_MainTex, uv - delta.xz).a,
tex2D(_MainTex, uv + delta.xz).a,
tex2D(_MainTex, uv - delta.zy).a,
tex2D(_MainTex, uv + delta.zy).a};
return GetSurfaceNormal(h, bias);
}
float3 GetSpecular(float3 n, float3 l)
{
float spec = pow(max(0.0, dot(n, l)), _Reflectivity);
return _SpecularColor.rgb * spec * _SpecularPower;
}
float4 GetGlowColor(float d, float scale)
{
float glow = d - (_GlowOffset*_ScaleRatioB) * 0.5 * scale;
float t = lerp(_GlowInner, (_GlowOuter * _ScaleRatioB), step(0.0, glow)) * 0.5 * scale;
glow = saturate(abs(glow/(1.0 + t)));
glow = 1.0-pow(glow, _GlowPower);
glow *= sqrt(min(1.0, t)); // Fade off glow thinner than 1 screen pixel
return float4(_GlowColor.rgb, saturate(_GlowColor.a * glow * 2));
}
float4 BlendARGB(float4 overlying, float4 underlying)
{
overlying.rgb *= overlying.a;
underlying.rgb *= underlying.a;
float3 blended = overlying.rgb + ((1-overlying.a)*underlying.rgb);
float alpha = underlying.a + (1-underlying.a)*overlying.a;
return float4(blended, alpha);
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: dba6242363c96c44eb6ec1e124d487e4
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,157 @@
struct vertex_t {
UNITY_VERTEX_INPUT_INSTANCE_ID
float4 position : POSITION;
float3 normal : NORMAL;
float4 color : COLOR;
float2 texcoord0 : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
struct pixel_t {
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
float4 position : SV_POSITION;
float4 faceColor : COLOR;
float4 outlineColor : COLOR1;
float4 texcoord0 : TEXCOORD0;
float4 param : TEXCOORD1; // weight, scaleRatio
float2 mask : TEXCOORD2;
#if (UNDERLAY_ON || UNDERLAY_INNER)
float4 texcoord2 : TEXCOORD3;
float4 underlayColor : COLOR2;
#endif
};
float4 SRGBToLinear(float4 rgba) {
return float4(lerp(rgba.rgb / 12.92f, pow((rgba.rgb + 0.055f) / 1.055f, 2.4f), step(0.04045f, rgba.rgb)), rgba.a);
}
pixel_t VertShader(vertex_t input)
{
pixel_t output;
UNITY_INITIALIZE_OUTPUT(pixel_t, output);
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float bold = step(input.texcoord1.y, 0);
float4 vert = input.position;
vert.x += _VertexOffsetX;
vert.y += _VertexOffsetY;
float4 vPosition = UnityObjectToClipPos(vert);
float weight = lerp(_WeightNormal, _WeightBold, bold) / 4.0;
weight = (weight + _FaceDilate) * _ScaleRatioA * 0.5;
// Generate UV for the Masking Texture
float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
float2 maskUV = (vert.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
float4 color = input.color;
#if (FORCE_LINEAR && !UNITY_COLORSPACE_GAMMA)
color = SRGBToLinear(input.color);
#endif
float opacity = color.a;
#if (UNDERLAY_ON | UNDERLAY_INNER)
opacity = 1.0;
#endif
float4 faceColor = float4(color.rgb, opacity) * _FaceColor;
faceColor.rgb *= faceColor.a;
float4 outlineColor = _OutlineColor;
outlineColor.a *= opacity;
outlineColor.rgb *= outlineColor.a;
output.position = vPosition;
output.faceColor = faceColor;
output.outlineColor = outlineColor;
output.texcoord0 = float4(input.texcoord0.xy, maskUV.xy);
output.param = float4(0.5 - weight, 1.3333 * _GradientScale * (_Sharpness + 1) / _TextureWidth, _OutlineWidth * _ScaleRatioA * 0.5, 0);
float2 mask = float2(0, 0);
#if UNITY_UI_CLIP_RECT
mask = vert.xy * 2 - clampedRect.xy - clampedRect.zw;
#endif
output.mask = mask;
#if (UNDERLAY_ON || UNDERLAY_INNER)
float4 underlayColor = _UnderlayColor;
underlayColor.rgb *= underlayColor.a;
float x = -(_UnderlayOffsetX * _ScaleRatioC) * _GradientScale / _TextureWidth;
float y = -(_UnderlayOffsetY * _ScaleRatioC) * _GradientScale / _TextureHeight;
output.texcoord2 = float4(input.texcoord0 + float2(x, y), input.color.a, 0);
output.underlayColor = underlayColor;
#endif
return output;
}
float4 PixShader(pixel_t input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
float d = tex2D(_MainTex, input.texcoord0.xy).a;
float2 UV = input.texcoord0.xy;
float scale = rsqrt(abs(ddx(UV.x) * ddy(UV.y) - ddy(UV.x) * ddx(UV.y))) * input.param.y;
#if (UNDERLAY_ON | UNDERLAY_INNER)
float layerScale = scale;
layerScale /= 1 + ((_UnderlaySoftness * _ScaleRatioC) * layerScale);
float layerBias = input.param.x * layerScale - .5 - ((_UnderlayDilate * _ScaleRatioC) * .5 * layerScale);
#endif
scale /= 1 + (_OutlineSoftness * _ScaleRatioA * scale);
float4 faceColor = input.faceColor * saturate((d - input.param.x) * scale + 0.5);
#ifdef OUTLINE_ON
float4 outlineColor = lerp(input.faceColor, input.outlineColor, sqrt(min(1.0, input.param.z * scale * 2)));
faceColor = lerp(outlineColor, input.faceColor, saturate((d - input.param.x - input.param.z) * scale + 0.5));
faceColor *= saturate((d - input.param.x + input.param.z) * scale + 0.5);
#endif
#if UNDERLAY_ON
d = tex2D(_MainTex, input.texcoord2.xy).a * layerScale;
faceColor += float4(_UnderlayColor.rgb * _UnderlayColor.a, _UnderlayColor.a) * saturate(d - layerBias) * (1 - faceColor.a);
#endif
#if UNDERLAY_INNER
float bias = input.param.x * scale - 0.5;
float sd = saturate(d * scale - bias - input.param.z);
d = tex2D(_MainTex, input.texcoord2.xy).a * layerScale;
faceColor += float4(_UnderlayColor.rgb * _UnderlayColor.a, _UnderlayColor.a) * (1 - saturate(d - layerBias)) * sd * (1 - faceColor.a);
#endif
#ifdef MASKING
float a = abs(_MaskInverse - tex2D(_MaskTex, input.texcoord0.zw).a);
float t = a + (1 - _MaskWipeControl) * _MaskEdgeSoftness - _MaskWipeControl;
a = saturate(t / _MaskEdgeSoftness);
faceColor.rgb = lerp(_MaskEdgeColor.rgb * faceColor.a, faceColor.rgb, a);
faceColor *= a;
#endif
// Alternative implementation to UnityGet2DClipping with support for softness
#if UNITY_UI_CLIP_RECT
float2 maskZW = 0.25 / (0.25 * half2(_MaskSoftnessX, _MaskSoftnessY) + (1 / scale));
float2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * maskZW);
faceColor *= m.x * m.y;
#endif
#if (UNDERLAY_ON | UNDERLAY_INNER)
faceColor *= input.texcoord2.z;
#endif
#if UNITY_UI_ALPHACLIP
clip(faceColor.a - 0.001);
#endif
return faceColor;
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d9a5c27d283a4e7429acad6face5485a
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,85 @@
// UI Editable properties
uniform sampler2D _FaceTex; // Alpha : Signed Distance
uniform float _FaceUVSpeedX;
uniform float _FaceUVSpeedY;
uniform fixed4 _FaceColor; // RGBA : Color + Opacity
uniform float _FaceDilate; // v[ 0, 1]
uniform float _OutlineSoftness; // v[ 0, 1]
uniform sampler2D _OutlineTex; // RGBA : Color + Opacity
uniform float _OutlineUVSpeedX;
uniform float _OutlineUVSpeedY;
uniform fixed4 _OutlineColor; // RGBA : Color + Opacity
uniform float _OutlineWidth; // v[ 0, 1]
uniform float _Bevel; // v[ 0, 1]
uniform float _BevelOffset; // v[-1, 1]
uniform float _BevelWidth; // v[-1, 1]
uniform float _BevelClamp; // v[ 0, 1]
uniform float _BevelRoundness; // v[ 0, 1]
uniform sampler2D _BumpMap; // Normal map
uniform float _BumpOutline; // v[ 0, 1]
uniform float _BumpFace; // v[ 0, 1]
uniform samplerCUBE _Cube; // Cube / sphere map
uniform fixed4 _ReflectFaceColor; // RGB intensity
uniform fixed4 _ReflectOutlineColor;
//uniform float _EnvTiltX; // v[-1, 1]
//uniform float _EnvTiltY; // v[-1, 1]
uniform float3 _EnvMatrixRotation;
uniform float4x4 _EnvMatrix;
uniform fixed4 _SpecularColor; // RGB intensity
uniform float _LightAngle; // v[ 0,Tau]
uniform float _SpecularPower; // v[ 0, 1]
uniform float _Reflectivity; // v[ 5, 15]
uniform float _Diffuse; // v[ 0, 1]
uniform float _Ambient; // v[ 0, 1]
uniform fixed4 _UnderlayColor; // RGBA : Color + Opacity
uniform float _UnderlayOffsetX; // v[-1, 1]
uniform float _UnderlayOffsetY; // v[-1, 1]
uniform float _UnderlayDilate; // v[-1, 1]
uniform float _UnderlaySoftness; // v[ 0, 1]
uniform fixed4 _GlowColor; // RGBA : Color + Intesity
uniform float _GlowOffset; // v[-1, 1]
uniform float _GlowOuter; // v[ 0, 1]
uniform float _GlowInner; // v[ 0, 1]
uniform float _GlowPower; // v[ 1, 1/(1+4*4)]
// API Editable properties
uniform float _ShaderFlags;
uniform float _WeightNormal;
uniform float _WeightBold;
uniform float _ScaleRatioA;
uniform float _ScaleRatioB;
uniform float _ScaleRatioC;
uniform float _VertexOffsetX;
uniform float _VertexOffsetY;
//uniform float _UseClipRect;
uniform float _MaskID;
uniform sampler2D _MaskTex;
uniform float4 _MaskCoord;
uniform float4 _ClipRect; // bottom left(x,y) : top right(z,w)
//uniform float _MaskWipeControl;
//uniform float _MaskEdgeSoftness;
//uniform fixed4 _MaskEdgeColor;
//uniform bool _MaskInverse;
uniform float _MaskSoftnessX;
uniform float _MaskSoftnessY;
// Font Atlas properties
uniform sampler2D _MainTex;
uniform float _TextureWidth;
uniform float _TextureHeight;
uniform float _GradientScale;
uniform float _ScaleX;
uniform float _ScaleY;
uniform float _PerspectiveFilter;
uniform float _Sharpness;

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8218173e722cac14996fc86da8882fc8
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,101 @@
void VertShader(inout appdata_full v, out Input data)
{
v.vertex.x += _VertexOffsetX;
v.vertex.y += _VertexOffsetY;
UNITY_INITIALIZE_OUTPUT(Input, data);
float bold = step(v.texcoord1.y, 0);
// Generate normal for backface
float3 view = ObjSpaceViewDir(v.vertex);
v.normal *= sign(dot(v.normal, view));
#if USE_DERIVATIVE
data.param.y = 1;
#else
float4 vert = v.vertex;
float4 vPosition = UnityObjectToClipPos(vert);
float2 pixelSize = vPosition.w;
pixelSize /= float2(_ScaleX, _ScaleY) * mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy);
float scale = rsqrt(dot(pixelSize, pixelSize));
scale *= abs(v.texcoord1.y) * _GradientScale * (_Sharpness + 1);
scale = lerp(scale * (1 - _PerspectiveFilter), scale, abs(dot(UnityObjectToWorldNormal(v.normal.xyz), normalize(WorldSpaceViewDir(vert)))));
data.param.y = scale;
#endif
data.param.x = (lerp(_WeightNormal, _WeightBold, bold) / 4.0 + _FaceDilate) * _ScaleRatioA * 0.5; //
v.texcoord1.xy = UnpackUV(v.texcoord1.x);
data.viewDirEnv = mul((float3x3)_EnvMatrix, WorldSpaceViewDir(v.vertex));
}
void PixShader(Input input, inout SurfaceOutput o)
{
#if USE_DERIVATIVE
float2 pixelSize = float2(ddx(input.uv_MainTex.y), ddy(input.uv_MainTex.y));
pixelSize *= _TextureWidth * .75;
float scale = rsqrt(dot(pixelSize, pixelSize)) * _GradientScale * (_Sharpness + 1);
#else
float scale = input.param.y;
#endif
// Signed distance
float c = tex2D(_MainTex, input.uv_MainTex).a;
float sd = (.5 - c - input.param.x) * scale + .5;
float outline = _OutlineWidth*_ScaleRatioA * scale;
float softness = _OutlineSoftness*_ScaleRatioA * scale;
// Color & Alpha
float4 faceColor = _FaceColor;
float4 outlineColor = _OutlineColor;
faceColor *= input.color;
outlineColor.a *= input.color.a;
faceColor *= tex2D(_FaceTex, float2(input.uv2_FaceTex.x + _FaceUVSpeedX * _Time.y, input.uv2_FaceTex.y + _FaceUVSpeedY * _Time.y));
outlineColor *= tex2D(_OutlineTex, float2(input.uv2_OutlineTex.x + _OutlineUVSpeedX * _Time.y, input.uv2_OutlineTex.y + _OutlineUVSpeedY * _Time.y));
faceColor = GetColor(sd, faceColor, outlineColor, outline, softness);
faceColor.rgb /= max(faceColor.a, 0.0001);
#if BEVEL_ON
float3 delta = float3(1.0 / _TextureWidth, 1.0 / _TextureHeight, 0.0);
float4 smp4x = {tex2D(_MainTex, input.uv_MainTex - delta.xz).a,
tex2D(_MainTex, input.uv_MainTex + delta.xz).a,
tex2D(_MainTex, input.uv_MainTex - delta.zy).a,
tex2D(_MainTex, input.uv_MainTex + delta.zy).a };
// Face Normal
float3 n = GetSurfaceNormal(smp4x, input.param.x);
// Bumpmap
float3 bump = UnpackNormal(tex2D(_BumpMap, input.uv2_FaceTex.xy)).xyz;
bump *= lerp(_BumpFace, _BumpOutline, saturate(sd + outline * 0.5));
bump = lerp(float3(0, 0, 1), bump, faceColor.a);
n = normalize(n - bump);
// Cubemap reflection
fixed4 reflcol = texCUBE(_Cube, reflect(input.viewDirEnv, mul((float3x3)unity_ObjectToWorld, n)));
float3 emission = reflcol.rgb * lerp(_ReflectFaceColor.rgb, _ReflectOutlineColor.rgb, saturate(sd + outline * 0.5)) * faceColor.a;
#else
float3 n = float3(0, 0, -1);
float3 emission = float3(0, 0, 0);
#endif
#if GLOW_ON
float4 glowColor = GetGlowColor(sd, scale);
glowColor.a *= input.color.a;
emission += glowColor.rgb*glowColor.a;
faceColor = BlendARGB(glowColor, faceColor);
faceColor.rgb /= max(faceColor.a, 0.0001);
#endif
// Set Standard output structure
o.Albedo = faceColor.rgb;
o.Normal = -n;
o.Emission = emission;
o.Specular = lerp(_FaceShininess, _OutlineShininess, saturate(sd + outline * 0.5));
o.Gloss = 1;
o.Alpha = faceColor.a;
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0511409892ffdb7409b52349d8ceceee
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -731,7 +731,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 11499388, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} - target: {fileID: 11499388, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3}
propertyPath: m_EditorResourceMode propertyPath: m_EditorResourceMode
value: 1 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 11499388, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} - target: {fileID: 11499388, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3}
propertyPath: m_JsonHelperTypeName propertyPath: m_JsonHelperTypeName
@ -1426,14 +1426,13 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 8a558ebbc9cb4d94946ac9f4f27914d8, type: 3} m_Script: {fileID: 11500000, guid: 8a558ebbc9cb4d94946ac9f4f27914d8, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_useSimulationMovement: 1
_useJobSimulation: 1
_useBurstJobs: 1
_enemySeparationCellSize: 0 _enemySeparationCellSize: 0
_enemySeparationPushDamping: 0.5 _enemySeparationPushDamping: 0.5
_enemySeparationMaxStepScale: 0.5 _enemySeparationMaxStepScale: 0.5
_enemySeparationUseTangentialInAttackRange: 1 _enemySeparationUseTangentialInAttackRange: 1
_enemySeparationPushSmoothing: 0.55 _enemySeparationPushSmoothing: 0.55
_projectileMaxDistanceFromPlayer: 120
_projectileMaxVerticalOffsetFromPlayer: 30
_projectileHitPresentationEnabled: 1 _projectileHitPresentationEnabled: 1
_projectileHitMarkerEnabled: 1 _projectileHitMarkerEnabled: 1
_projectileHitMarkerSize: 0.2 _projectileHitMarkerSize: 0.2
@ -1442,16 +1441,17 @@ MonoBehaviour:
_projectileHitMarkerColor: {r: 1, g: 0, b: 0, a: 0.95} _projectileHitMarkerColor: {r: 1, g: 0, b: 0, a: 0.95}
_projectileHitEffectEnabled: 0 _projectileHitEffectEnabled: 0
_projectileHitEffectTypeId: 0 _projectileHitEffectTypeId: 0
_projectileMaxDistanceFromPlayer: 120 _useSimulationMovement: 1
_projectileMaxVerticalOffsetFromPlayer: 30 _collisionPipelineSettings:
_projectileCollisionQueryRadius: 0.35 ProjectileCollisionQueryRadius: 0.35
_projectileMaxCandidatesPerQuery: 1 ProjectileMaxCandidatesPerQuery: 1
_projectileCollisionCellSize: 0 ProjectileCollisionCellSize: 0
_dispatchProjectileHitPresentationEvent: 1 DispatchProjectileHitPresentationEvent: 1
_dispatchProjectileHitMarkerEvent: 1 DispatchProjectileHitMarkerEvent: 1
_dispatchProjectileHitEffectEvent: 1 DispatchProjectileHitEffectEvent: 1
_projectileHitPresentationEffectTypeId: 0 ProjectileHitPresentationEffectTypeId: 0
_targetSelectionCellSize: 2 _targetSelectionSettings:
CellSize: 2
--- !u!1 &1852670052 --- !u!1 &1852670052
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -97,20 +97,11 @@ namespace Simulation.Tests.Editor
private static readonly MethodInfo TryGetNearestEnemyEntityIdMethod = private static readonly MethodInfo TryGetNearestEnemyEntityIdMethod =
SimulationWorldType?.GetMethod("TryGetNearestEnemyEntityId", PublicInstance); SimulationWorldType?.GetMethod("TryGetNearestEnemyEntityId", PublicInstance);
private static readonly MethodInfo TryEnqueueAreaCollisionQueryMethod = private static readonly MethodInfo TryRequestAreaCollisionMethod =
SimulationWorldType?.GetMethod("TryEnqueueAreaCollisionQuery", PublicInstance); SimulationWorldType?.GetMethod("TryRequestAreaCollision", PublicInstance);
private static readonly MethodInfo SetUseSimulationMovementMethod = private static readonly MethodInfo ClearSimulationStateMethod =
SimulationWorldType?.GetMethod("SetUseSimulationMovement", PublicInstance); SimulationWorldType?.GetMethod("ClearSimulationState", PublicInstance);
private static readonly MethodInfo SetUseJobSimulationMethod =
SimulationWorldType?.GetMethod("SetUseJobSimulation", PublicInstance);
private static readonly MethodInfo SetUseBurstJobsMethod =
SimulationWorldType?.GetMethod("SetUseBurstJobs", PublicInstance);
private static readonly MethodInfo ClearMethod =
SimulationWorldType?.GetMethod("Clear", PublicInstance);
private static readonly MethodInfo UseGridBucketSolverMethod = private static readonly MethodInfo UseGridBucketSolverMethod =
EnemySeparationSolverProviderType?.GetMethod("UseGridBucketSolver", PublicStatic); EnemySeparationSolverProviderType?.GetMethod("UseGridBucketSolver", PublicStatic);
@ -118,8 +109,14 @@ namespace Simulation.Tests.Editor
private static readonly FieldInfo EntitySyncField = private static readonly FieldInfo EntitySyncField =
SimulationWorldType?.GetField("_entitySync", NonPublicInstance); SimulationWorldType?.GetField("_entitySync", NonPublicInstance);
private static readonly FieldInfo PresentationField = private static readonly FieldInfo TransformSyncField =
SimulationWorldType?.GetField("_presentation", NonPublicInstance); SimulationWorldType?.GetField("_transformSync", NonPublicInstance);
private static readonly FieldInfo HitPresentationField =
SimulationWorldType?.GetField("_hitPresentation", NonPublicInstance);
private static readonly FieldInfo UseSimulationMovementField =
SimulationWorldType?.GetField("_useSimulationMovement", NonPublicInstance);
private static readonly PropertyInfo EnemiesProperty = private static readonly PropertyInfo EnemiesProperty =
SimulationWorldType?.GetProperty("Enemies", PublicInstance); SimulationWorldType?.GetProperty("Enemies", PublicInstance);
@ -133,9 +130,6 @@ namespace Simulation.Tests.Editor
private static readonly PropertyInfo UseSimulationMovementProperty = private static readonly PropertyInfo UseSimulationMovementProperty =
SimulationWorldType?.GetProperty("UseSimulationMovement", PublicInstance); SimulationWorldType?.GetProperty("UseSimulationMovement", PublicInstance);
private static readonly PropertyInfo UseJobSimulationProperty =
SimulationWorldType?.GetProperty("UseJobSimulation", PublicInstance);
private static readonly PropertyInfo LastResolvedAreaHitCountProperty = private static readonly PropertyInfo LastResolvedAreaHitCountProperty =
SimulationWorldType?.GetProperty("LastResolvedAreaHitCount", PublicInstance); SimulationWorldType?.GetProperty("LastResolvedAreaHitCount", PublicInstance);
@ -226,17 +220,14 @@ namespace Simulation.Tests.Editor
Assert.NotNull(TryGetEnemyDataMethod, "TryGetEnemyData reflection lookup failed."); Assert.NotNull(TryGetEnemyDataMethod, "TryGetEnemyData reflection lookup failed.");
Assert.NotNull(TickMethod, "Tick reflection lookup failed."); Assert.NotNull(TickMethod, "Tick reflection lookup failed.");
Assert.NotNull(TryGetNearestEnemyEntityIdMethod, "TryGetNearestEnemyEntityId reflection lookup failed."); Assert.NotNull(TryGetNearestEnemyEntityIdMethod, "TryGetNearestEnemyEntityId reflection lookup failed.");
Assert.NotNull(TryEnqueueAreaCollisionQueryMethod, "TryEnqueueAreaCollisionQuery reflection lookup failed."); Assert.NotNull(TryRequestAreaCollisionMethod, "TryRequestAreaCollision reflection lookup failed.");
Assert.NotNull(SetUseSimulationMovementMethod, "SetUseSimulationMovement reflection lookup failed."); Assert.NotNull(ClearSimulationStateMethod, "ClearSimulationState reflection lookup failed.");
Assert.NotNull(SetUseJobSimulationMethod, "SetUseJobSimulation reflection lookup failed.");
Assert.NotNull(SetUseBurstJobsMethod, "SetUseBurstJobs reflection lookup failed.");
Assert.NotNull(ClearMethod, "Clear reflection lookup failed.");
Assert.NotNull(UseGridBucketSolverMethod, "UseGridBucketSolver reflection lookup failed."); Assert.NotNull(UseGridBucketSolverMethod, "UseGridBucketSolver reflection lookup failed.");
Assert.NotNull(EnemiesProperty, "Enemies property reflection lookup failed."); Assert.NotNull(EnemiesProperty, "Enemies property reflection lookup failed.");
Assert.NotNull(ProjectilesProperty, "Projectiles property reflection lookup failed."); Assert.NotNull(ProjectilesProperty, "Projectiles property reflection lookup failed.");
Assert.NotNull(CollisionCandidateCountProperty, "CollisionCandidateCount property reflection lookup failed."); Assert.NotNull(CollisionCandidateCountProperty, "CollisionCandidateCount property reflection lookup failed.");
Assert.NotNull(UseSimulationMovementProperty, "UseSimulationMovement property reflection lookup failed."); Assert.NotNull(UseSimulationMovementProperty, "UseSimulationMovement property reflection lookup failed.");
Assert.NotNull(UseJobSimulationProperty, "UseJobSimulation property reflection lookup failed."); Assert.NotNull(UseSimulationMovementField, "_useSimulationMovement field reflection lookup failed.");
Assert.NotNull(LastResolvedAreaHitCountProperty, "LastResolvedAreaHitCount property reflection lookup failed."); Assert.NotNull(LastResolvedAreaHitCountProperty, "LastResolvedAreaHitCount property reflection lookup failed.");
Assert.NotNull(CollisionQueryInputsField, "Collision query inputs field reflection lookup failed."); Assert.NotNull(CollisionQueryInputsField, "Collision query inputs field reflection lookup failed.");
Assert.NotNull(AreaCollisionRequestsField, "Area collision requests field reflection lookup failed."); Assert.NotNull(AreaCollisionRequestsField, "Area collision requests field reflection lookup failed.");
@ -264,7 +255,7 @@ namespace Simulation.Tests.Editor
_worldGameObject = new GameObject("SimulationWorldTickTests"); _worldGameObject = new GameObject("SimulationWorldTickTests");
_worldComponent = _worldGameObject.AddComponent(SimulationWorldType); _worldComponent = _worldGameObject.AddComponent(SimulationWorldType);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(true);
UseGridBucketSolverMethod.Invoke(null, new object[] { 1f }); UseGridBucketSolverMethod.Invoke(null, new object[] { 1f });
} }
@ -274,7 +265,8 @@ namespace Simulation.Tests.Editor
if (_worldComponent != null) if (_worldComponent != null)
{ {
EntitySyncField?.SetValue(_worldComponent, null); EntitySyncField?.SetValue(_worldComponent, null);
PresentationField?.SetValue(_worldComponent, null); TransformSyncField?.SetValue(_worldComponent, null);
HitPresentationField?.SetValue(_worldComponent, null);
} }
if (_worldGameObject != null) if (_worldGameObject != null)
@ -340,7 +332,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickEnemies_ChasesPlayer_WhenJobSimulationChannelEnabled() public void TickEnemies_ChasesPlayer_WhenJobSimulationChannelEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 1101, position: Vector3.zero, speed: 2f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 1101, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f)); InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@ -355,10 +346,8 @@ namespace Simulation.Tests.Editor
} }
[Test] [Test]
public void TickEnemies_MatchesOutput_WhenBurstJobsToggled() public void TickEnemies_MatchesOutput_AfterClearSimulationState()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseBurstJobsMethod.Invoke(_worldComponent, new object[] { false });
UpsertEnemy(CreateEnemy(entityId: 1151, position: Vector3.zero, speed: 2f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 1151, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f)); InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@ -367,11 +356,9 @@ namespace Simulation.Tests.Editor
Vector3 nonBurstPosition = (Vector3)GetField(nonBurstEnemy, "Position"); Vector3 nonBurstPosition = (Vector3)GetField(nonBurstEnemy, "Position");
Vector3 nonBurstForward = (Vector3)GetField(nonBurstEnemy, "Forward"); Vector3 nonBurstForward = (Vector3)GetField(nonBurstEnemy, "Forward");
ClearMethod.Invoke(_worldComponent, null); ClearSimulationStateMethod.Invoke(_worldComponent, null);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(true);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseBurstJobsMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 1151, position: Vector3.zero, speed: 2f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 1151, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f)); InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@ -388,7 +375,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TryGetNearestEnemyEntityId_SelectsNearestBucketCandidate_WhenJobSimulationEnabled() public void TryGetNearestEnemyEntityId_SelectsNearestBucketCandidate_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 1201, position: new Vector3(1f, 0f, 0f), speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 1201, position: new Vector3(1f, 0f, 0f), speed: 0f, attackRange: 1f));
UpsertEnemy(CreateEnemy(entityId: 1202, position: new Vector3(6f, 0f, 0f), speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 1202, position: new Vector3(6f, 0f, 0f), speed: 0f, attackRange: 1f));
@ -405,7 +391,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickEnemies_SeparatesOverlappedEnemies_WhenJobSimulationEnabled() public void TickEnemies_SeparatesOverlappedEnemies_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 1301, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 0.1f, UpsertEnemy(CreateEnemy(entityId: 1301, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 0.1f,
avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 2)); avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 2));
UpsertEnemy(CreateEnemy(entityId: 1302, position: new Vector3(0.1f, 0f, 0f), speed: 1f, attackRange: 0.1f, UpsertEnemy(CreateEnemy(entityId: 1302, position: new Vector3(0.1f, 0f, 0f), speed: 1f, attackRange: 0.1f,
@ -426,7 +411,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickEnemies_SeparatesOverlappedEnemies_WhenPlayerIsStaticAndInRange() public void TickEnemies_SeparatesOverlappedEnemies_WhenPlayerIsStaticAndInRange()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 1311, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 10f, UpsertEnemy(CreateEnemy(entityId: 1311, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 10f,
avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 3)); avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 3));
UpsertEnemy(CreateEnemy(entityId: 1312, position: new Vector3(0.05f, 0f, 0f), speed: 1f, attackRange: 10f, UpsertEnemy(CreateEnemy(entityId: 1312, position: new Vector3(0.05f, 0f, 0f), speed: 1f, attackRange: 10f,
@ -450,7 +434,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_MovesAndUpdatesLifetime_WhenJobSimulationEnabled() public void TickProjectiles_MovesAndUpdatesLifetime_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5101, position: Vector3.zero, forward: Vector3.right, UpsertProjectile(CreateProjectile(entityId: 5101, position: Vector3.zero, forward: Vector3.right,
velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 2f, age: 0f, active: true, velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 2f, age: 0f, active: true,
remainingLifetime: 2f, state: 0)); remainingLifetime: 2f, state: 0));
@ -471,9 +454,8 @@ namespace Simulation.Tests.Editor
} }
[Test] [Test]
public void TickProjectiles_ResumesFromLatestState_AfterTogglingJobSimulation() public void TickProjectiles_ContinuesFromLatestState_AcrossConsecutiveTicks()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5110, position: Vector3.zero, forward: Vector3.right, UpsertProjectile(CreateProjectile(entityId: 5110, position: Vector3.zero, forward: Vector3.right,
velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 5f, age: 0f, active: true, velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 5f, age: 0f, active: true,
remainingLifetime: 5f, state: 0)); remainingLifetime: 5f, state: 0));
@ -485,32 +467,23 @@ namespace Simulation.Tests.Editor
Assert.That(positionAfterJobEnabled.x, Is.EqualTo(1f).Within(0.0001f)); Assert.That(positionAfterJobEnabled.x, Is.EqualTo(1f).Within(0.0001f));
Assert.That(ageAfterJobEnabled, Is.EqualTo(0.5f).Within(0.0001f)); Assert.That(ageAfterJobEnabled, Is.EqualTo(0.5f).Within(0.0001f));
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false });
InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero); InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero);
object afterJobDisabled = GetProjectileAt(0); object afterSecondTick = GetProjectileAt(0);
Vector3 positionAfterJobDisabled = (Vector3)GetField(afterJobDisabled, "Position"); Vector3 positionAfterSecondTick = (Vector3)GetField(afterSecondTick, "Position");
float ageAfterJobDisabled = (float)GetField(afterJobDisabled, "Age"); float ageAfterSecondTick = (float)GetField(afterSecondTick, "Age");
Assert.That(positionAfterJobDisabled.x, Is.EqualTo(1f).Within(0.0001f)); float remainingLifetimeAfterSecondTick = (float)GetField(afterSecondTick, "RemainingLifetime");
Assert.That(ageAfterJobDisabled, Is.EqualTo(0.5f).Within(0.0001f)); bool activeAfterSecondTick = (bool)GetField(afterSecondTick, "Active");
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true }); Assert.That(positionAfterSecondTick.x, Is.EqualTo(2f).Within(0.0001f));
InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero); Assert.That(ageAfterSecondTick, Is.EqualTo(1f).Within(0.0001f));
object afterJobReEnabled = GetProjectileAt(0); Assert.That(remainingLifetimeAfterSecondTick, Is.EqualTo(4f).Within(0.0001f));
Vector3 positionAfterJobReEnabled = (Vector3)GetField(afterJobReEnabled, "Position"); Assert.IsTrue(activeAfterSecondTick);
float ageAfterJobReEnabled = (float)GetField(afterJobReEnabled, "Age");
float remainingLifetimeAfterJobReEnabled = (float)GetField(afterJobReEnabled, "RemainingLifetime");
bool activeAfterJobReEnabled = (bool)GetField(afterJobReEnabled, "Active");
Assert.That(positionAfterJobReEnabled.x, Is.EqualTo(2f).Within(0.0001f));
Assert.That(ageAfterJobReEnabled, Is.EqualTo(1f).Within(0.0001f));
Assert.That(remainingLifetimeAfterJobReEnabled, Is.EqualTo(4f).Within(0.0001f));
Assert.IsTrue(activeAfterJobReEnabled);
} }
[Test] [Test]
public void EnemyProjectile_TogglesCollider_WhenJobSimulationSwitchesAtRuntime() public void EnemyProjectile_TogglesCollider_WhenSimulationMovementSwitchesAtRuntime()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false }); SetUseSimulationMovement(false);
GameObject projectileObject = new GameObject("EnemyProjectileColliderToggleEditMode"); GameObject projectileObject = new GameObject("EnemyProjectileColliderToggleEditMode");
try try
@ -538,11 +511,11 @@ namespace Simulation.Tests.Editor
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f); InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsTrue(projectileCollider.enabled); Assert.IsTrue(projectileCollider.enabled);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(true);
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f); InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsFalse(projectileCollider.enabled); Assert.IsFalse(projectileCollider.enabled);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false }); SetUseSimulationMovement(false);
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f); InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsTrue(projectileCollider.enabled); Assert.IsTrue(projectileCollider.enabled);
} }
@ -582,7 +555,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_RecyclesWhenExceedingPlayerDistance_WhenJobSimulationEnabled() public void TickProjectiles_RecyclesWhenExceedingPlayerDistance_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 5f); ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 5f);
ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1000f); ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1000f);
UpsertProjectile(CreateProjectile(entityId: 5108, position: new Vector3(6f, 0f, 0f), UpsertProjectile(CreateProjectile(entityId: 5108, position: new Vector3(6f, 0f, 0f),
@ -597,7 +569,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_RecyclesWhenExceedingVerticalOffset_WhenJobSimulationEnabled() public void TickProjectiles_RecyclesWhenExceedingVerticalOffset_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 0f); ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 0f);
ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1f); ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1f);
UpsertProjectile(CreateProjectile(entityId: 5109, position: new Vector3(0f, 2f, 0f), UpsertProjectile(CreateProjectile(entityId: 5109, position: new Vector3(0f, 2f, 0f),
@ -612,7 +583,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_RecyclesExpiredProjectile_WhenJobSimulationEnabled() public void TickProjectiles_RecyclesExpiredProjectile_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5102, position: Vector3.zero, forward: Vector3.forward, UpsertProjectile(CreateProjectile(entityId: 5102, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 1f, age: 0.95f, active: true, remainingLifetime: 0.05f, velocity: Vector3.zero, speed: 0f, lifeTime: 1f, age: 0.95f, active: true, remainingLifetime: 0.05f,
state: 0)); state: 0));
@ -625,7 +595,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_BuildsCollisionCandidatesAgainstEnemies_WhenJobSimulationEnabled() public void TickProjectiles_BuildsCollisionCandidatesAgainstEnemies_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5201, position: Vector3.zero, speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 5201, position: Vector3.zero, speed: 0f, attackRange: 1f));
UpsertProjectile(CreateProjectile(entityId: 5202, position: Vector3.zero, forward: Vector3.forward, UpsertProjectile(CreateProjectile(entityId: 5202, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, remainingLifetime: 2f, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, remainingLifetime: 2f,
@ -639,7 +608,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_BuildsCollisionCandidates_WithLatestEnemyMovement_WhenJobSimulationEnabled() public void TickProjectiles_BuildsCollisionCandidates_WithLatestEnemyMovement_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5211, position: new Vector3(2f, 0f, 0f), speed: 1f, attackRange: 0.1f)); UpsertEnemy(CreateEnemy(entityId: 5211, position: new Vector3(2f, 0f, 0f), speed: 1f, attackRange: 0.1f));
UpsertProjectile(CreateProjectile(entityId: 5212, position: new Vector3(1f, 0f, 0f), UpsertProjectile(CreateProjectile(entityId: 5212, position: new Vector3(1f, 0f, 0f),
forward: Vector3.forward, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, forward: Vector3.forward, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true,
@ -653,7 +621,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_ExpiresAfterCollisionCandidateConsumed_WhenJobSimulationEnabled() public void TickProjectiles_ExpiresAfterCollisionCandidateConsumed_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5203, position: Vector3.zero, speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 5203, position: Vector3.zero, speed: 0f, attackRange: 1f));
UpsertProjectile(CreateProjectile(entityId: 5204, position: Vector3.zero, forward: Vector3.forward, UpsertProjectile(CreateProjectile(entityId: 5204, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 10f, age: 0f, active: true, remainingLifetime: 10f, velocity: Vector3.zero, speed: 0f, lifeTime: 10f, age: 0f, active: true, remainingLifetime: 10f,
@ -667,7 +634,6 @@ namespace Simulation.Tests.Editor
[Test] [Test]
public void TickProjectiles_LimitsCandidatesToMaxTargets_IncludingPlayerCandidate() public void TickProjectiles_LimitsCandidatesToMaxTargets_IncludingPlayerCandidate()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
object previousEnemyManager = GetGameEntryEnemyManager(); object previousEnemyManager = GetGameEntryEnemyManager();
GameObject enemyManagerObject = new GameObject("EnemyManagerMaxTargetsEditMode"); GameObject enemyManagerObject = new GameObject("EnemyManagerMaxTargetsEditMode");
GameObject playerObject = new GameObject("PlayerTargetMaxTargetsEditMode"); GameObject playerObject = new GameObject("PlayerTargetMaxTargetsEditMode");
@ -707,49 +673,23 @@ namespace Simulation.Tests.Editor
} }
[Test] [Test]
public void SetUseSimulationAndJob_AreIgnored_WhenBattleStateIsActive() public void TryRequestAreaCollision_ReturnsFalse_WhenSimulationMovementDisabled()
{ {
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(false);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false }); object[] requestArgs = { 5230, 5230, Vector3.zero, 1f, 1 };
bool requestResult = (bool)TryRequestAreaCollisionMethod.Invoke(_worldComponent, requestArgs);
object previousProcedure = GetGameEntryProcedure(); Assert.IsFalse(requestResult);
GameObject procedureObject = new GameObject("ProcedureGuardEditMode"); Assert.IsFalse((bool)UseSimulationMovementProperty.GetValue(_worldComponent));
try
{
Component procedureComponent = procedureObject.AddComponent(ProcedureComponentType);
object procedureManager = Activator.CreateInstance(ProcedureManagerType);
Type fsmType = FsmOpenGenericType.MakeGenericType(ProcedureManagerInterfaceType);
object fsm = Activator.CreateInstance(fsmType);
object procedureGame = Activator.CreateInstance(ProcedureGameType);
object battleState = Enum.Parse(GameStateTypeType, "Battle");
SetPrivateField(procedureGame, "_currentGameState", battleState);
SetPrivateField(fsm, "m_CurrentState", procedureGame);
SetPrivateField(procedureManager, "m_ProcedureFsm", fsm);
SetPrivateField(procedureComponent, "m_ProcedureManager", procedureManager);
SetGameEntryProcedure(procedureComponent);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { false });
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
Assert.IsTrue((bool)UseSimulationMovementProperty.GetValue(_worldComponent));
Assert.IsFalse((bool)UseJobSimulationProperty.GetValue(_worldComponent));
}
finally
{
SetGameEntryProcedure(previousProcedure);
Object.DestroyImmediate(procedureObject);
}
} }
[Test] [Test]
public void EnqueueAreaQuery_CapturesInactiveSourceSnapshot_WhenSourceEntityUnavailable() public void EnqueueAreaQuery_CapturesInactiveSourceSnapshot_WhenSourceEntityUnavailable()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5231, position: Vector3.zero, speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 5231, position: Vector3.zero, speed: 0f, attackRange: 1f));
object[] enqueueArgs = { 99999, 99999, Vector3.zero, 1f, 1 }; object[] enqueueArgs = { 99999, 99999, Vector3.zero, 1f, 1 };
bool enqueueResult = (bool)TryEnqueueAreaCollisionQueryMethod.Invoke(_worldComponent, enqueueArgs); bool enqueueResult = (bool)TryRequestAreaCollisionMethod.Invoke(_worldComponent, enqueueArgs);
Assert.IsTrue(enqueueResult); Assert.IsTrue(enqueueResult);
object areaCollisionRequests = AreaCollisionRequestsField.GetValue(_worldComponent); object areaCollisionRequests = AreaCollisionRequestsField.GetValue(_worldComponent);
@ -818,6 +758,11 @@ namespace Simulation.Tests.Editor
TickMethod.Invoke(_worldComponent, new[] { tickContext }); TickMethod.Invoke(_worldComponent, new[] { tickContext });
} }
private void SetUseSimulationMovement(bool enabled)
{
UseSimulationMovementField.SetValue(_worldComponent, enabled);
}
private void UpsertEnemy(object enemy) private void UpsertEnemy(object enemy)
{ {
UpsertEnemyMethod.Invoke(_worldComponent, new[] { enemy }); UpsertEnemyMethod.Invoke(_worldComponent, new[] { enemy });

View File

@ -95,20 +95,11 @@ namespace Simulation.Tests.PlayMode
private static readonly MethodInfo TryGetNearestEnemyEntityIdMethod = private static readonly MethodInfo TryGetNearestEnemyEntityIdMethod =
SimulationWorldType?.GetMethod("TryGetNearestEnemyEntityId", PublicInstance); SimulationWorldType?.GetMethod("TryGetNearestEnemyEntityId", PublicInstance);
private static readonly MethodInfo TryEnqueueAreaCollisionQueryMethod = private static readonly MethodInfo TryRequestAreaCollisionMethod =
SimulationWorldType?.GetMethod("TryEnqueueAreaCollisionQuery", PublicInstance); SimulationWorldType?.GetMethod("TryRequestAreaCollision", PublicInstance);
private static readonly MethodInfo SetUseSimulationMovementMethod = private static readonly MethodInfo ClearSimulationStateMethod =
SimulationWorldType?.GetMethod("SetUseSimulationMovement", PublicInstance); SimulationWorldType?.GetMethod("ClearSimulationState", PublicInstance);
private static readonly MethodInfo SetUseJobSimulationMethod =
SimulationWorldType?.GetMethod("SetUseJobSimulation", PublicInstance);
private static readonly MethodInfo SetUseBurstJobsMethod =
SimulationWorldType?.GetMethod("SetUseBurstJobs", PublicInstance);
private static readonly MethodInfo ClearMethod =
SimulationWorldType?.GetMethod("Clear", PublicInstance);
private static readonly MethodInfo UseGridBucketSolverMethod = private static readonly MethodInfo UseGridBucketSolverMethod =
EnemySeparationSolverProviderType?.GetMethod("UseGridBucketSolver", PublicStatic); EnemySeparationSolverProviderType?.GetMethod("UseGridBucketSolver", PublicStatic);
@ -116,8 +107,14 @@ namespace Simulation.Tests.PlayMode
private static readonly FieldInfo EntitySyncField = private static readonly FieldInfo EntitySyncField =
SimulationWorldType?.GetField("_entitySync", NonPublicInstance); SimulationWorldType?.GetField("_entitySync", NonPublicInstance);
private static readonly FieldInfo PresentationField = private static readonly FieldInfo TransformSyncField =
SimulationWorldType?.GetField("_presentation", NonPublicInstance); SimulationWorldType?.GetField("_transformSync", NonPublicInstance);
private static readonly FieldInfo HitPresentationField =
SimulationWorldType?.GetField("_hitPresentation", NonPublicInstance);
private static readonly FieldInfo UseSimulationMovementField =
SimulationWorldType?.GetField("_useSimulationMovement", NonPublicInstance);
private static readonly PropertyInfo EnemiesProperty = private static readonly PropertyInfo EnemiesProperty =
SimulationWorldType?.GetProperty("Enemies", PublicInstance); SimulationWorldType?.GetProperty("Enemies", PublicInstance);
@ -131,9 +128,6 @@ namespace Simulation.Tests.PlayMode
private static readonly PropertyInfo UseSimulationMovementProperty = private static readonly PropertyInfo UseSimulationMovementProperty =
SimulationWorldType?.GetProperty("UseSimulationMovement", PublicInstance); SimulationWorldType?.GetProperty("UseSimulationMovement", PublicInstance);
private static readonly PropertyInfo UseJobSimulationProperty =
SimulationWorldType?.GetProperty("UseJobSimulation", PublicInstance);
private static readonly PropertyInfo LastResolvedAreaHitCountProperty = private static readonly PropertyInfo LastResolvedAreaHitCountProperty =
SimulationWorldType?.GetProperty("LastResolvedAreaHitCount", PublicInstance); SimulationWorldType?.GetProperty("LastResolvedAreaHitCount", PublicInstance);
@ -223,17 +217,14 @@ namespace Simulation.Tests.PlayMode
Assert.NotNull(TryGetEnemyDataMethod, "TryGetEnemyData reflection lookup failed."); Assert.NotNull(TryGetEnemyDataMethod, "TryGetEnemyData reflection lookup failed.");
Assert.NotNull(TickMethod, "Tick reflection lookup failed."); Assert.NotNull(TickMethod, "Tick reflection lookup failed.");
Assert.NotNull(TryGetNearestEnemyEntityIdMethod, "TryGetNearestEnemyEntityId reflection lookup failed."); Assert.NotNull(TryGetNearestEnemyEntityIdMethod, "TryGetNearestEnemyEntityId reflection lookup failed.");
Assert.NotNull(TryEnqueueAreaCollisionQueryMethod, "TryEnqueueAreaCollisionQuery reflection lookup failed."); Assert.NotNull(TryRequestAreaCollisionMethod, "TryRequestAreaCollision reflection lookup failed.");
Assert.NotNull(SetUseSimulationMovementMethod, "SetUseSimulationMovement reflection lookup failed."); Assert.NotNull(ClearSimulationStateMethod, "ClearSimulationState reflection lookup failed.");
Assert.NotNull(SetUseJobSimulationMethod, "SetUseJobSimulation reflection lookup failed.");
Assert.NotNull(SetUseBurstJobsMethod, "SetUseBurstJobs reflection lookup failed.");
Assert.NotNull(ClearMethod, "Clear reflection lookup failed.");
Assert.NotNull(UseGridBucketSolverMethod, "UseGridBucketSolver reflection lookup failed."); Assert.NotNull(UseGridBucketSolverMethod, "UseGridBucketSolver reflection lookup failed.");
Assert.NotNull(EnemiesProperty, "Enemies property reflection lookup failed."); Assert.NotNull(EnemiesProperty, "Enemies property reflection lookup failed.");
Assert.NotNull(ProjectilesProperty, "Projectiles property reflection lookup failed."); Assert.NotNull(ProjectilesProperty, "Projectiles property reflection lookup failed.");
Assert.NotNull(CollisionCandidateCountProperty, "CollisionCandidateCount property reflection lookup failed."); Assert.NotNull(CollisionCandidateCountProperty, "CollisionCandidateCount property reflection lookup failed.");
Assert.NotNull(UseSimulationMovementProperty, "UseSimulationMovement property reflection lookup failed."); Assert.NotNull(UseSimulationMovementProperty, "UseSimulationMovement property reflection lookup failed.");
Assert.NotNull(UseJobSimulationProperty, "UseJobSimulation property reflection lookup failed."); Assert.NotNull(UseSimulationMovementField, "_useSimulationMovement field reflection lookup failed.");
Assert.NotNull(LastResolvedAreaHitCountProperty, "LastResolvedAreaHitCount property reflection lookup failed."); Assert.NotNull(LastResolvedAreaHitCountProperty, "LastResolvedAreaHitCount property reflection lookup failed.");
Assert.NotNull(CollisionQueryInputsField, "Collision query inputs field reflection lookup failed."); Assert.NotNull(CollisionQueryInputsField, "Collision query inputs field reflection lookup failed.");
Assert.NotNull(AreaCollisionRequestsField, "Area collision requests field reflection lookup failed."); Assert.NotNull(AreaCollisionRequestsField, "Area collision requests field reflection lookup failed.");
@ -264,9 +255,10 @@ namespace Simulation.Tests.PlayMode
// Isolate PlayMode regression to simulation behavior only. // Isolate PlayMode regression to simulation behavior only.
EntitySyncField?.SetValue(_worldComponent, null); EntitySyncField?.SetValue(_worldComponent, null);
PresentationField?.SetValue(_worldComponent, null); TransformSyncField?.SetValue(_worldComponent, null);
HitPresentationField?.SetValue(_worldComponent, null);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(true);
UseGridBucketSolverMethod.Invoke(null, new object[] { 1f }); UseGridBucketSolverMethod.Invoke(null, new object[] { 1f });
yield return null; yield return null;
} }
@ -277,7 +269,8 @@ namespace Simulation.Tests.PlayMode
if (_worldComponent != null) if (_worldComponent != null)
{ {
EntitySyncField?.SetValue(_worldComponent, null); EntitySyncField?.SetValue(_worldComponent, null);
PresentationField?.SetValue(_worldComponent, null); TransformSyncField?.SetValue(_worldComponent, null);
HitPresentationField?.SetValue(_worldComponent, null);
} }
if (_worldGameObject != null) if (_worldGameObject != null)
@ -347,7 +340,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickEnemies_ChasesPlayer_WhenJobSimulationChannelEnabled() public IEnumerator TickEnemies_ChasesPlayer_WhenJobSimulationChannelEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3201, position: Vector3.zero, speed: 2f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 3201, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f)); InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@ -363,10 +355,8 @@ namespace Simulation.Tests.PlayMode
} }
[UnityTest] [UnityTest]
public IEnumerator TickEnemies_MatchesOutput_WhenBurstJobsToggled() public IEnumerator TickEnemies_MatchesOutput_AfterClearSimulationState()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseBurstJobsMethod.Invoke(_worldComponent, new object[] { false });
UpsertEnemy(CreateEnemy(entityId: 3251, position: Vector3.zero, speed: 2f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 3251, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f)); InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@ -375,11 +365,9 @@ namespace Simulation.Tests.PlayMode
Vector3 nonBurstPosition = (Vector3)GetField(nonBurstEnemy, "Position"); Vector3 nonBurstPosition = (Vector3)GetField(nonBurstEnemy, "Position");
Vector3 nonBurstForward = (Vector3)GetField(nonBurstEnemy, "Forward"); Vector3 nonBurstForward = (Vector3)GetField(nonBurstEnemy, "Forward");
ClearMethod.Invoke(_worldComponent, null); ClearSimulationStateMethod.Invoke(_worldComponent, null);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(true);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseBurstJobsMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3251, position: Vector3.zero, speed: 2f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 3251, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f)); InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@ -397,7 +385,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TryGetNearestEnemyEntityId_SelectsNearestBucketCandidate_WhenJobSimulationEnabled() public IEnumerator TryGetNearestEnemyEntityId_SelectsNearestBucketCandidate_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3301, position: new Vector3(1f, 0f, 0f), speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 3301, position: new Vector3(1f, 0f, 0f), speed: 0f, attackRange: 1f));
UpsertEnemy(CreateEnemy(entityId: 3302, position: new Vector3(6f, 0f, 0f), speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 3302, position: new Vector3(6f, 0f, 0f), speed: 0f, attackRange: 1f));
@ -415,7 +402,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickEnemies_SeparatesOverlappedEnemies_WhenJobSimulationEnabled() public IEnumerator TickEnemies_SeparatesOverlappedEnemies_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3401, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 0.1f, UpsertEnemy(CreateEnemy(entityId: 3401, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 0.1f,
avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 2)); avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 2));
UpsertEnemy(CreateEnemy(entityId: 3402, position: new Vector3(0.1f, 0f, 0f), speed: 1f, attackRange: 0.1f, UpsertEnemy(CreateEnemy(entityId: 3402, position: new Vector3(0.1f, 0f, 0f), speed: 1f, attackRange: 0.1f,
@ -437,7 +423,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickEnemies_SeparatesOverlappedEnemies_WhenPlayerIsStaticAndInRange() public IEnumerator TickEnemies_SeparatesOverlappedEnemies_WhenPlayerIsStaticAndInRange()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3411, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 10f, UpsertEnemy(CreateEnemy(entityId: 3411, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 10f,
avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 3)); avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 3));
UpsertEnemy(CreateEnemy(entityId: 3412, position: new Vector3(0.05f, 0f, 0f), speed: 1f, attackRange: 10f, UpsertEnemy(CreateEnemy(entityId: 3412, position: new Vector3(0.05f, 0f, 0f), speed: 1f, attackRange: 10f,
@ -462,7 +447,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_MovesAndUpdatesLifetime_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_MovesAndUpdatesLifetime_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5401, position: Vector3.zero, forward: Vector3.right, UpsertProjectile(CreateProjectile(entityId: 5401, position: Vector3.zero, forward: Vector3.right,
velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 2f, age: 0f, active: true, velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 2f, age: 0f, active: true,
remainingLifetime: 2f, state: 0)); remainingLifetime: 2f, state: 0));
@ -484,9 +468,8 @@ namespace Simulation.Tests.PlayMode
} }
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_ResumesFromLatestState_AfterTogglingJobSimulation() public IEnumerator TickProjectiles_ContinuesFromLatestState_AcrossConsecutiveTicks()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5410, position: Vector3.zero, forward: Vector3.right, UpsertProjectile(CreateProjectile(entityId: 5410, position: Vector3.zero, forward: Vector3.right,
velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 5f, age: 0f, active: true, velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 5f, age: 0f, active: true,
remainingLifetime: 5f, state: 0)); remainingLifetime: 5f, state: 0));
@ -498,33 +481,24 @@ namespace Simulation.Tests.PlayMode
Assert.That(positionAfterJobEnabled.x, Is.EqualTo(1f).Within(0.0001f)); Assert.That(positionAfterJobEnabled.x, Is.EqualTo(1f).Within(0.0001f));
Assert.That(ageAfterJobEnabled, Is.EqualTo(0.5f).Within(0.0001f)); Assert.That(ageAfterJobEnabled, Is.EqualTo(0.5f).Within(0.0001f));
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false });
InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero); InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero);
object afterJobDisabled = GetProjectileAt(0); object afterSecondTick = GetProjectileAt(0);
Vector3 positionAfterJobDisabled = (Vector3)GetField(afterJobDisabled, "Position"); Vector3 positionAfterSecondTick = (Vector3)GetField(afterSecondTick, "Position");
float ageAfterJobDisabled = (float)GetField(afterJobDisabled, "Age"); float ageAfterSecondTick = (float)GetField(afterSecondTick, "Age");
Assert.That(positionAfterJobDisabled.x, Is.EqualTo(1f).Within(0.0001f)); float remainingLifetimeAfterSecondTick = (float)GetField(afterSecondTick, "RemainingLifetime");
Assert.That(ageAfterJobDisabled, Is.EqualTo(0.5f).Within(0.0001f)); bool activeAfterSecondTick = (bool)GetField(afterSecondTick, "Active");
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true }); Assert.That(positionAfterSecondTick.x, Is.EqualTo(2f).Within(0.0001f));
InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero); Assert.That(ageAfterSecondTick, Is.EqualTo(1f).Within(0.0001f));
object afterJobReEnabled = GetProjectileAt(0); Assert.That(remainingLifetimeAfterSecondTick, Is.EqualTo(4f).Within(0.0001f));
Vector3 positionAfterJobReEnabled = (Vector3)GetField(afterJobReEnabled, "Position"); Assert.IsTrue(activeAfterSecondTick);
float ageAfterJobReEnabled = (float)GetField(afterJobReEnabled, "Age");
float remainingLifetimeAfterJobReEnabled = (float)GetField(afterJobReEnabled, "RemainingLifetime");
bool activeAfterJobReEnabled = (bool)GetField(afterJobReEnabled, "Active");
Assert.That(positionAfterJobReEnabled.x, Is.EqualTo(2f).Within(0.0001f));
Assert.That(ageAfterJobReEnabled, Is.EqualTo(1f).Within(0.0001f));
Assert.That(remainingLifetimeAfterJobReEnabled, Is.EqualTo(4f).Within(0.0001f));
Assert.IsTrue(activeAfterJobReEnabled);
yield break; yield break;
} }
[UnityTest] [UnityTest]
public IEnumerator EnemyProjectile_TogglesCollider_WhenJobSimulationSwitchesAtRuntime() public IEnumerator EnemyProjectile_TogglesCollider_WhenSimulationMovementSwitchesAtRuntime()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false }); SetUseSimulationMovement(false);
GameObject projectileObject = new GameObject("EnemyProjectileColliderTogglePlayMode"); GameObject projectileObject = new GameObject("EnemyProjectileColliderTogglePlayMode");
Component projectileComponent = null; Component projectileComponent = null;
@ -553,11 +527,11 @@ namespace Simulation.Tests.PlayMode
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f); InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsTrue(projectileCollider.enabled); Assert.IsTrue(projectileCollider.enabled);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(true);
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f); InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsFalse(projectileCollider.enabled); Assert.IsFalse(projectileCollider.enabled);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false }); SetUseSimulationMovement(false);
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f); InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsTrue(projectileCollider.enabled); Assert.IsTrue(projectileCollider.enabled);
} }
@ -603,7 +577,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_RecyclesWhenExceedingPlayerDistance_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_RecyclesWhenExceedingPlayerDistance_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 5f); ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 5f);
ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1000f); ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1000f);
UpsertProjectile(CreateProjectile(entityId: 5408, position: new Vector3(6f, 0f, 0f), UpsertProjectile(CreateProjectile(entityId: 5408, position: new Vector3(6f, 0f, 0f),
@ -619,7 +592,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_RecyclesWhenExceedingVerticalOffset_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_RecyclesWhenExceedingVerticalOffset_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 0f); ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 0f);
ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1f); ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1f);
UpsertProjectile(CreateProjectile(entityId: 5409, position: new Vector3(0f, 2f, 0f), UpsertProjectile(CreateProjectile(entityId: 5409, position: new Vector3(0f, 2f, 0f),
@ -635,7 +607,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_RecyclesExpiredProjectile_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_RecyclesExpiredProjectile_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5402, position: Vector3.zero, forward: Vector3.forward, UpsertProjectile(CreateProjectile(entityId: 5402, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 1f, age: 0.95f, active: true, remainingLifetime: 0.05f, velocity: Vector3.zero, speed: 0f, lifeTime: 1f, age: 0.95f, active: true, remainingLifetime: 0.05f,
state: 0)); state: 0));
@ -649,7 +620,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_BuildsCollisionCandidatesAgainstEnemies_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_BuildsCollisionCandidatesAgainstEnemies_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5501, position: Vector3.zero, speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 5501, position: Vector3.zero, speed: 0f, attackRange: 1f));
UpsertProjectile(CreateProjectile(entityId: 5502, position: Vector3.zero, forward: Vector3.forward, UpsertProjectile(CreateProjectile(entityId: 5502, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, remainingLifetime: 2f, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, remainingLifetime: 2f,
@ -664,7 +634,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_BuildsCollisionCandidates_WithLatestEnemyMovement_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_BuildsCollisionCandidates_WithLatestEnemyMovement_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5511, position: new Vector3(2f, 0f, 0f), speed: 1f, attackRange: 0.1f)); UpsertEnemy(CreateEnemy(entityId: 5511, position: new Vector3(2f, 0f, 0f), speed: 1f, attackRange: 0.1f));
UpsertProjectile(CreateProjectile(entityId: 5512, position: new Vector3(1f, 0f, 0f), UpsertProjectile(CreateProjectile(entityId: 5512, position: new Vector3(1f, 0f, 0f),
forward: Vector3.forward, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, forward: Vector3.forward, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true,
@ -679,7 +648,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_ExpiresAfterCollisionCandidateConsumed_WhenJobSimulationEnabled() public IEnumerator TickProjectiles_ExpiresAfterCollisionCandidateConsumed_WhenJobSimulationEnabled()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5503, position: Vector3.zero, speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 5503, position: Vector3.zero, speed: 0f, attackRange: 1f));
UpsertProjectile(CreateProjectile(entityId: 5504, position: Vector3.zero, forward: Vector3.forward, UpsertProjectile(CreateProjectile(entityId: 5504, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 10f, age: 0f, active: true, remainingLifetime: 10f, velocity: Vector3.zero, speed: 0f, lifeTime: 10f, age: 0f, active: true, remainingLifetime: 10f,
@ -694,7 +662,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest] [UnityTest]
public IEnumerator TickProjectiles_LimitsCandidatesToMaxTargets_IncludingPlayerCandidate() public IEnumerator TickProjectiles_LimitsCandidatesToMaxTargets_IncludingPlayerCandidate()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
object previousEnemyManager = GetGameEntryEnemyManager(); object previousEnemyManager = GetGameEntryEnemyManager();
GameObject enemyManagerObject = new GameObject("EnemyManagerMaxTargetsPlayMode"); GameObject enemyManagerObject = new GameObject("EnemyManagerMaxTargetsPlayMode");
GameObject playerObject = new GameObject("PlayerTargetMaxTargetsPlayMode"); GameObject playerObject = new GameObject("PlayerTargetMaxTargetsPlayMode");
@ -736,51 +703,25 @@ namespace Simulation.Tests.PlayMode
} }
[UnityTest] [UnityTest]
public IEnumerator SetUseSimulationAndJob_AreIgnored_WhenBattleStateIsActive() public IEnumerator TryRequestAreaCollision_ReturnsFalse_WhenSimulationMovementDisabled()
{ {
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true }); SetUseSimulationMovement(false);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false }); object[] requestArgs = { 5530, 5530, Vector3.zero, 1f, 1 };
bool requestResult = (bool)TryRequestAreaCollisionMethod.Invoke(_worldComponent, requestArgs);
object previousProcedure = GetGameEntryProcedure(); Assert.IsFalse(requestResult);
GameObject procedureObject = new GameObject("ProcedureGuardPlayMode"); Assert.IsFalse((bool)UseSimulationMovementProperty.GetValue(_worldComponent));
try
{
Component procedureComponent = procedureObject.AddComponent(ProcedureComponentType);
object procedureManager = Activator.CreateInstance(ProcedureManagerType);
Type fsmType = FsmOpenGenericType.MakeGenericType(ProcedureManagerInterfaceType);
object fsm = Activator.CreateInstance(fsmType);
object procedureGame = Activator.CreateInstance(ProcedureGameType);
object battleState = Enum.Parse(GameStateTypeType, "Battle");
SetPrivateField(procedureGame, "_currentGameState", battleState); yield break;
SetPrivateField(fsm, "m_CurrentState", procedureGame);
SetPrivateField(procedureManager, "m_ProcedureFsm", fsm);
SetPrivateField(procedureComponent, "m_ProcedureManager", procedureManager);
SetGameEntryProcedure(procedureComponent);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { false });
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
Assert.IsTrue((bool)UseSimulationMovementProperty.GetValue(_worldComponent));
Assert.IsFalse((bool)UseJobSimulationProperty.GetValue(_worldComponent));
}
finally
{
SetGameEntryProcedure(previousProcedure);
Object.Destroy(procedureObject);
}
yield return null;
} }
[UnityTest] [UnityTest]
public IEnumerator EnqueueAreaQuery_CapturesInactiveSourceSnapshot_WhenSourceEntityUnavailable() public IEnumerator EnqueueAreaQuery_CapturesInactiveSourceSnapshot_WhenSourceEntityUnavailable()
{ {
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5531, position: Vector3.zero, speed: 0f, attackRange: 1f)); UpsertEnemy(CreateEnemy(entityId: 5531, position: Vector3.zero, speed: 0f, attackRange: 1f));
object[] enqueueArgs = { 99999, 99999, Vector3.zero, 1f, 1 }; object[] enqueueArgs = { 99999, 99999, Vector3.zero, 1f, 1 };
bool enqueueResult = (bool)TryEnqueueAreaCollisionQueryMethod.Invoke(_worldComponent, enqueueArgs); bool enqueueResult = (bool)TryRequestAreaCollisionMethod.Invoke(_worldComponent, enqueueArgs);
Assert.IsTrue(enqueueResult); Assert.IsTrue(enqueueResult);
object areaCollisionRequests = AreaCollisionRequestsField.GetValue(_worldComponent); object areaCollisionRequests = AreaCollisionRequestsField.GetValue(_worldComponent);
@ -850,6 +791,11 @@ namespace Simulation.Tests.PlayMode
TickMethod.Invoke(_worldComponent, new[] { tickContext }); TickMethod.Invoke(_worldComponent, new[] { tickContext });
} }
private void SetUseSimulationMovement(bool enabled)
{
UseSimulationMovementField.SetValue(_worldComponent, enabled);
}
private void UpsertEnemy(object enemy) private void UpsertEnemy(object enemy)
{ {
UpsertEnemyMethod.Invoke(_worldComponent, new[] { enemy }); UpsertEnemyMethod.Invoke(_worldComponent, new[] { enemy });

View File

@ -240,5 +240,5 @@
- [ ] 风险与回滚说明(特别是热更新与渲染链路)。 - [ ] 风险与回滚说明(特别是热更新与渲染链路)。
## 测试命令 ## 测试命令
- PlayMode: `Unity -batchmode -nographics -projectPath . -runTests -testPlatform PlayMode -testResults Logs/playmode-test-results.xml -logFile Logs/playmode-tests.log` - PlayMode: `& "C:\UnityProjects\Unity Editor\2022.3.62f3c1\Editor\Unity.exe" -batchmode -nographics -projectPath . -runTests -testPlatform PlayMode -testResults Logs/playmode-test-results.xml -logFile Logs/playmode-tests.log`
- EditMode: `Unity -batchmode -nographics -projectPath . -runTests -testPlatform EditMode -testResults Logs/editmode-test-results.xml -logFile Logs/editmode-tests.log` - EditMode: `& "C:\UnityProjects\Unity Editor\2022.3.62f3c1\Editor\Unity.exe" -batchmode -nographics -projectPath . -runTests -testPlatform EditMode -testResults Logs/editmode-test-results.xml -logFile Logs/editmode-tests.log`