问题描述
我在 Unity 中有一个函数,它目前在 Unity 编辑器和 Windows 版本中有效,但在 WebGL 版本中无效。在浏览器中,我收到以下错误:
at System.Math.Sign (System.Double value) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Double.Vector+<>c.<DoPointwiseSign>b__31_0 (System.Double x) [0x00000] in <00000000000000000000000000000000>:0
at System.Func`2[T,TResult].Invoke (T arg) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Storage.DenseVectorStorage`1+<>c__displayClass30_0`1[T,TU].<MapToUnchecked>b__0 (system.int32 a,system.int32 b) [0x00000] in <00000000000000000000000000000000>:0
at System.Action`2[T1,T2].Invoke (T1 arg1,T2 arg2) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Threading.CommonParallel.For (system.int32 fromInclusive,system.int32 toExclusive,system.int32 rangeSize,System.Action`2[T1,T2] body) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Storage.DenseVectorStorage`1[T].MapToUnchecked[TU] (MathNet.Numerics.Linearalgebra.Storage.VectorStorage`1[T] target,System.Func`2[T,TResult] f,MathNet.Numerics.Linearalgebra.Zeros zeros,MathNet.Numerics.Linearalgebra.ExistingData existingData) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Storage.VectorStorage`1[T].MapTo[TU] (MathNet.Numerics.Linearalgebra.Storage.VectorStorage`1[T] target,MathNet.Numerics.Linearalgebra.ExistingData existingData) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Vector`1[T].Map (System.Func`2[T,MathNet.Numerics.Linearalgebra.Vector`1[T] result,MathNet.Numerics.Linearalgebra.Zeros zeros) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Double.Vector.DoPointwiseSign (MathNet.Numerics.Linearalgebra.Vector`1[T] result) [0x00000] in <00000000000000000000000000000000>:0
at System.Action`1[T].Invoke (T obj) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Vector`1[T].PointwiseUnary (System.Action`1[T] f) [0x00000] in <00000000000000000000000000000000>:0
at MathNet.Numerics.Linearalgebra.Vector`1[T].PointwiseSign () [0x00000] in <00000000000000000000000000000000>:0
at EBM.Integrate (MathNet.Numerics.Linearalgebra.Vector`1[T] T,system.int32 years,system.int32 timesteps) [0x00000] in <00000000000000000000000000000000>:0
at EBM.Calc (System.Collections.Generic.IEnumerable`1[T] input,system.int32 timesteps) [0x00000] in <00000000000000000000000000000000>:0
at World.Calc (System.Boolean useTemp,system.int32 steps) [0x00000] in <00000000000000000000000000000000>:0
at World.Init () [0x00000] in <00000000000000000000000000000000>:0
at GameManager.Awake () [0x00000] in <00000000000000000000000000000000>:0
(Filename: currently not available on il2cpp Line: -1)
/// <summary> Does entire timestep integration calculation </summary>
public static (Matrix<double>,Matrix<double>) Integrate(Vector<double> T = null,int years = 0,int timesteps = 0)
{
T = T ?? 7.5f + 20 * (1 - 2 * x.PointwisePower(2));
years = years == 0 ? dur : years;
timesteps = timesteps == 0 ? nt : timesteps;
Matrix<double> Tfin = Matrix<double>.Build.Dense(bands,nt,0);
Matrix<double> Efin = Matrix<double>.Build.Dense(bands,0);
Matrix<double> T0fin = Matrix<double>.Build.Dense(bands,0);
Matrix<double> ASRfin = Matrix<double>.Build.Dense(bands,0);
//Matrix<double> tfin = Matrix<double>.Build.Dense()np.linspace(0,1,nt);
Vector<double> Tg = Vector<double>.Build.DenSEOfVector(T);
Vector<double> E = Tg * cw;
for (var (i,p) = (0,0); i < years; i++)
{
for (int j = 0; j < timesteps; j++)
{
/* if (j % (nt / 100f) == 0)
{
Efin.SetColumn(p,E);
Tfin.SetColumn(p,T);
p++;
}*/
Vector<double> alpha = E.PointwiseSign().PointwiseMultiply(aw).Map(x => x < 0 ? aI : x); // aw * (E > 0) + ai * (E < 0)
Vector<double> C = alpha.PointwiseMultiply(S.Row(j)) + cg_tau * Tg - A + F; // alpha * S[i,:] + cg_tau * Tg - A
Vector<double> T0 = C / (M - k * Lf / E);
if (i == dur - 1)
{
Efin.SetColumn(j,E);// [":",i] = E;
Tfin.SetColumn(j,T);//[":",i] = T;
T0fin.SetColumn(j,T0);//[":",i] = T0;
ASRfin.SetColumn(j,alpha.PointwiseMultiply(S.Row(j)));//[":",i] = alpha * S[i,":"];
}
T = Sign0(GreatOrE,E) / cw + Sign0(Less,Sign0(Less,E,T0)); // E/cw*(E >= 0)+T0*(E < 0)*(T0 < 0)
E = E + dt * (C - M * T + Fb);
var mklfe = M - k * Lf / E;
var signlesset0 = Sign0(Less,T0);
/*# Implicit Euler on Tg
# latent heat transport
# n.b. this is semi-implicit,with some derivatives are
# calculated on the prevIoUs time steP*/
var q = RH * saturation_specific_humidity(Tg,Ps);
var rhs1 = (dt * diffop / cg) * (Lv * q / cp);
Tg = (kappa - Matrix<double>.Build.DiagonalOfDiagonalVector(
Sign0(Less,signlesset0,dc / mklfe) // np.diag(dc / (M - kLf / E) * (T0 < 0) * (E < 0)
)).solve(Tg + rhs1 + dt_tau * (
Sign0(GreatOrE,E) / cw + (aI * S.Row(j) - A + F). // E / cw * (E >= 0) + (ai * S[i,:] - A)
Map2((a,b) => b != 0 ? a / b : 0,// funky division
Sign0(Less,mklfe)) // (M - kLf / E) * (T0 < 0) * (E < 0)
));
}
}
根据堆栈跟踪,问题似乎出在行 Vector<double> alpha = E.PointwiseSign().PointwiseMultiply(aw).Map(x => x < 0 ? aI : x);
我不明白的是为什么代码在游戏的其他版本中有效,但在 WebGL 版本中却中断了。任何帮助将不胜感激。
解决方法
想出了一种解决方案——出于某种原因,这在 Unity 2019.3 中随机中断,但升级到 2019.4,现在该功能似乎一直在工作。可能与不同版本如何将函数转换为 WebGL 有关系。