private void CalculateFriction() { var isGrounded = _wheelCollisionDetector.TryGetCollision(out var point, out var normal, out var collider, out var rb, out var t); if (!isGrounded) { return; } var forceOffset = transform.up * _applyForcesOffset; var right = transform.right; var forward = transform.forward; var direction = Vector3.Cross(normal, right); if (motorTorque < 0) { direction *= -1; } var lateralVelocity = Vector3.Project(velocity, right); var forwardVelocity = Vector3.Project(velocity, forward); var slip = (forwardVelocity + lateralVelocity) / 2; var lateralFriction = Vector3.Project(right, slip).magnitude *lateralVelocity.magnitude *lateralFrictionMultiplier / Time.fixedDeltaTime; _rb.AddForceAtPosition(-Vector3.Project(slip, lateralVelocity).normalized *lateralFriction, point + forceOffset); var motorForce = Mathf.Abs(motorTorque / _wheel.GetRadius()); var maxForwardFriction = motorForce * forwardFrictionCoeff; var appliedForwardFriction = Mathf.Clamp(motorForce, 0, maxForwardFriction); var forwardForce = direction.normalized * appliedForwardFriction * engineShaftToWheelRatio; _rb.AddForceAtPosition(forwardForce, point + forceOffset); }
private void FixedUpdate() { _foundHit = false; if (_wheel == null) { return; } var radius = _wheel.GetRadius(); var width = _wheel.GetWidth(); var minDist = radius; for (var i = 0; i < _numberRaysRound; i++) { var angle = 180 - _angleLimit / 2 + i * _angleLimit / _numberRaysRound; var direction = Quaternion.AngleAxis(angle, transform.right) * transform.up; for (var j = 0; j < _numberRaysWidth; j++) { var origin = transform.position; if (_numberRaysWidth > 1) { origin -= transform.right * width / 2; origin += transform.right * width * j / _numberRaysWidth; } var rayHit = Physics.Raycast(origin, direction, out _hit, minDist, _raycastLayers); Debug.DrawRay(origin, direction.normalized * minDist, rayHit ? Color.cyan : Color.gray); if (!rayHit) { continue; } minDist = _hit.distance; _foundHit = true; _hitPoint = _hit.point; _hitNormal = direction.normalized * -1; _hitCollider = _hit.collider; _hitRigidbody = _hit.rigidbody; _hitTransform = _hit.transform; } } }
private void FixedUpdate() { _foundHit = false; if (_wheel == null) { return; } var down = transform.up * -1; Debug.DrawRay(transform.position, down, Color.magenta); var minDist = _suspensionTravel; var radius = _wheel.GetRadius(); var width = _wheel.GetWidth(); for (var i = 0; i < _numberRaysLength; i++) { var x = radius * 2 * i / _numberRaysLength - radius; var y = Mathf.Sqrt(radius * radius - x * x); var localDirection = new Vector3(0, -y, x); var normalDirection = transform.TransformDirection(localDirection); //var normalDirection = Vector3.Cross(direction, transform.right).normalized; for (var j = 0; j < _numberRaysWidth; j++) { var origin = transform.position + transform.up * radius / 2; if (_numberRaysWidth > 1) { origin -= transform.right * width / 2; origin += transform.right * width * j / _numberRaysWidth; } if (_numberRaysLength > 1) { origin += transform.forward * x; origin += transform.up * _suspensionTravel / 2; origin -= transform.up * y; } var rayHit = Physics.Raycast(origin, down, out _hit, minDist, _raycastLayers); Debug.DrawRay(origin, down * minDist, rayHit ? Color.cyan : Color.gray); if (!rayHit) { continue; } _foundHit = true; _hitPoint = _hit.point; _hitNormal = normalDirection; // TODO: Is this correct? _hitCollider = _hit.collider; _hitRigidbody = _hit.rigidbody; _hitTransform = _hit.transform; minDist = _hit.distance; } } _suspensionDistance = _foundHit ? _suspensionTravel - minDist : 0; }
private void FixedUpdate() { if (_wheel == null) { _rayHit = false; return; } _rayHit = Physics.Raycast(transform.position, transform.up * -1, out _hit, _wheel.GetRadius(), _raycastLayers); }