Hi
I updated my project to ECS 0.50 and now I get error messages.
The error message is as follows
Assets/Scripts/System/TestSystem.cs(20,69): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of ‘this’. Consider copying ‘this’ to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead.
I don’t think my code is accessing the members of this, but I don’t understand why I am getting this error message.
This did not occur in ECS 0.17.
Can anyone help me understand this error?
TestComponent.cs
```
using Unity.Entities;
[System.Serializable]
public struct TestComponent : IComponentData
{
public int id;
}
```
Test2Component.cs
```
using System;
using Unity.Entities;
[System.Serializable]
public struct Test2Component : IComponentData
{
public string id;
}
```
CallbackEvent.cs
```
using System;
using Unity.Entities;
[System.Serializable]
public struct CallbackEvent : IComponentData
{
public int actionId;
}
```
CallbackSystem.cs
```
using System;
using System.Collections.Generic;
using Unity.Entities;
public partial class CallbackSystem : SystemBase
{
EntityCommandBufferSystem _entityCommandBufferSystem;
Dictionary<int, Action<EntityCommandBuffer>> _callbacks;
int _actionIdSequential;
public CallbackEvent CreateCallback(Action<EntityCommandBuffer> action)
{
var actionId = _actionIdSequential++;
_callbacks[actionId] = action;
return new CallbackEvent {
actionId = actionId,
};
}
protected override void OnCreate()
{
_entityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
_callbacks = new Dictionary<int, Action<EntityCommandBuffer>>();
}
protected override void OnUpdate()
{
}
}
```
TestSystem.cs
```
using Unity.Entities;
public partial class TestSystem : SystemBase
{
CallbackSystem _callbackSystem;
protected override void OnUpdate()
{
Entities
.WithoutBurst()
.WithAll<TestComponent>()
.ForEach((
Entity entity,
int entityInQueryIndex
) => {
var str = "str";
var onArrived = _callbackSystem.CreateCallback(buffer => {
buffer.AddComponent(entity, new Test2Component {
id = str, // ng
// id = "str", // ok
});
});
}).Run();
}
}
```
I don‘t see it right away, but I noticed that TestComponent is a class, not a struct.
1 Like
Thank you for your reply!
Ah!!! You are right, I had overlooked that.
I tried to set TestComponent to struct, but unfortunately the error content did not improve.
You have few issue here.
First, you should not pass any managed tpye to your job. I. E Dictionary or classes.
Second, you should not have any string operations in a jobs.
Third, passing variables to job, which are outside of OnUpdate scope, require local variable and THIS.
For example in line 76, should become
var _callbackSystem = this. _callbackSystem;
ueue44
May 20, 2022, 10:01am
5
Antypodish:
You have few issue here.
First, you should not pass any managed tpye to your job. I. E Dictionary or classes.
Second, you should not have any string operations in a jobs.
Third, passing variables to job, which are outside of OnUpdate scope, require local variable and THIS.
For example in line 76, should become
var _callbackSystem = this. _callbackSystem;
Thank you kindly! It helps!!!
First, you should not pass any managed tpye to your job. i. E Dictionary or classes.
Which code is applicable here?
Is it the use of _callbacks(Dictionary) in the CreateCallback function?
Second, you should not have any string operations in a job.
Noted. Thank you.
Third, passing variables to a job, which are outside of the OnUpdate scope, requires local variables and THIS.
So this is how you would do it.
var _callbackSystem = this._callbackSystem;
Entities
.WithoutBurst()
.WithAll<TestComponent>()
.ForEach((
Entity entity,
int entityInQueryIndex
) => {
var str = "str";
var onArrived = _callbackSystem.CreateCallback(buffer => {
buffer.AddComponent(entity, new Test2Component {
id = "str",
});
});
}).Run();
You still need to remove the string, they are not allowed in struct IComponentData, see this for allowed types:
https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/ecs_components.html
ueue44
May 23, 2022, 12:36am
7
I see. Thank you very much.
Hi, I have the same issue, at Entity 0.50.1-preview.2 and Unity 2020.3.33.f1.
And this is the minimum example.
Entities
.ForEach((
Entity entity,
int entityInQueryIndex
) => {
var str = "str";
var action = new Action(() => {
Debug.Log(str);
});
}).Run();
Error message is below.(at Debug.Log(str); line)
error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of ‘this’. Consider copying ‘this’ to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead.
On Entity 0.17.0-preview.42, I could create lambda in Entities.ForEach.
How can I create lambda in Entities.ForEach of 0.50?
Thanks for your help.
@ryooo321
One way to do it would be having static functions to create them, either in the job lambda or somewhere else.
Job.WithoutBurst().WithCode(() =>
{
static Action CreateDelegate(string str) => () => Debug.Log(str);
string str = "str";
var action = CreateDelegate(str);
action();
}).Run();
1 Like
@Anthiese
Thank you, Your example has no error.
Or I have fixed by using for statement.
var entities = query.ToEntityArrayAsync(Allocator.TempJob, out var handle);
Dependency = JobHandle.CombineDependencies(Dependency, handle);
for (int i = 0; i < entities.Length; i++) {
var entity = entities[i];
var str = "str";
var action = new Action(() => {
Debug.Log(str);
});
}
entities.Dispose(Dependency);