void FixedUpdate() { // Fix an issue when m_isGrounded is always false the first update if SmartRectCollider2D was not updated first if (m_skipFirstFixedUpdate) { m_skipFirstFixedUpdate = false; return; } Vector3 vLocVelocity = transform.rotation != Quaternion.identity ? Quaternion.Inverse(transform.rotation) * m_smartRectCollider.InstantVelocity : m_smartRectCollider.InstantVelocity; m_isGrounded = m_smartRectCollider.enabled && m_smartRectCollider.IsGrounded() && vLocVelocity.y <= Vector3.kEpsilon; if (m_isGrounded) { m_fallingJumpToleranceTimer = FallingJumpTolerance; } if (m_isController) { if (State != eState.Dying) { m_spriteRenderer.color = Color.white; VPad.Update(); float fHorAxis = VPad.GetAxis("Horizontal"); float fVerAxis = VPad.GetAxis("Vertical"); // Fix issue when using keys, because the time to go from 0 to 1 or 1 to 0 is too high by default Unity parameters // So if a moving key is pressed, the horizontal axis will be set to the right value directly if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) { fHorAxis = 1f; } else if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) { fHorAxis = -1f; } //--- if (m_isClimbing) { // isLadder is true when the collider width is small enough to avoid moving horizontal and center the player in the center of the collider. // By default, it is true when collider width is less than two times the smart rect collider width bool isLadder = (m_currentClimbingCollider is BoxCollider2D) && ((BoxCollider2D)m_currentClimbingCollider).size.x < 2 * m_smartRectCollider.Size.x; Vector3 vDisp = new Vector3(isLadder ? 0f : fHorAxis, fVerAxis); if (isLadder) { // Snap to ladder BoxCollider2D box2DCollider = (BoxCollider2D)m_currentClimbingCollider; Vector3 center = box2DCollider.transform.TransformPoint(box2DCollider.offset); Vector3 snapPos = Vector3.Project(transform.position - center, m_currentClimbingCollider.transform.up); // this allow rotated ladders, like in pirate ship demo snapPos += center; snapPos.z = transform.position.z; transform.position = Vector3.Lerp(transform.position, snapPos, 0.5f); } if (vDisp.magnitude > 0.2f) { transform.position += transform.rotation * vDisp * ClimbingSpeed * Time.deltaTime; SetNextState(eState.Climbing); } else { SetNextState(eState.ClimbingIdle); } } else // normal walking { bool isWalking = (Mathf.Abs(fHorAxis) > 0.7f); fHorAxis = Mathf.Sign(fHorAxis) * Mathf.Max(Mathf.Abs(fHorAxis), 0.4f); if (isWalking) { SetNextState(m_isGrounded ? eState.Walking : (m_smartRectCollider.InstantVelocity.y > 0f ? eState.Jumping : eState.Falling)); float walkAcc = fHorAxis > 0 ? WalkAcc : -WalkAcc; float fHorAxisAbs = Mathf.Abs(fHorAxis); if (Mathf.Sign(fHorAxis) != Mathf.Sign(m_walkVeloc.x) && m_walkVeloc.x != 0) { m_walkVeloc.x += walkAcc + walkAcc * WalkReactivity * fHorAxisAbs; } else { m_walkVeloc.x += walkAcc; } float walkSpeed = m_isSwimming ? WalkSpeed / 2 : WalkSpeed; m_walkVeloc.x = Mathf.Clamp(m_walkVeloc.x, -walkSpeed * fHorAxisAbs, walkSpeed * fHorAxisAbs); float movingSign = (IsSpriteFacingRight ? Mathf.Sign(m_walkVeloc.x) : -Mathf.Sign(m_walkVeloc.x)); if (movingSign != Mathf.Sign(transform.localScale.x)) { Vector3 tempScale = transform.localScale; tempScale.x = -tempScale.x; // flip player transform.localScale = tempScale; } } else { SetNextState(m_isGrounded ? eState.Idle : (m_smartRectCollider.InstantVelocity.y > 0f ? eState.Jumping : eState.Falling)); m_walkVeloc *= Mathf.Clamp01(1 - m_rigidBody2D.drag * Time.deltaTime); } // Apply walk velocity Vector3 locWalkVeloc = transform.rotation != Quaternion.identity ? transform.rotation * m_walkVeloc : m_walkVeloc; transform.position += locWalkVeloc * Time.deltaTime; // Apply jump speed if (m_jumpSpeed > 0f) { Vector3 gravity = Physics2D.gravity * (m_rigidBody2D.gravityScale == 0f ? 1f : m_rigidBody2D.gravityScale); Vector3 locJumpVeloc = m_jumpSpeed * transform.up; transform.position += locJumpVeloc * Time.deltaTime + 0.5f * gravity * Time.deltaTime * Time.deltaTime; m_jumpSpeed = Mathf.Max(0f, m_jumpSpeed - (gravity.magnitude + m_rigidBody2D.drag * JumpDragFactor) * Time.deltaTime); if (m_jumpSpeed < Vector3.kEpsilon) { m_jumpSpeed = 0f; } } } // Check if going down and there is a climbing collider below float SkinBottomWidthFactor = 1.1f; //NOTE: set a value > 1f to allow climbing down when climb collision and platform collision are close Collider2D climbingColliderBelow = GetClimbingColliderBelow(SkinBottomWidthFactor); Collider2D climbingColliderAbove = GetClimbingColliderAbove(); if (fVerAxis < -0.5f && m_currentClimbingCollider == null) { if (climbingColliderBelow != null) { if (m_currentClimbingCollider == null) { m_smartRectCollider.TeleportTo(transform.position - transform.up * m_smartRectCollider.SkinBottomWidth * SkinBottomWidthFactor); } m_currentClimbingCollider = climbingColliderBelow; StartClimbing(); } else { StopClimbing(); } } // Check if going up and it is inside a climbing collider else if (fVerAxis > 0.5f) { if (climbingColliderAbove != null) { m_currentClimbingCollider = climbingColliderAbove; StartClimbing(); } else if (m_smartRectCollider.SkinBottomRayContacts.Contains(true) || climbingColliderBelow == null) { StopClimbing(); } } // Stop climbing once the top is reached else if (m_isGrounded || (climbingColliderBelow == null && climbingColliderAbove == null)) { StopClimbing(); } /*/ Used to teleport player to mouse position and test collisions with world * if( Input.GetMouseButton(0) ) * { * Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); * pos.z = transform.position.z; * transform.position = pos; * } * //*/ } } else { } }