[Unity]マウスポインタでECSエンティティをさわる（実行時）


##動作確認環境
Unity 2020.02
Entities 0.17.0

##前提
さわる対象のEntityはPhysics Shape相当(Colliderでもさわれる)がないとだめです。
＃Physics Bodyは不要の簡易版

## ソースコード
２パターン。（挙動的には同一のもの）
・Monobehavior経由
・ECS、Job、Burstで実行（無駄に長い）
　カメラ情報を取得するためにMonobehaviorを使います。

```MouseTouchEntityFromMonobehavior.cs
	[SerializeField] Camera xCamera = default;

	const float RAYCAST_DISTANCE = 1000;
	PhysicsWorld physicsWorld => World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld;
	EntityManager entityManager => World.DefaultGameObjectInjectionWorld.EntityManager;
	void LateUpdate()
	{
		var screenPointToRay = xCamera.ScreenPointToRay(position);
		var rayInput = new RaycastInput
		{
			Start = screenPointToRay.origin,
			End = screenPointToRay.GetPoint(RAYCAST_DISTANCE),
			Filter = CollisionFilter.Default
		};
		if (!physicsWorld.CastRay(rayInput, out RaycastHit hit)) return;
		var selectedEntity = physicsWorld.Bodies[hit.RigidBodyIndex].Entity;
		// ↑ マウスがあたったエンティティ（単体）
		// CastRayの2個目の引数でNativeList<RaycastHit>を入れてあげれば
		// Start-End間のEntitiesを取れる。（検証してないけど）

		// あたったコンポーネントにアクセッス！
		var renderMesh = entityManager.GetSharedComponentData<RenderMesh>(selectedEntity);
	}
```

```MouseTouchEntityFromJob.cs
    public class MouseTouchEntityFromJob : MonoBehaviour, IConvertGameObjectToEntity
    {
        [SerializeField] Camera xCamera = default;
        MouseTouchEntityFromJobSystem system => World.DefaultGameObjectInjectionWorld.GetExistingSystem<MouseTouchEntityFromJobSystem>();
        void IConvertGameObjectToEntity.Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
        {
            dstManager.AddComponentData(entity, new MouseTouch() {});
        }
        void Start()
        {
            system.xCamera = xCamera;
        }
    }
    public struct MouseTouch : IComponentData {}
	public struct HitTargetData
	{
		public Entity Entity;
		public int Hit;
	}

    public class MouseTouchEntityFromJobSystem : SystemBase
    {
        public Camera xCamera = default;
        const float RAYCAST_DISTANCE = 1000;
        public NativeArray<HitTargetData> MouseHitData;
        BuildPhysicsWorld m_BuildPhysicsWorldSystem;
        EndFramePhysicsSystem endFramePhysicsSystem;
        EntityQuery m_MouseGroup;

        public MousePickSystem() 
        {
            // 気持ち悪かったらOnStartRunning()内でもいい好きにして！
            MouseHitData = new NativeArray<HitTargetData>(1, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            MouseHitData[0] = new HitTargetData();
        }
        protected override void OnStartRunning()
        {
            // OnCreate()でもいい。好きにして！
            m_BuildPhysicsWorldSystem = World.GetOrCreateSystem<BuildPhysicsWorld>();
            endFramePhysicsSystem     = World.GetOrCreateSystem<EndFramePhysicsSystem>();
            m_MouseGroup = GetEntityQuery(new EntityQueryDesc { All = new ComponentType[] { typeof(MouseTouch) } });
        }
        protected override void OnUpdate()
        {
            var handle = JobHandle.CombineDependencies(Dependency, endFramePhysicsSystem.GetOutputDependency());
            if (Input.GetMouseButton(0))
            {
                MouseTouchExecute(ref handle);
                PaintJobHandle = handle;
                handle.Complete();
            }
            Dependency.Complete();
            if(MouseHitData[0].Hit == 1)
            {
				// あたったコンポーネントにアクセッス！
				var renderMesh = EntityManager.GetSharedComponentData<RenderMesh>(MouseHitData[0].Entity);
            }
        }
        protected override void OnDestroy()
        {
            if (MouseHitData.IsCreated) MouseHitData.Dispose();
        }

        void MouseTouchExecute(ref JobHandle handle)
        {
            var screenPointToRay = xCamera.ScreenPointToRay(Input.mousePosition);
            handle = new Touch
            {
                physicsWorld = m_BuildPhysicsWorldSystem.PhysicsWorld,
                SpringData = MouseHitData,
                RayInput = new RaycastInput
                {
                    Start = screenPointToRay.origin,
                    End = screenPointToRay.GetPoint(RAYCAST_DISTANCE),
                    Filter = CollisionFilter.Default
                },
            }.Schedule(handle);
        }
        [BurstCompile]
        struct Touch : IJob
        {
            [ReadOnly] public PhysicsWorld physicsWorld;
            public NativeArray<HitTargetData> SpringData;
            public RaycastInput RayInput;

            public void Execute()
            {
                if (physicsWorld.CastRay(RayInput, out Unity.Physics.RaycastHit rayInput))
                {
                    RigidBody hitBody = physicsWorld.Bodies[rayInput.RigidBodyIndex];
                    SpringData[0] = new HitTargetData
                    {
                        Entity = hitBody.Entity,
                        Hit = 1,
                    };
                }
                else
                {
                    SpringData[0] = new HitTargetData 
                    {
                        Hit = 0,
                    };
                }
            }
        }
    }
```

##参考資料
・https://github.com/reeseschultz/ReeseUnityDemos
・https://github.com/Unity-Technologies/EntityComponentSystemSamples