private void TouchInputHandling(Touch touch)
    {
        if (touch.phase == TouchPhase.Began)
        {
            GameObject hitGO = PickObject(touch.position);
            OnPickUpObject?.Invoke(touch, hitGO);
        }

        if (touch.phase == TouchPhase.Canceled || touch.phase == TouchPhase.Ended)
        {
            GameObject hitGO = PickObject(touch.position);
            OnEndMovement?.Invoke(touch, hitGO);
        }
    }
    public void StartMovement(float fastSpeed, float normalSpeed,
                              Vector3 fastStartPos, Vector3 normalStartPos,
                              Vector3 normalEndPos, Vector3 fastEndPos,
                              OnEndMovement onEndMovement, bool hasCustomStart,
                              Vector3 startPos)
    {
        m_fastSpeed      = fastSpeed;
        m_normalSpeed    = normalSpeed;
        m_fastStartPos   = fastStartPos;
        m_normalStartPos = normalStartPos;
        m_normalEndPos   = normalEndPos;
        m_fastEndPos     = fastEndPos;
        m_onEndMovement  = onEndMovement;
        if (m_fastStartPos.x < m_fastEndPos.x)
        {
            transform.SetRotY(0f);
            m_normalEndPos.x += PlatformLength;
            m_fastEndPos.x   += PlatformLength;
        }
        else
        {
            transform.SetRotY(180f);
            m_normalEndPos.x -= PlatformLength;
            m_fastEndPos.x   -= PlatformLength;
        }

        if (hasCustomStart)
        {
            transform.position = startPos;

            // Determine the current move state according to start position
            if (m_fastStartPos.x < m_fastEndPos.x)
            {
                // Left to right
                if (startPos.x < m_fastStartPos.x)
                {
                    m_moveState = MoveState.NONE;
                }
                else if (startPos.x < m_normalStartPos.x)
                {
                    m_moveState = MoveState.FAST_START;
                }
                else if (startPos.x < m_normalEndPos.x)
                {
                    m_moveState = MoveState.NORMAL;
                }
                else if (startPos.x < m_fastEndPos.x)
                {
                    m_moveState = MoveState.FAST_END;
                }
                else
                {
                    m_moveState = MoveState.NONE;
                }
            }
            else
            {
                // Right to left
                if (startPos.x > m_fastStartPos.x)
                {
                    m_moveState = MoveState.NONE;
                }
                else if (startPos.x > m_normalStartPos.x)
                {
                    m_moveState = MoveState.FAST_START;
                }
                else if (startPos.x > m_normalEndPos.x)
                {
                    m_moveState = MoveState.NORMAL;
                }
                else if (startPos.x > m_fastEndPos.x)
                {
                    m_moveState = MoveState.FAST_END;
                }
                else
                {
                    m_moveState = MoveState.NONE;
                }
            }
            StartMoveState();
        }
        else
        {
            m_moveState = MoveState.NONE;
            UpdateMoveState();
        }
    }
    private void GetInput()
    {
        int touchCount = Input.touchCount;

        if (oldTouchCount == 2 && touchCount <= 1)
        {
            OnEndDualSteering?.Invoke();
            letGoOfDualSteering = true;
        }

        if (touchCount == 1)
        {
            Vector2 touchPos = Input.GetTouch(0).position;

            if (oldTouchCount == 0)
            {
                singleTouchBeginTime = Time.time;
            }

            float preRotInput;

            if (touchPos.x < GameManager.Instance.screenWidth * controlAreaSize / 2)
            {
                preRotInput = rotateSpeed;
            }
            else if (touchPos.x > GameManager.Instance.screenWidth - GameManager.Instance.screenWidth * controlAreaSize / 2)
            {
                preRotInput = -rotateSpeed;
            }
            else
            {
                touchCount  = 0;
                preRotInput = 0;
            }

            preRotInput *= (Time.time - singleTouchBeginTime) * singleTouchAccelTime + 1;

            if (letGoOfDualSteering)
            {
                rotInput = Mathf.Lerp(rotInput, preRotInput, dualToSingleSlowdown * Time.deltaTime);
            }
            else
            {
                rotInput = preRotInput;
            }

            if (rotInput != 0 && oldTouchCount == 0)
            {
                OnBeginMovement?.Invoke();
            }
        }
        else if (touchCount == 2)
        {
            if (oldTouchCount != 2)
            {
                if (oldTouchCount == 0)
                {
                    OnBeginMovement?.Invoke();
                }
                OnBeginDualSteering?.Invoke();
            }

            Vector2[] touches = new Vector2[2];
            for (int i = 0; i < 2; i++)
            {
                touches[i] = Input.GetTouch(i).position;
            }

            if (touches[0].x > touches[1].x)
            {
                Vector2 tmp = touches[0];
                touches[0] = touches[1];
                touches[1] = tmp;
            }

            if (touches[0].x <GameManager.Instance.screenWidth * controlAreaSize / 2 &&
                              touches[1].x> GameManager.Instance.screenWidth - GameManager.Instance.screenWidth * controlAreaSize / 2)
            {
                float deltaY = (touches[0].y - touches[1].y) / GameManager.Instance.screenHeight;

                float acceleration = deltaY - oldDeltaY;

                rotInput = -deltaY *deltaY *dualTouchRotateSpeed *Mathf.Sign(deltaY) - acceleration * accelFactor;

                oldDeltaY = deltaY;
            }
            else
            {
                if (touches[0].x < GameManager.Instance.screenWidth * controlAreaSize / 2)
                {
                    rotInput = -rotateSpeed;
                }
                else if (touches[1].x > GameManager.Instance.screenWidth - GameManager.Instance.screenWidth * controlAreaSize / 2)
                {
                    rotInput = rotateSpeed;
                }
                else
                {
                    rotInput = 0;
                }
            }
        }
        else
        {
            rotInput            = 0;
            letGoOfDualSteering = false;
            OnEndMovement?.Invoke();
        }

        oldTouchCount = touchCount;
    }