I have done this with GameObjects in the past, and have scripts that work perfectly well for that. However, trying to make them work in an ECS-based project has me stumped.
I’ve tried to convert my existing MonoBehavior code to a SystemBase (it won’t let me use an ISystem, presumably because of needing to touch the non-entity camera) and come up with the following:
using Unity.Entities;
using Unity.Transforms;
using UnityEngine;
namespace Experience
{
public partial class DraggableSystem : SystemBase
{
Camera cam;
float _startXPos;
float _startYPos;
bool _isDragging = false;
protected override void OnUpdate()
{
if (cam == null)
{
cam = Camera.main;
if (cam == null )
{
Debug.LogError("Main camera not found");
}
}
if (_isDragging)
{
DragObject();
}
}
void OnMouseDown()
{
Vector3 mousePos = Input.mousePosition;
if (cam.orthographic == false)
{
mousePos.z = 10;
}
mousePos = cam.ScreenToWorldPoint(mousePos);
Entities
.WithAll<Draggable>()
.ForEach((TransformAspect transform) =>
{
var pos = transform.Position;
_startXPos = mousePos.x - pos.x;
_startYPos = mousePos.y - pos.y;
}).Run();
_isDragging = true;
}
void OnMouseUp()
{
_isDragging = false;
}
public void DragObject()
{
Vector3 mousePos = Input.mousePosition;
if (cam.orthographic == false)
{
mousePos.z = 10;
}
mousePos = cam.ScreenToWorldPoint(mousePos);
Entities
.WithAll<Draggable>()
.ForEach((TransformAspect transform) =>
{
var pos = transform.Position;
pos = new Vector3(mousePos.x - _startXPos, mousePos.y - _startYPos, pos.z);
}).Run();
}
}
}
However this gives me the following error in Unity:
Assets\_Experience\Scripts\Systems\DraggableSystem.cs(49,13): error DC0004: Entities.ForEach Lambda expression captures a non-value type 'this'. This is either due to use of a field, a member method, or property of the containing system, or the cause of explicit use of the this keyword. This is only allowed with .WithoutBurst() and .Run()
The line in question is the Entities.ForEach in OnMouseDown(), and there is a second error for the Entities.ForEach in DragObject(). I don’t understand what it’s telling me - I am using Run(), and I don’t see anywhere I am explicitly calling this. Is it implicit somewhere? I’m still getting my head around ECS, so I might be missing something.
You might be using Run(), but you are also not using WithoutBurst(). And because you use member variables of the class, the lambda captures a reference to the system itself, which is only allowed when using WithoutBurst().
Where do I find the physics samples? A web search hasn’t helped, and a quick browse of Unity’s ECS pages and Physics package documentation are not giving me anything either.
DreamingImLatios, Ah, I had been understanding it as an “or” rather than an “and”. I’m now no longer getting that error. Instead I’m getting this one:
Processing assembly Library/Bee/artifacts/1900b0aE.dag/Assembly-CSharp.dll, with 127 defines and 280 references
processors: Unity.Entities.CodeGen.EntitiesILPostProcessors, Unity.Jobs.CodeGen.JobsILPostProcessor, zzzUnity.Burst.CodeGen.BurstILPostProcessor
running Unity.Entities.CodeGen.EntitiesILPostProcessors
running Unity.Jobs.CodeGen.JobsILPostProcessor
Unity.Jobs.CodeGen.JobsILPostProcessor: ILPostProcessor has thrown an exception: System.NullReferenceException: Object reference not set to an instance of an object.
at Mono.Cecil.SignatureReader.ReadTypeSignature(ElementType etype)
at Mono.Cecil.SignatureReader.ReadTypeSignature(ElementType etype)
at Mono.Cecil.SignatureReader.ReadMethodSignature(IMethodSignature method)
at Mono.Cecil.MetadataReader.ReadMethod(UInt32 method_rid, Collection1 methods) at Mono.Cecil.MetadataReader.ReadMethods(TypeDefinition type) at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TRet& variable, TItem item, Func3 read)
at Mono.Cecil.TypeDefinition.get_Methods()
at Mono.Cecil.ImmediateModuleReader.ReadMethods(TypeDefinition type)
at Mono.Cecil.ImmediateModuleReader.ReadType(TypeDefinition type)
at Mono.Cecil.ImmediateModuleReader.ReadTypes(Collection1 types) at Mono.Cecil.ImmediateModuleReader.ReadModule(ModuleDefinition module, Boolean resolve_attributes) at Mono.Cecil.ModuleDefinition.Read[TItem](TItem item, Action2 read)
at Mono.Cecil.ModuleReader.CreateModule(Image image, ReaderParameters parameters)
at Unity.Jobs.CodeGen.JobsILPostProcessor.AssemblyDefinitionFor(ICompiledAssembly compiledAssembly)
at Unity.Jobs.CodeGen.JobsILPostProcessor.Process(ICompiledAssembly compiledAssembly)
at Unity.ILPP.Runner.PostProcessingPipeline.PostProcessAssemblyAsync(PostProcessAssemblyRequest request, Action`2 progressSink)
PostProcessing failed
Unhandled Exception: System.InvalidOperationException: Post processing failed
at Unity.ILPP.Trigger.TriggerApp.d__1.MoveNext() + 0xa97
— End of stack trace from previous location —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb6
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
at Unity.ILPP.Trigger.TriggerApp.d__0.MoveNext() + 0xe2
— End of stack trace from previous location —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb6
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
at Program.<$>d__0.MoveNext() + 0x145
— End of stack trace from previous location —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb6
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
at Program.(String[ ]) + 0x20
at Unity.ILPP.Trigger!+0x58c2bf
I don’t even know where to begin deciphering this one. It doesn’t seem to actually tell me there’s something specific wrong, just that it’s not happy. (The feeling is currently mutual!)