void Start()
 {
     // Initial Velocity
     //GetComponent<Rigidbody2D>().velocity = Vector2.up * Speed;
     _gameManager = GameObject.Find("$GameManager");
     _camera      = GameObject.Find("Camera");
     CatchCount   = -1;       //-1 because the first collision counts when serving
     if (this.tag != "DiscShadow")
     {
         IsThrownBy = CurrentPlayer.None;
     }
     LastThrownBy              = IsThrownBy;
     _liftDirection            = Direction.Standby;
     _gravity                  = 10.0f;
     _gravityIsSet             = false;
     _isRandomBounce           = PlayerPrefs.GetInt("Bounce") == Bounce.Random.GetHashCode() ? true : false;
     NbCol                     = 0;
     _liftEffectDelay          = 0.1f;
     _quickEffectDelay         = 0.05f;
     _isQuickThrow             = 0;
     _hasHitGoal               = false;
     _originalSpeed            = Speed;
     HasHitPlayer              = false;
     onWallCollisionDelegate   = null;
     onPlayerCollisionDelegate = null;
     QuickDisk                 = false;
     _currentMap               = PlayerPrefs.GetInt("SelectedMap");
     SuperId                   = 0;
 }
    void OnCollisionEnter2D(Collision2D col)
    {
        if (gameObject.tag == "DiscShadow")
        {
            if ((col.gameObject.tag == "Player" && col.gameObject.GetComponent <PlayerBehavior>().Player != this.IsThrownBy) ||
                col.gameObject.tag == "Goal" ||
                col.gameObject.tag == "FrozenWall" ||
                col.gameObject.tag == "TrainingWall")
            {
                Destroy(gameObject);
            }
        }

        if (col.gameObject.tag == "Player" && gameObject.tag != "DiscShadow")
        {
            if (_hasHitGoal || HasHitPlayer)
            {
                return;
            }
            HasHitPlayer            = true;
            onWallCollisionDelegate = null;
            if (onPlayerCollisionDelegate != null)
            {
                if (onPlayerCollisionDelegate() == false)
                {
                    _linkedPlayer = col.gameObject;
                    _linkedPlayer.GetComponent <PlayerBehavior> ().TriggerCatch();
                    return;
                }
            }
            if (_currentMap == 5)
            {
                GameObject.Find("MiddleWall01").GetComponent <MiddleWallBehavior> ().Reset();
            }
            NbCol         = 0;
            LastThrownBy  = IsThrownBy;
            _linkedPlayer = col.gameObject;
            CurrentPlayer = _linkedPlayer.GetComponent <PlayerBehavior> ().Player;
            if (_linkedPlayer.GetComponent <PlayerBehavior>().HasTheDisc == false)
            {
                _linkedPlayer.GetComponent <PlayerBehavior> ().Ball = this.gameObject;
                _linkedPlayer.GetComponent <PlayerBehavior> ().CatchTheDisc();
            }
            else
            {
                IsNextBall = true;
                _linkedPlayer.GetComponent <PlayerBehavior> ().NextBalls.Add(this.gameObject);
            }
            if (++CatchCount % 2 == 0 && CatchCount != 0 && Speed < 6.0f)             // "CatchCount != 0" because it starts at -1
            {
                Speed += 0.25f;
            }
            IsThrownBy        = CurrentPlayer.None;
            _liftDirection    = Direction.Standby;
            Physics2D.gravity = new Vector2(0.0f, 0.0f);
            _gravityIsSet     = false;
            _isQuickThrow++;
            var quickThrowDelay = _linkedPlayer.GetComponent <PlayerBehavior> ().IsDashing ? 0.1f : 0.45f;
            QuickDisk = false;
            Invoke("DisableQuickThrow", CatchCount == 0 ? 0.0f : quickThrowDelay);
            Invoke("PlayerGetBallLastCheck", 0.3f);
        }
        else if (col.gameObject.tag == "Goal" && gameObject.tag != "DiscShadow")
        {
            onWallCollisionDelegate   = null;
            onPlayerCollisionDelegate = null;
            if (_hasHitGoal || IsThrownBy == CurrentPlayer.None || HasHitPlayer)
            {
                return;
            }
            _hasHitGoal       = true;
            Physics2D.gravity = new Vector2(0.0f, 0.0f);
            var yGoalEffect = MapsData.Maps[MapId].GoalCollisionY;
            if (transform.position.y < 0)
            {
                yGoalEffect = -yGoalEffect;
            }
            var tmpGoalEffect = Instantiate(GoalExplosionEffect, new Vector3(transform.position.x, yGoalEffect, 0.0f), transform.rotation);
            if (transform.position.y > 0)
            {
                tmpGoalEffect.GetComponent <SpriteRenderer>().flipY = true;
            }

            if (!MoreThanOneBall() && _camera != null)
            {
                _camera.GetComponent <CameraBehavior>().GoalHit(transform.position.y);
            }

            /*if (transform.position.x >= col.gameObject.transform.position.x - (col.gameObject.GetComponent<BoxCollider2D> ().size.x / 2) &&
             *  transform.position.x <= col.gameObject.transform.position.x + (col.gameObject.GetComponent<BoxCollider2D> ().size.x / 2))
             * {*/
            col.gameObject.GetComponent <GoalBehavior> ().GoalHit();
            //}
            var looserGameObject = GameObject.Find(col.gameObject.GetComponent <GoalBehavior>().Player.ToString());
            if (looserGameObject != null)
            {
                looserGameObject.GetComponent <PlayerBehavior> ().Eject(transform.position);
                CollideElement(looserGameObject.transform.position);
            }
            if (_gameManager != null)
            {
                _gameManager.GetComponent <GameManagerBehavior>().NewBall(col.gameObject.GetComponent <GoalBehavior>().Player, col.gameObject.GetComponent <GoalBehavior>().Points, MoreThanOneBall());
            }
            Destroy(gameObject);
        }
        else if (col.gameObject.tag == "TrainingWall" && gameObject.tag != "DiscShadow")
        {
            NbCol = 0;
            DisableLift();
            var tmpWallHitEffect = Instantiate(WallHitEffect, new Vector3(gameObject.transform.position.x, col.transform.position.y - 0.39f, 0.0f), transform.rotation);
            tmpWallHitEffect.transform.Rotate(0.0f, 0.0f, 90.0f);
            _camera.GetComponent <CameraBehavior>().WallHit();
            IsThrownBy = CurrentPlayer.PlayerTwo;
            if (_isRandomBounce)
            {
                GetComponent <Rigidbody2D>().velocity = new Vector2(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, -2.0f)) * Speed;
            }
        }
        else if (col.gameObject.tag == "MiddleWall")
        {
            if (PlayerPrefs.GetInt("GameMode") == GameMode.Breakout.GetHashCode() && col.gameObject.name.Contains("Brick"))
            {
                NbCol = 0;
            }
            Vector2 point;
            if (col.contacts.Length > 0)
            {
                point = col.contacts [0].point;
            }
            else
            {
                point = this.transform.position;
            }
            CollideElement(point);
            if (col.gameObject.name.ToLower().Contains("goal"))
            {
                DisableLift();
            }
        }
        else if (col.gameObject.tag == "Wall")
        {
            if (onWallCollisionDelegate != null)
            {
                onWallCollisionDelegate();
            }
            ++NbCol;
            if (_liftDirection != Direction.Standby && NbCol <= 1)
            {
                AddGravity(2f);
                //if (_liftDirection == Direction.Left && col.transform.position.x < 0 ||
                //    _liftDirection == Direction.Right && col.transform.position.x > 0)
                //{
                //    GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x,
                //                                                       GetComponent<Rigidbody2D>().velocity.y * 1.5f);
                //}
            }
            _camera.GetComponent <CameraBehavior>().WallHit();
            col.gameObject.GetComponent <WallBehavior>().WallHit();

            var xWallEffect = MapsData.Maps[MapId].WallCollisionX;
            if (transform.position.x < 0)
            {
                xWallEffect = -xWallEffect;
            }
            var tmpWallHitEffect = Instantiate(WallHitEffect, new Vector3(xWallEffect, transform.position.y, 0.0f), transform.rotation);
            if (transform.position.x < 0)
            {
                tmpWallHitEffect.GetComponent <SpriteRenderer>().flipX = true;
            }
            if (GetComponent <Rigidbody2D>().velocity.y > 0)
            {
                tmpWallHitEffect.GetComponent <SpriteRenderer>().flipY = true;
            }
        }
        else if (col.gameObject.tag == "FrozenWall" && gameObject.tag != "DiscShadow")
        {
            _camera.GetComponent <CameraBehavior>().WallHit();
            col.gameObject.GetComponent <GoalBehavior> ().GoalHit();
            col.gameObject.GetComponent <GoalBehavior> ().Unfreeze();
        }
        else if (col.gameObject.tag == "Target")
        {
            Vector2 point;
            if (col.contacts.Length > 0)
            {
                point = col.contacts [0].point;
            }
            else
            {
                point = this.transform.position;
            }
            CollideElement(point, true);
            _gameManager.GetComponent <GameManagerBehavior> ().NewBallChallenge();
            Destroy(gameObject);
        }

        if (NbCol >= 10)
        {
            _gameManager.GetComponent <GameManagerBehavior>().NewBall(IsThrownBy, 2, MoreThanOneBall());
            Physics2D.gravity = new Vector2(0.0f, 0.0f);
            Destroy(gameObject);
        }
    }