/// <summary> /// The character should start the jump. /// </summary> private void ApplyJumpForce() { if (IsActive && !m_JumpApplied) { // A surface effect can optionally play when the character leaves the ground. if (m_JumpSurfaceImpact != null) { SurfaceManager.SpawnEffect(m_CharacterLocomotion.GroundRaycastHit, m_JumpSurfaceImpact, m_CharacterLocomotion.GravityDirection, m_CharacterLocomotion.TimeScale, m_GameObject); } // Do not set the Jumping variable because the ability should be active for at least one frame. If Jumping was set there is a chance // the ability could stop right away if the character jumps while moving down a slope. m_JumpApplied = true; m_JumpTime = Time.time; var force = m_Force; // Prevent the character from jumping as high when moving backwards or sideways. if (m_CharacterLocomotion.InputVector.y < 0) { force *= Mathf.Lerp(1, m_BackwardsForceMultiplier, Mathf.Abs(m_CharacterLocomotion.InputVector.y)); } else { // The character's forward movement will contribute to a full jump force. force *= Mathf.Lerp(1, m_SidewaysForceMultiplier, Mathf.Abs(m_CharacterLocomotion.InputVector.x) - Mathf.Abs(m_CharacterLocomotion.InputVector.y)); } AddForce(m_CharacterLocomotion.Up * force, m_Frames, false, true); // Ensure the character is in the air after jumping. Scheduler.ScheduleFixed(Time.fixedDeltaTime + .001f, EnsureAirborne); } }
/// <summary> /// A footstep has occurred. Notify the SurfaceManager. /// </summary> /// <param name="foot">The foot which caused the footstep.</param> /// <param name="flipFootprint">Should the footprint be flipped?</param> /// <returns>True if the footstep was successfully planted.</returns> public virtual bool FootStep(Transform foot, bool flipFootprint) { // A RaycastHit is required for the SurfaceManager. RaycastHit hit; if (Physics.Raycast(foot.position + m_CharacterLocomotion.Up * 0.1f, -m_CharacterLocomotion.Up, out hit, 0.11f + m_FootOffset, m_CharacterLayerManager.IgnoreInvisibleCharacterWaterLayers, QueryTriggerInteraction.Ignore)) { SurfaceManager.SpawnEffect(hit, m_SurfaceImpact, m_CharacterLocomotion.GravityDirection, m_CharacterLocomotion.TimeScale, foot.gameObject, m_Transform.forward, flipFootprint); return(true); } return(false); }
/// <summary> /// The object has collided with another object. /// </summary> /// <param name="hit">The RaycastHit of the object. Can be null.</param> protected virtual void OnCollision(RaycastHit?hit) { if (hit != null && hit.HasValue) { m_ActiveAudioClipSet.Stop(m_GameObject, 0); // A Rigidbody should be affected by the impact. if (hit.Value.rigidbody != null && m_Collider != null && m_Collider.enabled) { hit.Value.rigidbody.AddForceAtPosition(m_Velocity, hit.Value.point); } // An impact has occurred. if (m_SurfaceImpact != null) { SurfaceManager.SpawnEffect(hit.Value, m_SurfaceImpact, m_NormalizedGravity, m_TimeScale, m_GameObject); } } }
/// <summary> /// The character has changed grounded states. /// </summary> /// <param name="grounded">Is the character on the ground?</param> private void OnGrounded(bool grounded) { if (grounded) { // Allow the SurfaceManager to play an effect when the character hits the ground. if (m_LandSurfaceImpact != null && m_CharacterLocomotion.LocalVelocity.y < m_MinSurfaceImpactVelocity) { SurfaceManager.SpawnEffect(m_CharacterLocomotion.GroundRaycastHit, m_LandSurfaceImpact, m_CharacterLocomotion.GravityDirection, m_CharacterLocomotion.TimeScale, m_GameObject, m_Transform.forward, false); } // Move to the fall end state when the character lands. m_StateIndex = 1; if (!m_LandEvent.WaitForAnimationEvent) { Scheduler.ScheduleFixed(m_LandEvent.Duration, Land); } } else { m_StateIndex = 0; } }
/// <summary> /// The character has changed grounded states. /// </summary> /// <param name="grounded">Is the character on the ground?</param> private void OnGrounded(bool grounded) { if (!IsActive) { return; } if (grounded) { SurfaceManager.SpawnEffect(m_CharacterLocomotion.GroundRaycastHit, m_GroundImpact, m_CharacterLocomotion.GravityDirection, m_CharacterLocomotion.TimeScale, m_GameObject); EventHandler.ExecuteEvent(m_GameObject, "OnAddSecondaryCameraForce", m_GroundPositionCameraRecoil.RandomValue, m_GroundRotationCameraRecoil.RandomValue, 0f); // The item may have completed its use before the object is grounded. if (CanStopAbility()) { StopAbility(); } else { m_UseOnGroundedSubstate = true; m_CharacterLocomotion.UpdateItemAbilityAnimatorParameters(); } } }
/// <summary> /// Perform the impact action. /// </summary> /// <param name="castID">The ID of the cast.</param> /// <param name="source">The object that caused the cast.</param> /// <param name="target">The object that was hit by the cast.</param> /// <param name="hit">The raycast that caused the impact.</param> protected override void ImpactInternal(uint castID, GameObject source, GameObject target, RaycastHit hit) { SurfaceManager.SpawnEffect(hit, m_MagicItem.SurfaceImpact, m_CharacterLocomotion.Up, m_CharacterLocomotion.TimeScale, m_CharacterLocomotion.gameObject); }