Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question How do I make an entity draggable?

Discussion in 'Entity Component System' started by seona13, Dec 5, 2022.

  1. seona13

    seona13

    Joined:
    Nov 28, 2019
    Posts:
    23
    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:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Transforms;
    3. using UnityEngine;
    4.  
    5. namespace Experience
    6. {
    7.     public partial class DraggableSystem : SystemBase
    8.     {
    9.         Camera cam;
    10.  
    11.         float _startXPos;
    12.         float _startYPos;
    13.  
    14.         bool _isDragging = false;
    15.  
    16.         protected override void OnUpdate()
    17.         {
    18.             if (cam == null)
    19.             {
    20.                 cam = Camera.main;
    21.                 if (cam == null )
    22.                 {
    23.                     Debug.LogError("Main camera not found");
    24.                 }
    25.             }
    26.  
    27.             if (_isDragging)
    28.             {
    29.                 DragObject();
    30.             }
    31.         }
    32.  
    33.         void OnMouseDown()
    34.         {
    35.             Vector3 mousePos = Input.mousePosition;
    36.  
    37.             if (cam.orthographic == false)
    38.             {
    39.                 mousePos.z = 10;
    40.             }
    41.  
    42.             mousePos = cam.ScreenToWorldPoint(mousePos);
    43.  
    44.             Entities
    45.                 .WithAll<Draggable>()
    46.                 .ForEach((TransformAspect transform) =>
    47.                 {
    48.                     var pos = transform.Position;
    49.  
    50.                     _startXPos = mousePos.x - pos.x;
    51.                     _startYPos = mousePos.y - pos.y;
    52.                 }).Run();
    53.  
    54.  
    55.             _isDragging = true;
    56.         }
    57.  
    58.         void OnMouseUp()
    59.         {
    60.             _isDragging = false;
    61.         }
    62.  
    63.         public void DragObject()
    64.         {
    65.             Vector3 mousePos = Input.mousePosition;
    66.  
    67.             if (cam.orthographic == false)
    68.             {
    69.                 mousePos.z = 10;
    70.             }
    71.  
    72.             mousePos = cam.ScreenToWorldPoint(mousePos);
    73.  
    74.             Entities
    75.                 .WithAll<Draggable>()
    76.                 .ForEach((TransformAspect transform) =>
    77.                 {
    78.                     var pos = transform.Position;
    79.  
    80.                     pos = new Vector3(mousePos.x - _startXPos, mousePos.y - _startYPos, pos.z);
    81.                 }).Run();
    82.         }
    83.     }
    84. }

    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.
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,452
    Physics samples has draggable entities, I would go suggest looking at how they implemented it.
     
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,487
    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().
     
  4. seona13

    seona13

    Joined:
    Nov 28, 2019
    Posts:
    23
    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.
     
  5. seona13

    seona13

    Joined:
    Nov 28, 2019
    Posts:
    23
    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, Collection`1 methods)
    at Mono.Cecil.MetadataReader.ReadMethods(TypeDefinition type)
    at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TRet& variable, TItem item, Func`3 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(Collection`1 types)
    at Mono.Cecil.ImmediateModuleReader.ReadModule(ModuleDefinition module, Boolean resolve_attributes)
    at Mono.Cecil.ModuleDefinition.Read[TItem](TItem item, Action`2 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.<ProcessArgumentsAsync>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.<RunAsync>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.<<Main>$>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.<Main>(String[]) + 0x20
    at Unity.ILPP.Trigger!<BaseAddress>+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!)
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,452
  7. seona13

    seona13

    Joined:
    Nov 28, 2019
    Posts:
    23
    Thanks tertle. Off to explore now. :)
     
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,120