public void OnEntityCreated(SpatialOSEntityInfo entityInfo, GameObject prefab, EntityManager entityManager, EntityGameObjectLinker linker)
        {
            Coordinates position = Coordinates.Zero;

            if (TryGetComponent <Position.Component>(ref entityManager, entityInfo.Entity, out var pos))
            {
                position = pos.Value.Coords;
            }

            Quaternion rot   = Quaternion.identity;
            Vector3    scale = Vector3.one;

            if (TryGetComponent <PostureRoot.Component>(ref entityManager, entityInfo.Entity, out var posture))
            {
                rot   = posture.Value.RootTrans.Rotation.ToUnityQuaternion();
                scale = posture.Value.RootTrans.Scale.ToUnityVector();
            }

            Dictionary <int, CompressedLocalTransform> boneMap = null;

            if (TryGetComponent <BoneAnimation.Component>(ref entityManager, entityInfo.Entity, out var anim))
            {
                boneMap = anim.Value.BoneMap;
            }

            var gameObject = UnityEngine.Object.Instantiate(prefab, position.ToUnityVector() + this.WorkerOrigin, rot);

            gameObject.transform.localScale = scale;

            Type[] types = componentsToAdd;
            if (boneMap != null)
            {
                var container = gameObject.GetComponent <PostureBoneContainer>();
                container?.SetTrans(boneMap);
            }

            if (this.IsClient == false)
            {
                if (TryGetComponent <BaseUnitMovement.Component>(ref entityManager, entityInfo.Entity, out var movement))
                {
                    entityManager.AddComponentData <NavPathData>(entityInfo.Entity, NavPathData.CreateData());
                    entityManager.AddComponentData <MovementData>(entityInfo.Entity, MovementData.CreateData(movement.Value.MoveSpeed, movement.Value.RotSpeed));
                }

                if (TryGetComponent <BaseUnitStatus.Component>(ref entityManager, entityInfo.Entity, out var status))
                {
                    if (UnitUtils.IsBuilding(status.Value.Type))
                    {
                        entityManager.AddComponentData <BuildingData>(entityInfo.Entity, BuildingData.CreateData());
                    }
                }
            }

            gameObjectsCreated.Add(entityInfo.SpatialOSEntityId, gameObject);
            gameObject.name = $"{prefab.name}(SpatialOS: {entityInfo.SpatialOSEntityId}, Worker: {this.WorkerType})";
            linker.LinkGameObjectToSpatialOSEntity(entityInfo.SpatialOSEntityId, gameObject, types);
        }
        private void MovementQuery(Entity entity,
                                   ref MovementData movement,
                                   ref NavPathData path,
                                   ref BaseUnitSight.Component sight,
                                   ref BaseUnitStatus.Component status,
                                   ref SpatialEntityId entityId)
        {
            movement.MoveSpeed = 0.0f;
            movement.RotSpeed  = 0.0f;

            if (status.State != UnitState.Alive)
            {
                return;
            }

            if (UnitUtils.IsAutomaticallyMoving(status.Type) == false)
            {
                return;
            }

            var unit = EntityManager.GetComponentObject <UnitTransform>(entity);

            // check ground
            if (unit == null || unit.GetGrounded(out var hitInfo) == false)
            {
                return;
            }

            if (sight.State == TargetState.None)
            {
                return;
            }

            var trans = unit.transform;
            var pos   = trans.position;

            Vector3?tgt    = null;
            Vector3 spread = Vector3.zero;

            var id = entityId.EntityId;

            if (vectorDic.ContainsKey(id))
            {
                //tgt = vectorDic[id].boidTarget;
                spread = vectorDic[id].spread;
            }

            if (tgt == null)
            {
                tgt = sight.GetTargetPosition(this.Origin, pos);
            }

            tgt = CheckNavPathAndTarget(tgt.Value, pos, unit.SizeRadius, sight.State, entityId.EntityId.Id, ref path);

            if (RangeDictionary.IsSpreadValid(spread))
            {
                var length = (tgt.Value - pos).magnitude;
                tgt += spread * Mathf.Max(1.0f, (length / RangeDictionary.SpreadSize));
            }

            var positionDiff = tgt.Value - pos;

            var forward = get_forward(positionDiff, sight.TargetRange);

            MovementDictionary.TryGet(status.Type, out var speed, out var rot);

            var isRotate = rotate(rot, trans, positionDiff);

            if (forward != 0.0f)
            {
                movement.MoveSpeed = forward * speed;
            }

            if (isRotate != 0)
            {
                movement.RotSpeed = rot * isRotate;
            }
        }
        Vector3 CheckNavPathAndTarget(Vector3 target, Vector3 current, float size, TargetState state, long uid, ref NavPathData path)
        {
            if (pointsDic.ContainsKey(uid) == false)
            {
                pointsDic[uid] = new Vector3[256];
            }

            var points = pointsDic[uid];

            if (path.IsSetData == false || (target - path.target).sqrMagnitude > checkRange * checkRange)
            {
                NavMeshUtils.GetNavPoint(current, target, size, WalkableNavArea, out var count, points);
                if (count > 0)
                {
                    path.count   = count;
                    path.current = 0;
                    path.target  = target;
                    return(path.GetCurrentCorner(points));
                }
            }
            else
            {
                if ((path.GetCurrentCorner(points) - current).sqrMagnitude < size * size)
                {
                    path.Next();
                }

                return(path.GetCurrentCorner(points));
            }

            return(target);
        }