protected override void Start()
 {
     HitLayers = Global.TriggerLayers | Global.CharacterDamageLayers;
     IgnoreCollideObjects.AddRange(GetComponentsInChildren <Collider2D>());
     spriteRenderers.AddRange(GetComponentsInChildren <SpriteRenderer>());
     graphookTip.SetActive(false);
     grapCableRender.gameObject.SetActive(false);
     if (weapons.Count > 0)
     {
         weapon = weapons[CurrentWeaponIndex % weapons.Count];
     }
     // unpack
     InteractIndicator.SetActive(false);
     InteractIndicator.transform.SetParent(null);
 }
    new void UpdateCollision(float dT)
    {
        collideRight  = false;
        collideLeft   = false;
        collideTop    = false;
        collideBottom = false;
        adjust        = transform.position;

        #region multisampleAttempt

        /*
         * // Avoid the (box-to-box) standing-on-a-corner-and-moving-means-momentarily-not-on-ground bug by 'sampling' the ground at multiple points
         * RaycastHit2D right = Physics2D.Raycast( adjust + Vector2.right * box.x, Vector2.down, Mathf.Max( raylength, -velocity.y * Time.deltaTime ), LayerMask.GetMask( PlayerCollideLayers ) );
         * RaycastHit2D left = Physics2D.Raycast( adjust + Vector2.left * box.x, Vector2.down, Mathf.Max( raylength, -velocity.y * Time.deltaTime ), LayerMask.GetMask( PlayerCollideLayers ) );
         * if( right.transform != null )
         * rightFoot = right.point;
         * else
         * rightFoot = adjust + ( Vector2.right * box.x ) + ( Vector2.down * Mathf.Max( raylength, -velocity.y * Time.deltaTime ) );
         * if( left.transform != null )
         * leftFoot = left.point;
         * else
         * leftFoot = adjust + ( Vector2.left * box.x ) + ( Vector2.down * Mathf.Max( raylength, -velocity.y * Time.deltaTime ) );
         *
         * if( right.transform != null || left.transform != null )
         * {
         * Vector2 across = rightFoot - leftFoot;
         * Vector3 sloped = Vector3.Cross( across.normalized, Vector3.back );
         * if( sloped.y > corner )
         * {
         *  collideFeet = true;
         *  adjust.y = ( leftFoot + across * 0.5f ).y + contactSeparation + verticalOffset;
         *  hitBottomNormal = sloped;
         * }
         * }
         *
         * if( left.transform != null )
         * Debug.DrawLine( adjust + Vector2.left * box.x, leftFoot, Color.green );
         * else
         * Debug.DrawLine( adjust + Vector2.left * box.x, leftFoot, Color.grey );
         * if( right.transform != null )
         * Debug.DrawLine( adjust + Vector2.right * box.x, rightFoot, Color.green );
         * else
         * Debug.DrawLine( adjust + Vector2.right * box.x, rightFoot, Color.grey );
         *
         */
        #endregion

        float down = jumping ? raydown - downOffset : raydown;
        hitCount = Physics2D.BoxCastNonAlloc(adjust, box.size, 0, Vector2.down, RaycastHits, Mathf.Max(down, -velocity.y * dT), Global.CharacterCollideLayers);
        for (int i = 0; i < hitCount; i++)
        {
            hit = RaycastHits[i];
            if (IgnoreCollideObjects.Contains(hit.collider))
            {
                continue;
            }
            if (hit.normal.y > corner)
            {
                collideBottom   = true;
                adjust.y        = hit.point.y + box.size.y * 0.5f + downOffset;
                hitBottomNormal = hit.normal;
                // moving platforms
                Entity cha = hit.transform.GetComponent <Entity>();
                if (cha != null)
                {
#if UNITY_EDITOR
                    if (cha.GetInstanceID() == GetInstanceID())
                    {
                        Debug.LogError("character set itself as carry character", gameObject);
                        Debug.Break();
                    }
#endif
                    carryCharacter = cha;
                }
                break;
            }
        }

        hitCount = Physics2D.BoxCastNonAlloc(adjust + Vector2.down * headboxy, headbox, 0, Vector2.up, RaycastHits, Mathf.Max(raylength, velocity.y * dT), Global.CharacterCollideLayers);
        for (int i = 0; i < hitCount; i++)
        {
            hit = RaycastHits[i];
            if (IgnoreCollideObjects.Contains(hit.collider))
            {
                continue;
            }
            if (hit.normal.y < -corner)
            {
                collideTop = true;
                adjust.y   = hit.point.y - box.size.y * 0.5f - contactSeparation;
                break;
            }
        }

        hitCount = Physics2D.BoxCastNonAlloc(adjust, box.size, 0, Vector2.left, RaycastHits, Mathf.Max(contactSeparation, -velocity.x * dT), Global.CharacterCollideLayers);
        for (int i = 0; i < hitCount; i++)
        {
            hit = RaycastHits[i];
            if (IgnoreCollideObjects.Contains(hit.collider))
            {
                continue;
            }
            if (hit.normal.x > corner)
            {
                collideLeft     = true;
                hitLeft         = hit;
                adjust.x        = hit.point.x + box.size.x * 0.5f + contactSeparation;
                wallSlideNormal = hit.normal;
                break;
            }
        }

        hitCount = Physics2D.BoxCastNonAlloc(adjust, box.size, 0, Vector2.right, RaycastHits, Mathf.Max(contactSeparation, velocity.x * dT), Global.CharacterCollideLayers);
        for (int i = 0; i < hitCount; i++)
        {
            hit = RaycastHits[i];
            if (IgnoreCollideObjects.Contains(hit.collider))
            {
                continue;
            }
            if (hit.normal.x < -corner)
            {
                collideRight    = true;
                hitRight        = hit;
                adjust.x        = hit.point.x - box.size.x * 0.5f - contactSeparation;
                wallSlideNormal = hit.normal;
                break;
            }
        }

        transform.position = adjust;
    }