void MoveDeliver()
    {
        if (ballDeliver)
        {
            Vector3 camPos   = new Vector3(Camera.main.transform.position.x, 0.0f, Camera.main.transform.position.z);
            float   distance = Vector3.Distance(this.transform.position, camPos);
            if (distance > 0.1f)
            {
                Vector3 lookpos = camPos - this.transform.position;
                lookpos.y = 0;
                if (lookpos != Vector3.zero)
                {
                    var rotation = Quaternion.LookRotation(lookpos);
                    this.transform.rotation = Quaternion.Slerp(this.transform.rotation, rotation, Time.deltaTime * 2.0f);
                }

                this.transform.position = Vector3.MoveTowards(this.transform.position, camPos, Time.deltaTime * speed);
            }
            else
            {
                ball.transform.parent = null;
                Destroy(GameObject.FindGameObjectWithTag("Ball"));
                ballDeliver  = false;
                ballInGround = false;
                ballPlay     = false;
                ballThrown   = false;

                targetMove = transform.position;

                int curAgility = PlayerPrefs.GetInt("Walk");
                PlayerPrefs.SetInt("Walk", curAgility + 2);

                // update ball
                var  mapScript   = mapController.GetComponent <MapController>();
                int  tileX       = mapScript.tileX;
                int  tileY       = mapScript.tileY;
                bool readyToSend = mapScript.okToSentPetPos;

                if (readyToSend)
                {
                    UpdateBallState updateBall = new UpdateBallState();
                    updateBall.type      = "updateBall";
                    updateBall.username  = PlayerPrefs.GetString("username");
                    updateBall.tileX     = tileX;
                    updateBall.tileY     = tileY;
                    updateBall.ballPosX  = Camera.main.transform.position.x;
                    updateBall.ballPosY  = 0.0f;
                    updateBall.ballPosZ  = Camera.main.transform.position.z;
                    updateBall.ballState = "none";

                    string requestJson = JsonUtility.ToJson(updateBall);
                    AmqpClient.Publish(AmqpController.amqpControl.requestExchangeName, AmqpController.amqpControl.requestRoutingKey, requestJson);
                }
            }
        }
    }
    void SimulateProjectile()
    {
        if (ball.transform.position.y <= 0.0f && !ballInGround)
        {
            ball.GetComponent <Rigidbody>().isKinematic = true;
            ball.transform.position = new Vector3(ball.transform.position.x, 0.0f, ball.transform.position.z);

            ballInGround = true;

            petCalled = false;

            var  mapScript   = mapController.GetComponent <MapController>();
            int  tileX       = mapScript.tileX;
            int  tileY       = mapScript.tileY;
            bool readyToSend = mapScript.okToSentPetPos;

            if (readyToSend)
            {
                // ball
                UpdateBallState updateBall = new UpdateBallState();
                updateBall.type      = "updateBall";
                updateBall.username  = PlayerPrefs.GetString("username");
                updateBall.tileX     = tileX;
                updateBall.tileY     = tileY;
                updateBall.ballPosX  = ball.transform.position.x;
                updateBall.ballPosY  = 0.0f;
                updateBall.ballPosZ  = ball.transform.position.z;
                updateBall.ballState = "inground";

                string requestJson = JsonUtility.ToJson(updateBall);
                AmqpClient.Publish(AmqpController.amqpControl.requestExchangeName, AmqpController.amqpControl.requestRoutingKey, requestJson);

                // movement
                timeStartMove = DateTime.Now.Ticks.ToString();

                UpdatePetPos petPos = new UpdatePetPos();
                petPos.type          = "listplayer";
                petPos.username      = PlayerPrefs.GetString("username");
                petPos.timeStartMove = timeStartMove;
                petPos.petLastPosX   = transform.position.x;
                petPos.petLastPosY   = transform.position.z;
                petPos.petPosX       = ball.transform.position.x;
                petPos.petPosY       = ball.transform.position.z;
                petPos.tileX         = tileX;
                petPos.tileY         = tileY;
                petPos.petState      = "walktoball";
                petPos.speed         = speed;

                string requestJson2 = JsonUtility.ToJson(petPos);
                AmqpClient.Publish(AmqpController.amqpControl.requestExchangeName, AmqpController.amqpControl.requestRoutingKey, requestJson2);
            }
        }
    }
    void ThrowBall()
    {
        if (!ballThrown)
        {
            if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
            {
                if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
                {
                    ball.GetComponent <Rigidbody>().isKinematic = false;
                    ball.GetComponent <Rigidbody>().velocity    = Camera.main.transform.forward * 5;

                    ballThrown = true;

                    var  mapScript   = mapController.GetComponent <MapController>();
                    int  tileX       = mapScript.tileX;
                    int  tileY       = mapScript.tileY;
                    bool readyToSend = mapScript.okToSentPetPos;

                    if (readyToSend)
                    {
                        UpdateBallState updateBall = new UpdateBallState();
                        updateBall.type      = "updateBall";
                        updateBall.username  = PlayerPrefs.GetString("username");
                        updateBall.tileX     = tileX;
                        updateBall.tileY     = tileY;
                        updateBall.ballPosX  = Camera.main.transform.forward.x;
                        updateBall.ballPosY  = Camera.main.transform.forward.y;
                        updateBall.ballPosZ  = Camera.main.transform.forward.z;
                        updateBall.ballState = "throw";

                        string requestJson = JsonUtility.ToJson(updateBall);
                        AmqpClient.Publish(AmqpController.amqpControl.requestExchangeName, AmqpController.amqpControl.requestRoutingKey, requestJson);
                    }
                }
            }
        }
    }
    void PlayBall()
    {
        if (!ballThrown)
        {
            if (!ballPlay)
            {
                ball     = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                ball.tag = "Ball";
                ball.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
                float pos = (Camera.main.nearClipPlane + 2f);
                ball.transform.position = Camera.main.transform.position + Camera.main.transform.forward * pos;

                Rigidbody ballRigibody = ball.AddComponent <Rigidbody>();
                ballRigibody.mass        = 1;
                ballRigibody.isKinematic = true;

                ballPlay = true;

                var  mapScript   = mapController.GetComponent <MapController>();
                int  tileX       = mapScript.tileX;
                int  tileY       = mapScript.tileY;
                bool readyToSend = mapScript.okToSentPetPos;

                if (readyToSend)
                {
                    UpdateBallState updateBall = new UpdateBallState();
                    updateBall.type      = "updateBall";
                    updateBall.username  = PlayerPrefs.GetString("username");
                    updateBall.tileX     = tileX;
                    updateBall.tileY     = tileY;
                    updateBall.ballPosX  = Camera.main.transform.position.x;
                    updateBall.ballPosY  = 10.0f;
                    updateBall.ballPosZ  = Camera.main.transform.position.z;
                    updateBall.ballState = "live";

                    string requestJson = JsonUtility.ToJson(updateBall);
                    AmqpClient.Publish(AmqpController.amqpControl.requestExchangeName, AmqpController.amqpControl.requestRoutingKey, requestJson);
                }
            }
            else
            {
                Destroy(GameObject.FindGameObjectWithTag("Ball"));
                ballPlay = false;

                var  mapScript   = mapController.GetComponent <MapController>();
                int  tileX       = mapScript.tileX;
                int  tileY       = mapScript.tileY;
                bool readyToSend = mapScript.okToSentPetPos;

                if (readyToSend)
                {
                    UpdateBallState updateBall = new UpdateBallState();
                    updateBall.type      = "updateBall";
                    updateBall.username  = PlayerPrefs.GetString("username");
                    updateBall.tileX     = tileX;
                    updateBall.tileY     = tileY;
                    updateBall.ballPosX  = Camera.main.transform.position.x;
                    updateBall.ballPosY  = 10.0f;
                    updateBall.ballPosZ  = Camera.main.transform.position.z;
                    updateBall.ballState = "none";

                    string requestJson = JsonUtility.ToJson(updateBall);
                    AmqpClient.Publish(AmqpController.amqpControl.requestExchangeName, AmqpController.amqpControl.requestRoutingKey, requestJson);
                }
            }
        }
    }