void FixedUpdate() { _localTargetUp = Vector3.up; int accelerateOrDecelerate = -1; float forceScale = 0; if (_controller.isEnergyEnough(0.01f) && _controller.hasDriver) { switch (_forceDirection) { case Direction.Up: { // 目标上升速度 float targetYSpeed = 0; if (_controller.inputVertical > 0.01f) { targetYSpeed = _controller.inputVertical * PEVCConfig.instance.helicopterMaxUpSpeed; } else if (_controller.inputVertical < -0.01f) { targetYSpeed = _controller.inputVertical * PEVCConfig.instance.helicopterMaxDownSpeed; } // 判断应该加速还是减速 float currentYSpeed = _controller.rigidbody.velocity.y; if (currentYSpeed < targetYSpeed - 0.1f) { accelerateOrDecelerate = 1; } else if (currentYSpeed > targetYSpeed + 0.1f) { accelerateOrDecelerate = -1; } else { accelerateOrDecelerate = 0; } // 计算偏转方向 Vector3 direction = _controller.inputX * _localAngularDirection + _controller.inputY * _localForwardDirection; if (direction != Vector3.zero) { _localTargetUp = Vector3.RotateTowards(Vector3.up, direction, _maxDeflectionAngle * Mathf.Deg2Rad, 0); } forceScale = 1f; break; } case Direction.Left: case Direction.Right: { if (Mathf.Abs(_controller.inputX) > 0.01f) { if (_controller.inputX > 0 ? _rotateRight : _rotateLeft) { _localTargetUp = Vector3.RotateTowards(Vector3.up, _controller.inputX * _localAngularDirection, _maxDeflectionAngle * Mathf.Deg2Rad, 0); accelerateOrDecelerate = 1; forceScale = 1f; } } else if (Mathf.Abs(_controller.rigidbody.angularVelocity.y) > 0.26f) { // 在没有旋转输入的情况下, 反向组件提供阻力保持稳定 if (_controller.rigidbody.angularVelocity.y > 0) { if (_rotateLeft) { accelerateOrDecelerate = 1; forceScale = 1f; } } else { if (_rotateRight) { accelerateOrDecelerate = 1; forceScale = 1f; } } } break; } case Direction.Forward: case Direction.Back: { if (Mathf.Abs(_controller.inputX) > 0.01f) { if (_controller.inputX > 0 ? _rotateRight : _rotateLeft) { // 首选作为旋转动力, 其次作为前进/后退动力 _localTargetUp = Vector3.RotateTowards(Vector3.up, _controller.inputX * _localAngularDirection, _maxDeflectionAngle * Mathf.Deg2Rad, 0); accelerateOrDecelerate = 1; forceScale = 1f; break; } if (_controller.inputX > 0 ? _rotateLeft : _rotateRight) { // 在不阻止旋转的前提下才作为前进/后退动力 break; } } else if (Mathf.Abs(_controller.rigidbody.angularVelocity.y) > 0.26f) { // 在没有旋转输入的情况下, 反向组件提供阻力保持稳定, 正向组件停止工作 if (_controller.rigidbody.angularVelocity.y > 0) { if (_rotateLeft) { accelerateOrDecelerate = 1; forceScale = 1f; break; } if (_rotateRight) { break; } } else { if (_rotateRight) { accelerateOrDecelerate = 1; forceScale = 1f; break; } if (_rotateLeft) { break; } } } if (_forceDirection == Direction.Forward) { accelerateOrDecelerate = _controller.inputY > 0.01f ? 1 : -1; if (accelerateOrDecelerate == 1) { forceScale = _controller.inputY; } } else { accelerateOrDecelerate = _controller.inputY < -0.01f ? 1 : -1; if (accelerateOrDecelerate == 1) { forceScale = -_controller.inputY; } } break; } } } // 更新偏转角 Quaternion targetRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(Vector3.forward, _localTargetUp), _localTargetUp); _deflectionPivot.localRotation = Quaternion.RotateTowards( _deflectionPivot.localRotation, targetRotation, PEVCConfig.instance.rotorDeflectSpeed * Time.deltaTime); // 更新转速 if (accelerateOrDecelerate == 1) { _currentRotateSpeed = Mathf.Min(maxRotateSpeed, _currentRotateSpeed + _accelerate * Time.deltaTime); } else if (accelerateOrDecelerate == -1) { _currentRotateSpeed = Mathf.Max(0, _currentRotateSpeed - _decelerate * Time.deltaTime); } // 更新旋转角 _currentYAngle = (_currentYAngle + _currentRotateSpeed * Time.deltaTime) % 360; _rotatePivot.localEulerAngles = new Vector3(0, _currentYAngle, 0); // 应用力 if (forceScale > 0) { float force = _currentRotateSpeed / PEVCConfig.instance.rotorMaxRotateSpeed * _maxForce * forceScale; if (_forceDirection == Direction.Up) { // 限制高度 force *= _controller.liftForceFactor; // 向上螺旋桨可以提供旋转扭矩 _controller.rigidbody.AddTorque(_controller.inputX * force * PEVCConfig.instance.rotorSteerHelp * transform.up); // 应用力 _controller.rigidbody.AddForceAtPosition(transform.up * force * _controller.speedScale, _forcePivot.position); _controller.rigidbody.AddForceAtPosition( Vector3.ProjectOnPlane(_rotatePivot.up * force * _controller.speedScale, transform.up), (_forcePivot.position + _controller.rigidbody.worldCenterOfMass) * 0.5f); } else { // 应用力 _controller.rigidbody.AddForceAtPosition(_rotatePivot.up * force * _controller.speedScale, _forcePivot.position); } // 消耗能量 if (_controller.isPlayerHost) { _controller.ExpendEnergy(force * Time.deltaTime * PEVCConfig.instance.rotorEnergySpeed); } } UpdateSound(); }
void FixedUpdate() { int increaseOrDecrease = -1; float forceScale = 0f; if (_controller.isEnergyEnough(0.01f) && _controller.hasDriver) { switch (_forceDirection) { case Direction.Up: { // 目标上升速度 float targetYSpeed = 0; if (_controller.inputVertical > 0.01f) { targetYSpeed = _controller.inputVertical * PEVCConfig.instance.helicopterMaxUpSpeed; } else if (_controller.inputVertical < -0.01f) { targetYSpeed = _controller.inputVertical * PEVCConfig.instance.helicopterMaxDownSpeed; } // 判断应该加速还是减速 float currentYSpeed = _controller.rigidbody.velocity.y; if (currentYSpeed < targetYSpeed - 0.1f) { increaseOrDecrease = 1; } else if (currentYSpeed > targetYSpeed + 0.1f) { increaseOrDecrease = -1; } else { increaseOrDecrease = 0; } forceScale = 1f; break; } case Direction.Left: case Direction.Right: { if (Mathf.Abs(_controller.inputX) > 0.01f) { if (_controller.inputX > 0 && _rotateRight) { float rotateSpeedRatio = _controller.rigidbody.angularVelocity.y / 1.6f; increaseOrDecrease = rotateSpeedRatio >= 1f ? 0 : 1; forceScale = Mathf.Clamp01(1f - rotateSpeedRatio); } else if (_controller.inputX < 0 && _rotateLeft) { float rotateSpeedRatio = -_controller.rigidbody.angularVelocity.y / 1.6f; increaseOrDecrease = rotateSpeedRatio >= 1f ? 0 : 1; forceScale = Mathf.Clamp01(1f - rotateSpeedRatio); } } else if (Mathf.Abs(_controller.rigidbody.angularVelocity.y) > 0.26f) { if (_controller.rigidbody.angularVelocity.y > 0) { if (_rotateLeft) { increaseOrDecrease = 1; forceScale = 1f; } } else { if (_rotateRight) { increaseOrDecrease = 1; forceScale = 1f; } } } break; } case Direction.Forward: case Direction.Back: { if (Mathf.Abs(_controller.inputX) > 0.01f) { if (_controller.inputX > 0 ? _rotateRight : _rotateLeft) { // 首选作为旋转动力, 其次作为前进/后退动力 if (_controller.inputX > 0 && _rotateRight) { float rotateSpeedRatio = _controller.rigidbody.angularVelocity.y / 1.5f; increaseOrDecrease = rotateSpeedRatio >= 1f ? 0 : 1; forceScale = Mathf.Clamp01(1f - rotateSpeedRatio); } else if (_controller.inputX < 0 && _rotateLeft) { float rotateSpeedRatio = -_controller.rigidbody.angularVelocity.y / 1.5f; increaseOrDecrease = rotateSpeedRatio >= 1f ? 0 : 1; forceScale = Mathf.Clamp01(1f - rotateSpeedRatio); } break; } if (_controller.inputX > 0 ? _rotateLeft : _rotateRight) { // 在不阻止旋转的前提下才作为前进/后退动力 break; } } else if (Mathf.Abs(_controller.rigidbody.angularVelocity.y) > 0.26f) { // 在没有旋转输入的情况下, 反向组件提供阻力保持稳定, 正向组件停止工作 if (_controller.rigidbody.angularVelocity.y > 0) { if (_rotateLeft) { increaseOrDecrease = 1; forceScale = 1f; break; } if (_rotateRight) { break; } } else { if (_rotateRight) { increaseOrDecrease = 1; forceScale = 1f; break; } if (_rotateLeft) { break; } } } if (_forceDirection == Direction.Forward) { increaseOrDecrease = _controller.inputY > 0.01f ? 1 : -1; if (increaseOrDecrease == 1) { forceScale = _controller.inputY; } } else { increaseOrDecrease = _controller.inputY < -0.01f ? 1 : -1; if (increaseOrDecrease == 1) { forceScale = -_controller.inputY; } } break; } } } // 更新力比例 if (increaseOrDecrease == 1) { _currentForceRatio = Mathf.Min(maxForceRatio, _currentForceRatio + _increaseSpeed * Time.deltaTime); } else if (increaseOrDecrease == -1) { _currentForceRatio = Mathf.Max(0, _currentForceRatio - _decreaseSpeed * Time.deltaTime); } if (forceScale > 0) { float force = _currentForceRatio * _maxForce * forceScale; if (_forceDirection == Direction.Up) { // 限制高度 force *= _controller.liftForceFactor; // 向上推进器可以提供旋转扭矩 _controller.rigidbody.AddTorque(_controller.inputX * force * PEVCConfig.instance.thrusterSteerHelp * transform.up); } // 应用力 _controller.rigidbody.AddForceAtPosition(force * transform.up * _controller.speedScale, _pivot.position); // 消耗能量 if (_controller.isPlayerHost) { _controller.ExpendEnergy(force * Time.deltaTime * PEVCConfig.instance.thrusterEnergySpeed); } } // 更新效果 if (_effect.activeSelf) { if (increaseOrDecrease == -1 && _currentForceRatio < 0.05f) { _effect.SetActive(false); } } else { if (increaseOrDecrease == 1 && _currentForceRatio > 0.05f) { _effect.SetActive(true); } } _light.intensity = _currentForceRatio * 2f; }