예제 #1
0
        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();
        }
예제 #2
0
        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;
        }