//Query whether this module can be active, given the current state of the character controller (velocity, isGrounded etc.) //Called every frame when inactive (to see if it could be) and when active (to see if it should not be) public override bool IsApplicable() { if (m_ControlledCollider.IsGrounded() || (DoesInputExist("Crouch") && GetButtonInput("Crouch").m_IsPressed) || GetDirInput("Move").m_Direction == DirectionInput.Direction.Down || m_CharacterController.DidJustJump()) { return(false); } //Prevent overriding walljumps if (GetDirInput("Move").IsInThisDirection(m_ControlledCollider.GetEdgeCastInfo().GetWallNormal())) { return(false); } if ((m_CharacterController.GetJumpIsCached()) && m_ControlledCollider.IsTouchingEdge()) { //Move up to avoid transitioning into a wallrun. //Also used to prevent small distance jumps. CEdgeCastInfo edgeInfo = m_ControlledCollider.GetEdgeCastInfo(); CapsuleTransform copy = m_ControlledCollider.GetCapsuleTransformCopy(); Vector3 headStartDisplacement = edgeInfo.GetEdgeNormal() * (m_ControlledCollider.GetRadius() + 0.1f) + edgeInfo.GetWallNormal() * 0.015f; if (!copy.CanMove(headStartDisplacement, true)) { return(false); } copy.Move(headStartDisplacement); m_ProposedNewPosition = copy.GetPosition(); return(true); } return(false); }
//Main movement update //Used by CharacterControllerBase to move the collider and update its velocity in the process //This will collide against geometry and take appropriate action public override void UpdateWithVelocity(Vector2 a_Velocity) { #if UNITY_EDITOR //If the length has been edited in the inspector since last update, see if the capsule transform needs to be updated if (m_Length != m_PrevLength) { if (m_PrevLength == m_CapsuleTransform.GetLength()) { m_CapsuleTransform.SetLength(m_Length, CapsuleResizeMethod.FromBottom); } m_PrevLength = m_Length; } #endif //The character may have been moved, either via script or via editor. Adjust position to make up for this CheckForUpdatedPosition(); Vector3 realVel = new Vector3(a_Velocity.x, a_Velocity.y, 0) * Time.fixedDeltaTime; m_Collisions.Clear(); if (m_CollisionsActive) { TryMove(realVel, ref a_Velocity); } else { m_CapsuleTransform.Move(realVel); } m_PrevVelocity = m_Velocity; m_Velocity = a_Velocity; UpdateContextInfo(); //MOVINGCOLPOINT, see CapsuleMovingColliderSolver for more details if (IsGrounded()) { AddColPoint(m_State.m_GroundedInfo.GetGroundTransform(), m_State.m_GroundedInfo.GetPoint(), m_State.m_GroundedInfo.GetNormal()); } }
//Called for every fixedupdate that this module is active public override void FixedUpdateModule() { float currentTransitionTime = Time.time - m_TransitionStartTime; //A MovingColPoint is used to move and rotate the animation path when the collider it starts on is moved //This allows animated abilities to work on moving colliders if (m_ReferencePoint != null) { //Position CapsuleTransform copy = m_ControlledCollider.GetCapsuleTransformCopy(); Vector3 diff = m_ReferencePoint.m_Transform.position - m_ReferencePoint.m_PrevPoint; copy.Move(diff); m_Path.Move(diff); //Rotation Quaternion rotationDifference = Quaternion.FromToRotation(m_ReferencePoint.m_PrevRot * Vector3.up, m_ReferencePoint.m_Transform.rotation * Vector3.up); copy.Rotate(rotationDifference * copy.GetUpDirection(), RotateMethod.FromCenter); m_Path.Rotate(rotationDifference, m_ReferencePoint.m_PrevPoint); //Offset for rotation Vector3 newRelativePoint = rotationDifference * m_ReferencePoint.m_PointRelativeToThis; Vector3 relativeDifference = newRelativePoint - m_ReferencePoint.m_PointRelativeToThis; copy.Move(relativeDifference); m_ReferencePoint.m_PrevPoint = m_ReferencePoint.m_Transform.position; m_ReferencePoint.m_PrevRot = m_ReferencePoint.m_Transform.rotation; m_ReferencePoint.m_PointRelativeToThis = m_ReferencePoint.m_Transform.position - m_ControlledCollider.GetCapsuleTransform().GetPosition(); m_ReferencePoint.m_Normal = Quaternion.FromToRotation(m_ReferencePoint.m_PrevRot * Vector3.up, m_ReferencePoint.m_Transform.rotation * Vector3.up) * m_ReferencePoint.m_Normal; if (copy.CanExistHere()) { m_ControlledCollider.ApplyCapsuleTransform(copy); } else { m_WasInterrupted = true; return; } } m_ControlledCollider.SetVelocity(Vector2.zero); //Move along the nodes as long as they can be applied (either they are finished or their duration is 0) while (!m_Path.IsDone() && m_Path.m_CurrentPathNode != null && (m_Path.m_CurrentPathNode.m_Duration == 0 || Time.time - m_TransitionStartTime >= m_Path.m_CurrentPathNode.m_Duration)) { if (m_Path.m_CurrentPathNode.CanApplyEntireMovement(m_ControlledCollider.GetCapsuleTransform())) { m_TransitionStartTime += m_Path.m_CurrentPathNode.m_Duration; currentTransitionTime -= m_Path.m_CurrentPathNode.m_Duration; m_Path.m_CurrentPathNode.ApplyEntireMovement(m_ControlledCollider.GetCapsuleTransform()); m_Path.IncrementCurrentNode(); } else { m_WasInterrupted = true; return; } } //Move along the current node if (m_Path.CanApplyMotion(m_ControlledCollider.GetCapsuleTransform(), currentTransitionTime)) { m_Path.ApplyMotion(m_ControlledCollider.GetCapsuleTransform(), currentTransitionTime); } else { m_WasInterrupted = true; return; } m_ControlledCollider.UpdateContextInfo(); }