//    private GameObject[] AttackObjs;
            //    public int AttackLag;
            //    public float AttackLife;
            //    private int totalAttackFrames;
            //    private WaitForSeconds attackDisableDelay;
            //    public float InvicibilityFrames;
            //    private float invincibilityCount;

            //    private bool facingRight;

            //    private bool punching;
            //    public int PunchPercentAdd;
            //    public float PunchForceUp;
            //    public float PunchForceForward_Forward;
            //    public float PunchForceForward_Up;
            //    public float PunchForceDown;
            //    public float PunchForceDecel;
            //    private float punchForceUpTemp;
            //    private float punchForceForward_ForwardTemp;
            //    private float punchForceForward_UpTemp;
            //    private float punchForceDownTemp;
            //    private Dictionary<string, float> StrengthsList;
            //	private bool punchForceApplied;
            //    public float PunchDisablePerc;

            //    private float damage;

            //    private int lastHitBy;
            //    private float lastHitTime;
            //    private float lastHitForgetLength;

            //    public AudioClip DeathNoise;
            //    private AudioSource myAudioSrc;

            //    private bool isFrozen;
            //    private bool controlsPaused;
            //    private float spawnPause;
            //    private WaitForSeconds spawnPauseWait;

            //    private Animator anim;

            //    public float BoxPunch;

            /// todo GOOGLE: New keyword vs OVERRIDE
            //public void Start() {
            //    CBUG.Do("blah");
            //}

            public void Start()
            {
                _position        = new Vector2();
                _Rigibody3D      = GetComponent <Rigidbody>();
                _PhotonView      = GetComponent <PhotonView>();
                _PhotonTransform = GetComponent <PhotonTransformView>();

                ExternalForces = null;

                if (EnableDefaultGravity)
                {
                    ExternalForces += () => {
                        return(Forces.Gravity3);
                    };
                }

                if (_PhotonView.IsMine)
                {
                    tag = "PlayerSelf";
                    //_PhotonView.RPC("SetSlotNum", RpcTarget.All, NetID.ConvertToSlot(PhotonNetwork.player.ID));
                }
                jumpsRemaining = TotalJumpsAllowed;

                PM = PhotonArenaManager.Instance;
            }
            //    private void updateAttacks()
            //    {
            //        if (isDead)
            //            return;

            //        if(totalAttackFrames < 0 ){
            //            if ((Input.GetButtonDown("Up") || _MobileInput.GetButtonDown("Up")) && !punching)
            //            {
            //                punching = true;
            //                AttackObjs[0].SetActive(true);
            //                StartCoroutine(disableDelay(AttackObjs[0]));
            //                totalAttackFrames = AttackLag;
            //                _PhotonView.RPC("UpAttack", PhotonTargets.Others);
            //            }
            //            if ((Input.GetButtonDown("Down") || _MobileInput.GetButtonDown("Down")) && !punching)
            //            {
            //                punching = true;
            //                AttackObjs[2].SetActive(true);
            //                StartCoroutine(disableDelay(AttackObjs[2]));
            //                totalAttackFrames = AttackLag;
            //                _PhotonView.RPC("DownAttack", PhotonTargets.Others);
            //            }
            //            if (facingRight && (Input.GetButtonDown("Right") || _MobileInput.GetButtonDown("Right")) && !punching)
            //            {
            //                punching = true;
            //                AttackObjs[1].SetActive(true);
            //                StartCoroutine(disableDelay(AttackObjs[1]));
            //                totalAttackFrames = AttackLag;
            //                _PhotonView.RPC("ForwardAttack", PhotonTargets.Others);
            //            }
            //            if (!facingRight && (Input.GetButtonDown("Left") || _MobileInput.GetButtonDown("Left")) && !punching)
            //            {
            //                punching = true;
            //                AttackObjs[1].SetActive(true);
            //                StartCoroutine(disableDelay(AttackObjs[1]));
            //                totalAttackFrames = AttackLag;
            //                _PhotonView.RPC("ForwardAttack", PhotonTargets.Others);
            //            }
            //        }
            //        totalAttackFrames -= 1;
            //    }

            //    #region RPC Functions.
            //    //TODO: Determine allowed scope of RPC functions.
            //    [PunRPC]
            //    void SetSlotNum(int SlotNUm)
            //    {
            //        this.SlotNum = SlotNUm;
            //        CBUG.Do("Recording ID " + SlotNUm + " with Gamemaster.");
            //        CBUG.Do("Character is: " + gameObject.name);
            //        GameManager.AddPlayer(SlotNUm, gameObject);
            //    }

            //    [PunRPC]
            //    void UpAttack()
            //    {
            //        AttackObjs[0].SetActive(true);
            //        StartCoroutine(disableDelay(AttackObjs[0]));
            //    }

            //    [PunRPC]
            //    void ForwardAttack()
            //    {
            //        AttackObjs[1].SetActive(true);
            //        StartCoroutine(disableDelay(AttackObjs[1]));
            //    }

            //    [PunRPC]
            //    void DownAttack()
            //    {
            //        AttackObjs[2].SetActive(true);
            //        StartCoroutine(disableDelay(AttackObjs[2]));
            //    }

            //    [PunRPC]
            //    void SpecialActivate()
            //    {
            //        anim.SetBool("Activating", true);
            //    }

            //    [PunRPC]
            //    void HurtAnim(int hurtNum)
            //    {
            //        switch (hurtNum)
            //        {
            //            case 1:
            //                anim.SetBool("HurtSmall", true);
            //                break;
            //            case 2:
            //                anim.SetBool("HurtMedium", true);
            //                break;
            //            case 3:
            //                anim.SetBool("HurtBig", true);
            //                break;
            //            default:
            //                CBUG.Error("BAD ANIM NUMBER GIVEN");
            //                break;
            //        }
            //    }


            //    /// <summary>
            //    /// Calls GameManager's RecordDeath. Respawn Handling
            //    /// is done from there.
            //    /// </summary>
            //    /// <param name="killer"></param>
            //    /// <param name="killed"></param>
            //    [PunRPC]
            //    private void OnDeath(int killer, int killed)
            //    {
            //        isDead = true;
            //        //Hide Self till respawn (or stay dead, ghost)
            //        transform.GetChild(0).GetChild(1).GetChild(0).GetComponent<Image>().enabled = false;

            //        //Freeze and Clear motion
            //        _Rigibody2D.velocity = Vector2.zero;
            //        velocity = Vector2.zero;

            //        //Death Map: OnDeath > RecordDeath > HandleDeath >
            //        // doRespawnOrGhost
            //        GameManager.RecordDeath(killer, killed);
            //        GameManager.HandleDeath(killed);

            //        //TODO: Animate death
            //    }
            //    #endregion

            //    /// <summary>
            //    /// Nothing to do. You stay invisible and immobile
            //    /// </summary>
            //    public override void Ghost()
            //    {
            //        transform.tag = "PlayerGhost";
            //    }

            //    /// <summary>
            //    /// Respawning. Only Graphical UNLESS is our Player. Then we reposition ourselves.
            //    /// </summary>
            //    /// <param name="spawnPoint"></param>
            //    public override void Respawn(Vector3 spawnPoint)
            //    {
            //        if (_PhotonView.isMine) {
            //            transform.position = spawnPoint;
            //            GameHUDController.LoseALife();
            //            GameHUDController.ResetDamage();
            //            damage = 0;
            //        }

            //        _Rigibody2D.isKinematic = false;
            //        StartCoroutine(spawnProtection());
            //    }
            //    private IEnumerator spawnProtection()
            //    {
            //        yield return spawnPauseWait;
            //        //TODO: Spawn animation
            //        transform.GetChild(0).GetChild(1).GetChild(0).GetComponent<Image>().enabled = true;

            //        isDead = false;
            //    }

            //    public void Freeze()
            //    {
            //        _Rigibody2D.isKinematic = true;
            //        isFrozen= true;
            //    }
            //    public void UnFreeze()
            //    {
            //        _Rigibody2D.isKinematic = false;
            //        isFrozen = false;
            //    }

            //    void OnTriggerEnter2D(Collider2D col)
            //    {
            //        //if (col.name == "Physics Box(Clone)")
            //        //{
            //        //    CBUG.Log("PUNCH");
            //        //    if(transform.localScale.x > 0){
            //        //        col.GetComponent<Rigidbody2D>().AddForce(new Vector2(BoxPunch, BoxPunch), ForceMode2D.Impulse);
            //        //    }else{
            //        //        col.GetComponent<Rigidbody2D>().AddForce(new Vector2(-BoxPunch, BoxPunch), ForceMode2D.Impulse);
            //        //    }
            //        //}

            //        if (isDead || col == null || !_PhotonView.isMine)
            //            return;


            //        //apply force . . .
            //        else if (col.name.Contains("Punch"))
            //        {
            //            //Get name of puncher
            //            lastHitBy = col.GetComponentInParent<PlayerController2DOnline>().SlotNum;
            //            lastHitTime = Time.time;

            //            if (invincibilityCount > 0)
            //            {
            //                return;
            //            }
            //            else
            //            {
            //                invincibilityCount = InvicibilityFrames;
            //            }
            //            damage += PunchPercentAdd;
            //            if (damage < 30)
            //            {
            //                _PhotonView.RPC("HurtAnim", PhotonTargets.All, 1);
            //            }
            //            else if (damage < 60)
            //            {
            //                _PhotonView.RPC("HurtAnim", PhotonTargets.All, 2);
            //            }
            //            else
            //            {
            //                _PhotonView.RPC("HurtAnim", PhotonTargets.All, 3);
            //            }
            //            GameHUDController.SetDamageTo(damage);
            //            if (col.name == "PunchForward")
            //            {
            //                //velocity += Vector2.right * PunchForceForward_Forward;
            //                if (col.transform.parent.localScale.x > 0)
            //                {
            //                    Vector2 temp = Vector2.right * (PunchForceForward_Forward + StrengthsList[col.transform.parent.name] - Defense);
            //                    temp += Vector2.up * (PunchForceForward_Up + StrengthsList[col.transform.parent.name] - Defense);
            //                    StartCoroutine(
            //                        applyPunchForce(temp * (damage/100f))
            //                    );
            //                }
            //                else
            //                {
            //                    Vector2 temp = Vector2.left * (PunchForceForward_Forward + StrengthsList[col.transform.parent.name] - Defense);
            //                    temp += Vector2.up * (PunchForceForward_Up + StrengthsList[col.transform.parent.name] - Defense);
            //                    StartCoroutine(
            //                        applyPunchForce(temp * (damage / 100f))
            //                    );
            //                }
            //            }
            //            else if (col.name == "PunchUp")
            //            {
            //                StartCoroutine(
            //                    applyPunchForce(
            //                        (Vector2.up * (PunchForceUp + StrengthsList[col.transform.parent.name] - Defense) * (damage / 100f))
            //                    )
            //                );
            //            }
            //            else
            //            {
            //                if (!isGrounded)
            //                {
            //                    StartCoroutine(
            //                        applyPunchForce(
            //                            (Vector2.down * (PunchForceDown + StrengthsList[col.transform.parent.name] - Defense) * (damage / 100f))
            //                        )
            //                    );
            //                }
            //                else
            //                {
            //                    StartCoroutine(
            //                        applyPunchForce(
            //                            (Vector2.up * (PunchForceDown + StrengthsList[col.transform.parent.name] - Defense) * (damage / 200f))
            //                        )
            //                    );
            //                }
            //            }
            //        }
            //    }

            //    private IEnumerator disableDelay(GameObject dis)
            //    {
            //        yield return attackDisableDelay;
            //        dis.SetActive(false);
            //        punching = false;
            //    }

            //    private IEnumerator applyPunchForce(Vector2 punchForce)
            //    {
            //        Vector2 tempPunchForce = punchForce;
            //        bool isTempForceLow = false;
            //        CamManager.PunchShake(tempPunchForce.magnitude);
            //        while (tempPunchForce.magnitude > 0.01f)
            //        {
            //            velocity += tempPunchForce;
            //            tempPunchForce = Vector2.Lerp(tempPunchForce, Vector2.zero, PunchForceDecel);

            //            if (!isTempForceLow &&
            //                tempPunchForce.magnitude < punchForce.magnitude * PunchDisablePerc)
            //            {
            //                isTempForceLow = true;
            //                //if the force goes below 25%, let the character move again.
            //	            punchForceApplied = false;
            //            }
            //            else if(!isTempForceLow)
            //            {
            //			    punchForceApplied = true;
            //            }
            //            yield return null;
            //        }
            //    }

            //    void OnTriggerExit2D(Collider2D col)
            //    {
            //        if (col.tag != "DeathWall")
            //            return;
            //        myAudioSrc.Play();
            //        CamManager.DeathShake(_PhotonView.isMine);

            //        if (!_PhotonView.isMine)
            //            return;

            //        _PhotonView.RPC("OnDeath", PhotonTargets.All, lastHitBy, SlotNum);
            //    }


            //    public bool GetIsDead()
            //    {
            //        return isDead;
            //    }

            //    public void PauseMvmnt()
            //    {
            //        controlsPaused = true;
            //    }

            //    public void UnpauseMvmnt()
            //    {
            //        controlsPaused = false;
            //    }
            //}
            ////public void CheckWon()
            ////{
            ////    if (m_PhotonView.isMine && !isDead)
            ////    {
            ////        BattleUI.Won();
            ////    }

            public void AddExternalForce(Forces.ExternalForce newForce)
            {
                ExternalForces += new Forces.ExternalForce(newForce);
            }