/// <summary> /// Updates the motion over time. This is called by the controller /// every update cycle so animations and stages can be updated. /// </summary> /// <param name="rDeltaTime">Time since the last frame (or fixed update call)</param> /// <param name="rUpdateIndex">Index of the update to help manage dynamic/fixed updates. [0: Invalid update, >=1: Valid update]</param> public override void Update(float rDeltaTime, int rUpdateIndex) { mMovement = Vector3.zero; // Add movement based on the dive if ((mMotionLayer._AnimatorStateID == STATE_run_to_dive && mMotionLayer._AnimatorStateNormalizedTime > 0.5f) || mMotionLayer._AnimatorTransitionID == TRANS_run_to_dive_SwimIdlePose || mMotionLayer._AnimatorTransitionID == TRANS_run_to_dive_TreadIdlePose) { mMovement = mMomentum * _InWaterMomentumFactor * rDeltaTime; } // Test if it's time to play the splash if (!mHasHitWater) { if ((mMotionLayer._AnimatorStateID == STATE_run_to_dive && mMotionLayer._AnimatorStateNormalizedTime > 0.65f) || (mMotionLayer._AnimatorStateID == STATE_StandingDive && mMotionLayer._AnimatorStateNormalizedTime > 0.65f)) { float lDepth = mSwimmerInfo.GetDepth(); if (!mHasSplashed && lDepth > 0.1f) { mHasSplashed = true; mSwimmerInfo.CreateSplash(mMotionController._Transform.position + (mMotionController._Transform.forward * 1f)); } if (lDepth > _RecoverDepth) { mHasHitWater = true; mSwimmerInfo.EnterWater(); mMotionController.SetAnimatorMotionPhase(mMotionLayer._AnimatorLayerIndex, PHASE_ENTER_WATER, true); } } } else { // We still want gravity to take effect to a little while... just to represent momentum if (mMomentum.y == 0f && mMotionLayer._AnimatorTransitionID != 0 && mMotionLayer._AnimatorTransitionNormalizedTime < 0.5f) { mMovement.y = mMovement.y + (UnityEngine.Physics.gravity.y * _InWaterMomentumFactor * 0.25f * rDeltaTime); } } // This is a safety check to ensure we don't run aground if ((mMotionLayer._AnimatorStateID == STATE_run_to_dive && mMotionLayer._AnimatorStateNormalizedTime > 0.65f)) { if (RaycastExt.SafeRaycast(mMotionController._Transform.position + (Vector3.up * mSwimmerInfo.EnterDepth * 0.1f), Vector3.down, 0.12f, mActorController.GroundingLayers, mMotionController._Transform, null, false)) { Deactivate(); } } }
/// <summary> /// Tests if the motion should continue. If it shouldn't, the motion /// is typically disabled /// </summary> /// <returns></returns> public override bool TestUpdate() { if (mIsActivatedFrame) { return(true); } if (mActorController.State.Stance != EnumControllerStance.SWIMMING) { return(false); } // Ensure we're in the animation if (mIsAnimatorActive && !IsInMotionState) { return(false); } // Ensure we're in water if (mSwimmerInfo == null || mSwimmerInfo.WaterSurface == null) { return(false); } // If we're in the idle state with no movement, stop if (mMotionLayer._AnimatorStateID == STATE_TreadIdlePose) { if (mMotionController.State.InputMagnitudeTrend.Value < 0.1f) { return(false); } } // If we're surfacing, exit to the idle pose else if (mMotionLayer._AnimatorStateID == STATE_IdlePose) { mSwimmerInfo.ExitWater(); return(false); } // Just incse, ensure we're in water float lWaterMovement = mSwimmerInfo.WaterSurface.position.y - mSwimmerInfo.WaterSurfaceLastPosition.y; float lDepth = mSwimmerInfo.GetDepth(); if (lDepth - lWaterMovement <= 0f) { mSwimmerInfo.ExitWater(); return(false); } // Stay in return(true); }
/// <summary> /// Tests if this motion should be started. However, the motion /// isn't actually started. /// </summary> /// <returns></returns> public override bool TestActivate() { if (!mIsStartable) { return(false); } // Grab the swimmer info if it doesn't exist if (mSwimmerInfo == null) { mSwimmerInfo = SwimmerInfo.GetSwimmerInfo(mMotionController._Transform); } // This is only valid if we're in the right stance if (mActorController.State.Stance != EnumControllerStance.SWIMMING) { return(false); } // Check that we're actually moving fast mIsRunning = (mSwimStrafe != null && mSwimStrafe.IsActive && mSwimStrafe.IsRunning); // If we passed last frame, ensure the platform isn't moving down if (mIsSecondPass) { mIsSecondPass = false; // Ensure there is STILL an edge without the bounds bool lIsFound = RaycastExt.GetForwardEdge2(mMotionController._Transform, _MinHeight * _BodyScale, _MaxHeight * _BodyScale, 0.1f * _BodyScale, (_BodyRadius + _MaxDistance) * (mIsRunning ? 2f : 1f) * _BodyScale, _ClimbableLayers, out mRaycastHitInfo); if (lIsFound && mRaycastHitInfo.collider.gameObject.transform.position.y >= mLastPlatformPosition.y) { return(true); } } else { // Check if the user initiated exiting if (mMotionController._InputSource != null && mMotionController._InputSource.IsJustPressed(ActionAlias)) { // We can't exit if we're too deep if (_MaxDepth > 0f && mSwimmerInfo.GetDepth() < _MaxDepth * _BodyScale) { // Ensure there is an edge without the bounds bool lIsFound = RaycastExt.GetForwardEdge2(mMotionController._Transform, _MinHeight * _BodyScale, _MaxHeight * _BodyScale, 0.1f * _BodyScale, (_BodyRadius + _MaxDistance) * (mIsRunning ? 2f : 1f) * _BodyScale, _ClimbableLayers, out mRaycastHitInfo); if (lIsFound) { mIsSecondPass = true; mLastPlatformPosition = mRaycastHitInfo.collider.gameObject.transform.position; } } } } #if UNITY_EDITOR if (_IsDebugEnabled) { Vector3 lStart = mMotionController._Transform.position + (mMotionController._Transform.up * _MinHeight * _BodyScale) + (mMotionController._Transform.forward * _MinDistance * _BodyScale); Vector3 lEnd = mMotionController._Transform.position + (mMotionController._Transform.up * _MinHeight * _BodyScale) + (mMotionController._Transform.forward * _MaxDistance * (mIsRunning ? 2f : 1f) * _BodyScale); com.ootii.Graphics.GraphicsManager.DrawLine(lStart, lEnd, Color.blue); lStart = mMotionController._Transform.position + (mMotionController._Transform.up * _MaxHeight * _BodyScale) + (mMotionController._Transform.forward * _MinDistance * _BodyScale); lEnd = mMotionController._Transform.position + (mMotionController._Transform.up * _MaxHeight * _BodyScale) + (mMotionController._Transform.forward * _MaxDistance * (mIsRunning ? 2f : 1f) * _BodyScale); com.ootii.Graphics.GraphicsManager.DrawLine(lStart, lEnd, Color.blue); } #endif // Return the final result return(false); }