void TryPlaceAfterHitting(short hitX, short hitZ)
        {
            TileMap tileMap = GameManager.Instance.TileMap;

            bool canPlaceX = !tileMap.HasBlock((short)(Velocity.x < 0 ? hitX + 1 : hitX - 1), hitZ);
            bool canPlaceZ = !tileMap.HasBlock(hitX, (short)(Velocity.z < 0 ? hitZ + 1 : hitZ - 1));

            if (!canPlaceX && !canPlaceZ)
            {
                // Place diagonal
                if (Velocity.x < 0)
                {
                    hitX++;
                }
                else
                {
                    hitX--;
                }

                if (Velocity.z < 0)
                {
                    hitZ++;
                }
                else
                {
                    hitZ--;
                }
            }
            else
            {
                if ((Mathf.Abs(Velocity.x) > Mathf.Abs(Velocity.z) && canPlaceX) || !canPlaceZ)
                {
                    if (Velocity.x < 0)
                    {
                        hitX++;
                    }
                    else
                    {
                        hitX--;
                    }
                }
                else
                {
                    if (Velocity.z < 0)
                    {
                        hitZ++;
                    }
                    else
                    {
                        hitZ--;
                    }
                }
            }

            if (ColorType != null && !GameManager.Instance.IsOutOfBounds(hitX, hitZ))
            {
                GameManager.Instance.PlayCrystaliseSound();
                tileMap.SetBlock(hitX, hitZ, ColorType ?? Game.ColorType.RED);
            }
        }
        void Update()
        {
            Vector3 newPosition = transform.position;

            newPosition += Velocity * Time.deltaTime;

            Lifetime -= Time.deltaTime;
            if (Lifetime < 0)
            {
                Destroy(gameObject);
            }

            short tileX = (short)Mathf.FloorToInt(newPosition.x);
            short tileZ = (short)Mathf.FloorToInt(newPosition.z);

            TileMap tileMap = GameManager.Instance.TileMap;

            if (tileMap.HasBlock(tileX, tileZ) || GameManager.Instance.IsOutOfBounds(tileX, tileZ))
            {
                if (ColorType != null)
                {
                    TryPlaceAfterHitting(tileX, tileZ);
                }
                else
                {
                    TryTriggerChainReaction(tileX, tileZ);
                }
                Destroy(gameObject);
            }

            Ray ray = new Ray(LastPosition, newPosition - LastPosition);

            RaycastHit[] hits = Physics.RaycastAll(ray, (newPosition - LastPosition).magnitude);

            foreach (RaycastHit hit in hits)
            {
                EnemyBehaviour enemyBehaviour = hit.transform.gameObject.GetComponent <EnemyBehaviour>();
                if (enemyBehaviour != null)
                {
                    if (EnemiesPassed < MaxEnemyPasses)
                    {
                        if (ColorType == null)
                        {
                            SetColor(enemyBehaviour.ColorType);
                            killEnemy(enemyBehaviour);
                        }
                        else if (enemyBehaviour.ColorType == ColorType)
                        {
                            GameManager.Instance.AwardPoints(1);
                            killEnemy(enemyBehaviour);
                        }
                    }
                }
            }

            transform.position = newPosition;
            LastPosition       = transform.position;
        }