//Cast an array of rays into '_direction' and centered around '_origin'; private void CastRayArray(Vector3 _origin, Vector3 _direction) { //Calculate origin and direction of ray in world coordinates; Vector3 _rayStartPosition = Vector3.zero; Vector3 rayDirection = GetCastDirection(); //Clear results from last frame; arrayNormals.Clear(); arrayPoints.Clear(); RaycastHit _hit; //Cast array; for (int i = 0; i < raycastArrayStartPositions.Length; i++) { //Calculate ray start position; _rayStartPosition = _origin + tr.TransformDirection(raycastArrayStartPositions[i]); if (Physics.Raycast(_rayStartPosition, rayDirection, out _hit, castLength, layermask, QueryTriggerInteraction.Ignore)) { if (isInDebugMode) { Debug.DrawRay(_hit.point, _hit.normal, Color.red, Time.fixedDeltaTime * 1.01f); } hitColliders.Add(_hit.collider); hitTransforms.Add(_hit.transform); arrayNormals.Add(_hit.normal); arrayPoints.Add(_hit.point); } } //Evaluate results; hasDetectedHit = (arrayPoints.Count > 0); if (hasDetectedHit) { //Calculate average surface normal; Vector3 _averageNormal = Vector3.zero; foreach (Vector3 v in arrayNormals) { _averageNormal += v; } _averageNormal.Normalize(); //Calculate average surface point; Vector3 _averagePoint = Vector3.zero; foreach (Vector3 v in arrayPoints) { _averagePoint += v; } _averagePoint /= arrayPoints.Count; hitPosition = _averagePoint; hitNormal = _averageNormal; hitDistance = VectorMath.ExtractDotVector(_origin - hitPosition, _direction).magnitude; } }
private bool IsRisingOrFalling() { Vector3 verticalMomentum = VectorMath.ExtractDotVector(this.momentum, this.locomotionDriver.transform.up); float limit = 0.001f; return(verticalMomentum.magnitude > limit); }
//Apply friction to both vertical and horizontal momentum based on 'friction' and 'gravity'; //Handle sliding down steep slopes; void HandleMomentum() { Vector3 _verticalMomentum = Vector3.zero; Vector3 _horizontalMomentum = Vector3.zero; //Split momentum into vertical and horizontal components; if (momentum != Vector3.zero) { _verticalMomentum = VectorMath.ExtractDotVector(momentum, tr.up); _horizontalMomentum = momentum - _verticalMomentum; } //Add gravity to vertical momentum; if (currentControllerState == ControllerState.Sliding) { _verticalMomentum -= tr.up * slideGravity * Time.deltaTime; } else { _verticalMomentum -= tr.up * gravity * Time.deltaTime; } //Remove any downward force if the controller is grounded; if (currentControllerState == ControllerState.Grounded) { _verticalMomentum = Vector3.zero; } //Apply friction to horizontal momentum based on whether the controller is grounded; if (IsGrounded()) { _horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(_horizontalMomentum, groundFriction, Time.deltaTime, 0f); } else { _horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(_horizontalMomentum, airFriction, Time.deltaTime, 0f); } //Add horizontal and vertical momentum back together; momentum = _horizontalMomentum + _verticalMomentum; //Project the current momentum onto the current ground normal if the controller is sliding down a slope; if (currentControllerState == ControllerState.Sliding) { momentum = Vector3.ProjectOnPlane(momentum, mover.GetGroundNormal()); } //If controller is jumping, override vertical velocity with jumpSpeed; if (currentControllerState == ControllerState.Jumping) { momentum = VectorMath.RemoveDotVector(momentum, tr.up); momentum += tr.up * jumpSpeed; } }
//Helper functions; //Returns 'true' if vertical momentum is above a small threshold; private bool IsRisingOrFalling() { //Calculate current vertical momentum; Vector3 _verticalMomentum = VectorMath.ExtractDotVector(GetMomentum(), _characterGameObject.transform.up); //Setup threshold to check against; //For most applications, a value of '0.001f' is recommended; float _limit = 0.001f; //Return true if vertical momentum is above '_limit'; return(_verticalMomentum.magnitude > _limit); }
//Helper functions; //Returns 'true' if vertical momentum is above a small threshold; bool IsFalling() { //Calculate current vertical momentum; Vector3 _verticalMomentum = VectorMath.ExtractDotVector(m_momentum, m_trans.up); //Setup threshold to check against; //For most applications, a value of '0.001f' is recommended; float _limit = 0.001f; //Return true if vertical momentum is above '_limit'; return(_verticalMomentum.magnitude > _limit); }
//Cast a sphere into '_direction' from '_origin'; private void CastSphere(Vector3 _origin, Vector3 _direction) { RaycastHit _hit; hasDetectedHit = Physics.SphereCast(_origin, sphereCastRadius, _direction, out _hit, castLength - sphereCastRadius, layermask, QueryTriggerInteraction.Ignore); if (hasDetectedHit) { hitPosition = _hit.point; hitNormal = _hit.normal; hitColliders.Add(_hit.collider); hitTransforms.Add(_hit.transform); hitDistance = _hit.distance; hitDistance += sphereCastRadius; //Calculate real distance; if (calculateRealDistance) { hitDistance = VectorMath.ExtractDotVector(_origin - hitPosition, _direction).magnitude; } Collider _col = hitColliders[0]; //Calculate real surface normal by casting an additional raycast; if (calculateRealSurfaceNormal) { if (_col.Raycast(new Ray(hitPosition - _direction, _direction), out _hit, 1.5f)) { if (Vector3.Angle(_hit.normal, -_direction) >= 89f) { hitNormal = backupNormal; } else { hitNormal = _hit.normal; } } else { hitNormal = backupNormal; } backupNormal = hitNormal; } } }
private void HandleMomentum() { var verticalMomentum = Vector3.zero; var horizontalMomentum = Vector3.zero; if (momentum != Vector3.zero) { verticalMomentum = VectorMath.ExtractDotVector(momentum, mover.transform.up); horizontalMomentum = momentum - verticalMomentum; } if (currentMotorState == PlayerMotorStateEnum.Sliding) { verticalMomentum -= mover.transform.up * motorVariables.SlideGravity * Time.fixedDeltaTime; } else { verticalMomentum -= mover.transform.up * motorVariables.Gravity * Time.fixedDeltaTime; } if (currentMotorState == PlayerMotorStateEnum.Grounded) { verticalMomentum = Vector3.zero; } if (IsGrounded) { horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(horizontalMomentum, motorVariables.GroundFriction, Time.fixedDeltaTime, 0f); } else { horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(horizontalMomentum, motorVariables.AirFriction, Time.fixedDeltaTime, 0f); } momentum = horizontalMomentum + verticalMomentum; if (currentMotorState == PlayerMotorStateEnum.Sliding) { momentum = Vector3.ProjectOnPlane(momentum, mover.GetGroundNormal()); } if (currentMotorState == PlayerMotorStateEnum.Jumping) { momentum = VectorMath.RemoveDotVector(momentum, mover.transform.up); momentum += mover.transform.up * motorVariables.JumpSpeed; } }
//Apply friction to both vertical and horizontal momentum based on 'friction' and 'gravity'; //Handle sliding down steep slopes; void HandleMomentum() { Vector3 _verticalMomentum = Vector3.zero; Vector3 _horizontalMomentum = Vector3.zero; //Split momentum into vertical and horizontal components; if (m_momentum != Vector3.zero) { _verticalMomentum = VectorMath.ExtractDotVector(m_momentum, m_trans.up); _horizontalMomentum = m_momentum - _verticalMomentum; } //Add gravity to vertical momentum; // if (m_useGravity) // { _verticalMomentum -= m_trans.up * m_physics.m_gravity * Time.deltaTime; if (PlayerIsGrounded() || !m_hasToFall) { _verticalMomentum = Vector3.zero; } // } //Apply friction to horizontal momentum based on whether the controller is grounded; if (PlayerIsGrounded() && !m_hasToFall) { _horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(_horizontalMomentum, m_physics.m_groundFriction, Time.deltaTime, 0f); } else { _horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(_horizontalMomentum, m_physics.m_airFriction, Time.deltaTime, 0f); } //Add horizontal and vertical momentum back together; m_momentum = _horizontalMomentum + _verticalMomentum; if (CurrentState(PlayerState.Jump)) { m_momentum = VectorMath.RemoveDotVector(m_momentum, m_trans.up); AddJumpMomentum(); } }
private void HandleGravity() { Vector3 verticalMomentum = Vector3.zero; Vector3 horizontalMomentum = Vector3.zero; if (this.momentum != Vector3.zero) { verticalMomentum = VectorMath.ExtractDotVector(this.momentum, this.locomotionDriver.transform.up); horizontalMomentum = this.momentum - verticalMomentum; } verticalMomentum += this.locomotionDriver.transform.up * gravity * Time.fixedDeltaTime; if (this.character.IsGrounded()) { this.lastGroundTime = Time.fixedTime; verticalMomentum = Vector3.zero; } this.momentum = horizontalMomentum + verticalMomentum; }
//Apply friction to both vertical and horizontal momentum based on 'friction' and 'gravity'; //Handle sliding down steep slopes; void HandleMomentum() { //If local momentum is used, transform momentum into world coordinates first; if (useLocalMomentum) { momentum = _characterGameObject.transform.localToWorldMatrix * momentum; } Vector3 _verticalMomentum = Vector3.zero; Vector3 _horizontalMomentum = Vector3.zero; //Split momentum into vertical and horizontal components; if (momentum != Vector3.zero) { _verticalMomentum = VectorMath.ExtractDotVector(momentum, _characterGameObject.transform.up); _horizontalMomentum = momentum - _verticalMomentum; } //Add gravity to vertical momentum; _verticalMomentum += _characterGameObject.transform.up * gravity * Time.deltaTime; //Remove any downward force if the controller is grounded; if (_state == LocomotionState.Grounded) { _verticalMomentum = Vector3.zero; } //Apply friction to horizontal momentum based on whether the controller is grounded; if (_state == LocomotionState.Grounded) { _horizontalMomentum = VectorMath.IncrementVectorTowardTargetVector(_horizontalMomentum, groundFriction, Time.deltaTime, Vector3.zero); } else { _horizontalMomentum = VectorMath.IncrementVectorTowardTargetVector(_horizontalMomentum, airFriction, Time.deltaTime, Vector3.zero); } //Add horizontal and vertical momentum back together; momentum = _horizontalMomentum + _verticalMomentum; //Project the current momentum onto the current ground normal if the controller is sliding down a slope; if (_state == LocomotionState.Sliding) { momentum = Vector3.ProjectOnPlane(momentum, _characterMover.GetGroundNormal()); } //Apply slide gravity along ground normal, if controller is sliding; if (_state == LocomotionState.Sliding) { Vector3 _slideDirection = Vector3.ProjectOnPlane(-_characterGameObject.transform.up, _characterMover.GetGroundNormal()).normalized; momentum += _slideDirection * slideGravity * Time.deltaTime; momentum = Vector3.ClampMagnitude(momentum, slidingMaxVelocity); } //If controller is jumping, override vertical velocity with jumpSpeed; if (_state == LocomotionState.Jumping) { //momentum = VectorMath.RemoveDotVector(momentum, _characterGameObject.transform.up); //momentum += _characterGameObject.transform.up * jumpSpeed; if (JumpVelocity != Vector3.zero) { momentum.x = 0f; momentum.z = 0f; momentum += JumpVelocity; JumpVelocity = Vector3.zero; } } if (useLocalMomentum) { momentum = _characterGameObject.transform.worldToLocalMatrix * momentum; } }
void HandleMomentum() { //If local momentum is used, transform momentum into world coordinates first; if (useLocalMomentum) { momentum = transform.localToWorldMatrix * momentum; } Vector3 _verticalMomentum = Vector3.zero; Vector3 _horizontalMomentum = Vector3.zero; //Split momentum into vertical and horizontal components; if (momentum != Vector3.zero) { _verticalMomentum = VectorMath.ExtractDotVector(momentum, transform.up); _horizontalMomentum = momentum - _verticalMomentum; } //Add gravity to vertical momentum; _verticalMomentum -= transform.up * gravity * Time.deltaTime; //Remove any downward force if the controller is grounded; if (currentControllerState == ControllerState.Grounded) { _verticalMomentum = Vector3.zero; } //Apply friction to horizontal momentum based on whether the controller is grounded; if (currentControllerState == ControllerState.Grounded) { _horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(_horizontalMomentum, groundFriction, Time.deltaTime, 0f); } else { _horizontalMomentum = VectorMath.IncrementVectorLengthTowardTargetLength(_horizontalMomentum, airFriction, Time.deltaTime, 0f); } //Add horizontal and vertical momentum back together; momentum = _horizontalMomentum + _verticalMomentum; //Project the current momentum onto the current ground normal if the controller is sliding down a slope; if (currentControllerState == ControllerState.Sliding) { //momentum = Vector3.ProjectOnPlane(momentum, mover.GetGroundNormal()); } //Apply slide gravity along ground normal, if controller is sliding; if (currentControllerState == ControllerState.Sliding) { //Vector3 _slideDirection = Vector3.ProjectOnPlane(-tr.up, mover.GetGroundNormal()).normalized; //momentum += _slideDirection * slideGravity * Time.deltaTime; } //If controller is jumping, override vertical velocity with jumpSpeed; if (currentControllerState == ControllerState.Jumping) { momentum = VectorMath.RemoveDotVector(momentum, transform.up); momentum += transform.up * jumpSpeed; } if (useLocalMomentum) { momentum = transform.worldToLocalMatrix * momentum; } }
private bool IsRisingOrFalling() { var verticalMomentum = VectorMath.ExtractDotVector(momentum, mover.transform.up); return(verticalMomentum.magnitude > 0.001f); }