Fasendas
Вы хотите отреагировать на этот пост ? Создайте аккаунт всего в несколько кликов или войдите на форум.
Апрель 2024
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
2930     

Календарь Календарь

Последние темы
» Код вертолета
Код вертолета EmptyПт Май 08, 2020 6:18 pm автор Gedifilyte

» Создание точки появления противников (Устаревшее)
Код вертолета EmptyСб Дек 14, 2019 2:34 am автор Gedifilyte

» Создание инвентаря (устаревшее)
Код вертолета EmptyПт Апр 13, 2018 7:43 pm автор Eris

» Программное создание Mesh
Код вертолета EmptyПн Фев 05, 2018 12:05 am автор Eris

» Помогите !!! (вопросы, советы, обсуждения)
Код вертолета EmptyВт Июн 06, 2017 11:39 am автор Zhuravlev Yuri

» Редакторы карт и ресурсов
Код вертолета EmptyСр Май 24, 2017 10:23 pm автор Чумной Доктор

» Создание "Игрового типа" (GameType)
Код вертолета EmptyСр Апр 05, 2017 2:19 am автор Filat

» Экспорт из 3ds Max
Код вертолета EmptyСб Мар 11, 2017 12:22 pm автор Uggo

» Создание "Выбор персонажа"
Код вертолета EmptyСб Фев 25, 2017 11:32 am автор Filat

Поиск
 
 

Результаты :
 

 


Rechercher Расширенный поиск

Ключевые слова


Код вертолета

Перейти вниз

Код вертолета Empty Код вертолета

Сообщение автор Gedifilyte Пт Май 08, 2020 6:18 pm

Хоть этот код не совершенен, вертолет неплохо летает, наклоняется и даже стреляет.
Важные ньюансы:
Для вертолета нужно создать физическую модель в которой будут четыре тела с названиями: helicopter (основное тело в которое пойдут меши корпуса вертолета), stabilizator (невидимое тело, которое должно располагаться над вертолетом, под ним будет висеть вертолет на специальном сочленении, у самого тела следует выключить параметр "Контактировать"), mainPropeller (тело с мешем основного винта), backPropeller (тело с мешем заднего винта). Также нужно три сочленения: два HingeJoint с именами suspensionJoint, соединяющий тело helicopter с телом mainPropeller и rotationJoint, соединяющий тело backPropeller с телом helicopter. Третье сочленение - UniversalJoint с именем stabilizeJoint соединяет тело stabilizator с телом helicopter. У этого сочленения должны быть включены ограничители на обеих осях. Направление одной оси - X, другой - Y. А также значения ограничителей должны стоять на 0. Еще нужны два мотора GearedMotor. Один с именем suspensionMotor должен крепиться на сочленении suspensionJoint, второй мотор с именем rotationMotor должен крепиться на сочленении rotationJoint.
В общем, образец готового вертолета я также прикреплю, разберетесь. Wink
[Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку]

Управление:
W -вперед
S - назад
A - поворот влево
D - поворот вправо
Q - движение левым боком
E - движение правым боком
Shift - вниз
Пробел - вверх

Это код класса вертолет
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing.Design;
using Engine;
using Engine.EntitySystem;
using Engine.MapSystem;
using Engine.MathEx;
using Engine.PhysicsSystem;
using Engine.Renderer;
using Engine.SoundSystem;
using Engine.Utils;
using ProjectCommon;
using System.IO;
using Engine.FileSystem;

namespace ProjectEntities
{
    public class HelicopterType : UnitType
    {
        [FieldSerialize]
        private float maxSpeedUp = 40f;

        [FieldSerialize]
        private float speedRotations = 1f;

        [FieldSerialize]
        private float maxSpeedMove = 80f;

        [FieldSerialize]
        private float maxForce = 85000f;

        [FieldSerialize]
        private float force = 50000f;

        [FieldSerialize]
        Range optimalAttackDistanceRange;

        [FieldSerialize]
        Degree towerTurnSpeed = 90;

        [FieldSerialize]
        string soundOn;

        [FieldSerialize]
        string soundOff;

        [FieldSerialize]
        string soundGearUp;

        [FieldSerialize]
        string soundGearDown;

        [FieldSerialize]
        Range gunRotationAngleRange = new Range(-80, 20);

        [FieldSerialize]
        List<Gear> gears = new List<Gear>();

        ///////////////////////////////////////////

        public class Gear
        {
            [FieldSerialize]
            int number;

            [FieldSerialize]
            Range speedRange;

            [FieldSerialize]
            string soundMotor;

            [FieldSerialize]
            [DefaultValue(typeof(Range), "1 1.2")]
            Range soundMotorPitchRange = new Range(1, 1.2f);

            //

            [DefaultValue(0)]
            public int Number
            {
                get { return number; }
                set { number = value; }
            }

            [DefaultValue(typeof(Range), "0 0")]
            public Range SpeedRange
            {
                get { return speedRange; }
                set { speedRange = value; }
            }

            [Editor(typeof(EditorSoundUITypeEditor), typeof(UITypeEditor))]
            public string SoundMotor
            {
                get { return soundMotor; }
                set { soundMotor = value; }
            }

            [DefaultValue(typeof(Range), "1 1.2")]
            public Range SoundMotorPitchRange
            {
                get { return soundMotorPitchRange; }
                set { soundMotorPitchRange = value; }
            }

            public override string ToString()
            {
                return string.Format("Gear {0}", number);
            }
        }

        ///////////////////////////////////////////

        public float MaxSpeedUp
        {
            get { return maxSpeedUp; }
            set { maxSpeedUp = value; }
        }

        public float SpeedRotations
        {
            get { return speedRotations; }
            set { speedRotations = value; }
        }

        public float MaxSpeedMove
        {
            get { return maxSpeedMove; }
            set { maxSpeedMove = value; }
        }

        public float MaxForce
        {
            get { return maxForce; }
            set { maxForce = value; }
        }

        public float Force
        {
            get { return force; }
            set { force = value; }
        }

        [Description("In degrees.")]
        [DefaultValue(typeof(Range), "-80 20")]
        public Range GunRotationAngleRange
        {
            get { return gunRotationAngleRange; }
            set { gunRotationAngleRange = value; }
        }

        [DefaultValue(typeof(Range), "0 0")]
        public Range OptimalAttackDistanceRange
        {
            get { return optimalAttackDistanceRange; }
            set { optimalAttackDistanceRange = value; }
        }

        [Description("Degrees per second.")]
        [DefaultValue(typeof(Degree), "90")]
        public Degree TowerTurnSpeed
        {
            get { return towerTurnSpeed; }
            set { towerTurnSpeed = value; }
        }

        [Editor(typeof(EditorSoundUITypeEditor), typeof(UITypeEditor))]
        public string SoundOn
        {
            get { return soundOn; }
            set { soundOn = value; }
        }

        [Editor(typeof(EditorSoundUITypeEditor), typeof(UITypeEditor))]
        public string SoundOff
        {
            get { return soundOff; }
            set { soundOff = value; }
        }

        public List<Gear> Gears
        {
            get { return gears; }
        }

        [Editor(typeof(EditorSoundUITypeEditor), typeof(UITypeEditor))]
        public string SoundGearUp
        {
            get { return soundGearUp; }
            set { soundGearUp = value; }
        }

        [Editor(typeof(EditorSoundUITypeEditor), typeof(UITypeEditor))]
        public string SoundGearDown
        {
            get { return soundGearDown; }
            set { soundGearDown = value; }
        }
    }

    public class Helicopter : Unit
    {
        private HelicopterType _type = null;
        public new HelicopterType Type
        {
            get { return _type; }
        }

        ///////////////////////////////////////////
        class Track
        {
            public float speed;
            public float server_sentSpeed;
        }
        ///////////////////////////////////////////

        Body helicopterBody; //Это тело самого вертолета
        Body stabilizatorBody; //Это тело стабилизатора. Небольшой куб, который надо расположить в редакторе физики над        
        //вертолетом, затем соединить его с телом вертолета при помощи сочленения UniversalJoint. Стабилизатор будет выравнивать
        //тело вертолета, когда оно будет наклоняться. Тело стабилизатора должно быть над центром вертолета, чтобы тело вертолета
        //висело ровно и не наклонялось само.
        float Mass, suspensionForce;
        GearedMotor suspensionMotor, rotationMotor;
        HingeJoint suspensionJoint, rotationJoint;
        UniversalJoint stabilizeJoint;
        bool isWorking = false;
        bool firstTick = true;

        float RL = 0;
        float FB1 = 0;
        float FB2 = 0;
        float RwLw1 = 0;
        float RwLw2 = 0;

        Body towerBody;
        Vec3 towerBodyLocalPosition;

        MapObjectAttachedMapObject mainGunAttachedObject;
        Gun mainGun;
        Vec3 mainGunOffsetPosition;

        SphereDir towerLocalDirection;
        SphereDir needTowerLocalDirection;
        SphereDir server_sentTowerLocalDirection;

        bool motorOn;
        string currentMotorSoundName;
        VirtualChannel motorSoundChannel;

        HelicopterType.Gear currentGear;
        Track leftTrack = new Track();
        Track rightTrack = new Track();

        protected override void OnPostCreate(bool loaded)
        {
            base.OnPostCreate(loaded);
            if (EngineApp.Instance.ApplicationType == EngineApp.ApplicationTypes.Simulation)
                GetPhysics();
            {

                if (EngineApp.Instance.ApplicationType != EngineApp.ApplicationTypes.ResourceEditor)
                {
                    if (PhysicsModel == null)
                    {
                        Log.Error("Не добавлена физика вертолету. Класс Helicopter, экземпляр: " + Name);
                        return;
                    }

                    helicopterBody = PhysicsModel.GetBody("helicopter");
                    if (helicopterBody == null)
                    {
                        Log.Error("Тело 'helicopter' не найдено. Либо оно отсутствует, либо задано неправильное имя. Класс Helicopter, экземпляр: " + Name);
                        return;
                    }
                    towerBody = PhysicsModel.GetBody("tower");
                    stabilizatorBody = PhysicsModel.GetBody("stabilizator");
                    if (stabilizatorBody == null)
                    {
                        Log.Error("Тело 'stabilizator' не найдено. Либо оно отсутствует, либо задано неправильное имя. Класс Helicopter, экземпляр: " + Name);
                        return;
                    }
                    stabilizeJoint = PhysicsModel.GetJoint("stabilizeJoint") as UniversalJoint;
                    if (stabilizeJoint == null)
                    {
                        Log.Error("Сочленение 'stabilizeJoint' не найдено. Либо оно отсутствует, либо задано неправильное имя, либо сочленение не является UniversalJoint. Класс Helicopter, экземпляр: " + Name);
                        return;
                    }
                }
                //mainGun
                foreach (MapObjectAttachedObject attachedObject in AttachedObjects)
                {
                    MapObjectAttachedMapObject attachedMapObject = attachedObject as MapObjectAttachedMapObject;
                    if (attachedMapObject == null)
                        continue;

                    mainGun = attachedMapObject.MapObject as Gun;
                    if (mainGun != null)
                    {
                        mainGunAttachedObject = attachedMapObject;
                        mainGunOffsetPosition = attachedMapObject.PositionOffset;
                        break;
                    }
                }
                //towerBodyLocalPosition
                if (towerBody != null)
                    towerBodyLocalPosition = PhysicsModel.ModelDeclaration.GetBody(towerBody.Name).Position;

                //initialize currentGear
                currentGear = Type.Gears.Find(delegate(HelicopterType.Gear gear)
                {
                    return gear.Number == 0;
                });

                //disable contacts between chassisBody and towerBody
                if (helicopterBody != null && towerBody != null)
                {
                    foreach (Shape shape1 in helicopterBody.Shapes)
                    {
                        foreach (Shape shape2 in towerBody.Shapes)
                        {
                            PhysicsWorld.Instance.SetShapePairFlags(shape1, shape2,
                                ShapePairFlags.DisableContacts);
                        }
                    }
                }
            }
        }

        protected override void OnDestroy()
        {
            if (motorSoundChannel != null)
            {
                motorSoundChannel.Stop();
                motorSoundChannel = null;
            }
            base.OnDestroy();
        }

        protected override void OnRender(Camera camera)
        {
            //not very true update in the OnRender.
            //it is here because need update after all Ticks and before update attached objects.
            UpdateTowerTransform();
            base.OnRender(camera);
        }

        void TickTowerTurn()
        {
            //update direction
            if (towerLocalDirection != needTowerLocalDirection)
            {
                Radian turnSpeed = Type.TowerTurnSpeed;

                SphereDir needDirection = needTowerLocalDirection;
                SphereDir direction = towerLocalDirection;

                //update horizontal direction
                float diffHorizontalAngle = needDirection.Horizontal - direction.Horizontal;
                while (diffHorizontalAngle < -MathFunctions.PI)
                    diffHorizontalAngle += MathFunctions.PI * 2;
                while (diffHorizontalAngle > MathFunctions.PI)
                    diffHorizontalAngle -= MathFunctions.PI * 2;

                if (diffHorizontalAngle > 0)
                {
                    if (direction.Horizontal > needDirection.Horizontal)
                        direction.Horizontal -= MathFunctions.PI * 2;
                    direction.Horizontal += turnSpeed * TickDelta;
                    if (direction.Horizontal > needDirection.Horizontal)
                        direction.Horizontal = needDirection.Horizontal;
                }
                else
                {
                    if (direction.Horizontal < needDirection.Horizontal)
                        direction.Horizontal += MathFunctions.PI * 2;
                    direction.Horizontal -= turnSpeed * TickDelta;
                    if (direction.Horizontal < needDirection.Horizontal)
                        direction.Horizontal = needDirection.Horizontal;
                }

                //update vertical direction
                if (direction.Vertical < needDirection.Vertical)
                {
                    direction.Vertical += turnSpeed * TickDelta;
                    if (direction.Vertical > needDirection.Vertical)
                        direction.Vertical = needDirection.Vertical;
                }
                else
                {
                    direction.Vertical -= turnSpeed * TickDelta;
                    if (direction.Vertical < needDirection.Vertical)
                        direction.Vertical = needDirection.Vertical;
                }

                if (direction.Equals(needTowerLocalDirection, .001f))
                    towerLocalDirection = direction;

                towerLocalDirection = direction;
            }
        }

        private void GetPhysics()
        {
            //Будьте внимательны при вводе имен тел, сочленений и моторов в редакторе ресурсов при создании физики.
            //Обязательно соблюдайте регистр. По умолчанию имена принято писать с маленькой буквы
            helicopterBody = PhysicsModel.GetBody("helicopter");
            if (helicopterBody == null) Log.Error("{0} - Тело 'helicopter' не найдено. Либо оно отсутствует, либо задано неправильное имя. Класс Helicopter, экземпляр: " + Name, this);
            stabilizatorBody = PhysicsModel.GetBody("stabilizator");
            if (stabilizatorBody == null) Log.Error("{0} - Тело 'stabilizator' не найдено. Либо оно отсутствует, либо задано неправильное имя. Класс Helicopter, экземпляр: " + Name, this);

            rotationJoint = PhysicsModel.GetJoint("rotationJoint") as HingeJoint;
            rotationMotor = PhysicsModel.GetMotor("rotationMotor") as GearedMotor;
            suspensionJoint = PhysicsModel.GetJoint("suspensionJoint") as HingeJoint;
            suspensionMotor = PhysicsModel.GetMotor("suspensionMotor") as GearedMotor;

            if (suspensionMotor == null) Log.Error("{0} - Мотор 'stabilizationMotor' не найден. Либо он отсутствует, либо задано неправильное имя, либо мотор не является GearedMotor. Класс Helicopter, экземпляр: " + Name, this);
            if (suspensionJoint == null) Log.Error("{0} - Сочлинение 'suspensionJoint' не найдено. Либо оно отсутствует, либо задано неправильное имя, либо сочленение не является HingeJoint. Класс Helicopter, экземпляр: " + Name, this);
            if (rotationJoint == null) Log.Error("{0} - Сочлинение 'rotationJoint' не найдено. Либо оно отсутствует, либо задано неправильное имя, либо сочленение не является HingeJoint. Класс Helicopter, экземпляр: " + Name, this);
            if (rotationMotor == null) Log.Error("{0} - Мотор 'rotationMotor' не найден. Либо он отсутствует, либо задано неправильное имя, либо мотор не является GearedMotor. Класс Helicopter, экземпляр: " + Name, this);

            foreach (Body b in PhysicsModel.Bodies) Mass += b.Mass;
            suspensionForce = (-PhysicsWorld.Instance.MainScene.Gravity.Z * Mass) + Type.Force;
        }

        private void Starting()
        {
            if (suspensionJoint.Broken) return;
            if (Intellect == null)
            {
                isWorking = false;
                suspensionMotor.Throttle = 0;
                rotationMotor.Throttle = 0;
            }
            else if (!isWorking && suspensionMotor.Throttle < 1)
            {
                suspensionMotor.Throttle += (TickDelta / 7);
                rotationMotor.Throttle += (TickDelta / 7);
            }
            else
                isWorking = true;
        }

        private void MoveUpDown()
        {
            Vec3 ForceVec = new Vec3(0, 0, suspensionForce);

            if (Intellect.IsControlKeyPressed(GameControlKeys.Jump) && GetSpeed().Z < Type.MaxSpeedUp)
                stabilizatorBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta, ForceVec, Vec3.Zero);
            else if (Intellect.IsControlKeyPressed(GameControlKeys.Run) && GetSpeed().Z > -Type.MaxSpeedUp)
                stabilizatorBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta, -ForceVec, Vec3.Zero);
        }

        private void MoveForwardBackward()
        {
            if (Intellect.IsControlKeyPressed(GameControlKeys.Forward))
            {
                if (GetSpeed().X < Type.MaxSpeedMove)
                    stabilizatorBody.AddForce(ForceType.LocalAtLocalPos, TickDelta, new Vec3(Type.Force, 0, 0), Vec3.Zero);
            }
            else if (Intellect.IsControlKeyPressed(GameControlKeys.Backward))
            {
                if (GetSpeed().X < Type.MaxSpeedMove)
                    stabilizatorBody.AddForce(ForceType.LocalAtLocalPos, TickDelta, new Vec3(-Type.Force, 0, 0), Vec3.Zero);
            }
        }

        private void MoveLeftRight()
        {
            if (Intellect.IsControlKeyPressed(GameControlKeys.Rightward))
            {
                if (GetSpeed().X < Type.MaxSpeedMove)
                    stabilizatorBody.AddForce(ForceType.LocalAtLocalPos, TickDelta, new Vec3(0, -Type.Force, 0), Vec3.Zero);
            }
            else if (Intellect.IsControlKeyPressed(GameControlKeys.Leftward))
                if (GetSpeed().X < Type.MaxSpeedMove)
                    stabilizatorBody.AddForce(ForceType.LocalAtLocalPos, TickDelta, new Vec3(0, Type.Force, 0), Vec3.Zero);
        }

        private void Rotate()
        {
            //Наклоны тела работают не совсем и не всегда корректно, нуждаются в доработке
            //Тело наклоняется посредством изменения значения ограничителя в UniversalJoint, которое по умолчанию 0
            //и не дает вертолету наклоняться
            if (rotationJoint.Broken) return;

            if (RL < 20)
                RL += Intellect.GetControlKeyStrength(GameControlKeys.Left); //сила, с которой тело вертолета разворачивается
            if (RL > -20)
                RL -= Intellect.GetControlKeyStrength(GameControlKeys.Right);

            if (FB1 < 30)
                FB1 += Intellect.GetControlKeyStrength(GameControlKeys.Backward) * 2;
            if (FB1 > 0 && FB1 < 30)
                stabilizeJoint.Axis2.LimitHigh = FB1; //Наклоняет тело назад до 30 градусов
            if (FB2 > -30)
                FB2 -= Intellect.GetControlKeyStrength(GameControlKeys.Forward) * 2;
            if (FB2 < 0 && FB2 > -30)
                stabilizeJoint.Axis2.LimitLow = FB2; //Наклоняет тело вперед до 30 градусов

            if (RwLw1 < 30)
                RwLw1 += Intellect.GetControlKeyStrength(GameControlKeys.Leftward) * 2;
            if (RwLw1 > 0 && RwLw1 < 30)
                stabilizeJoint.Axis1.LimitHigh = RwLw1; //Наклоняет тело влево до 30 градусов
            if (RwLw2 > -30)
                RwLw2 -= Intellect.GetControlKeyStrength(GameControlKeys.Rightward) * 2;
            if (RwLw2 < 0 && RwLw2 > -30)
                stabilizeJoint.Axis1.LimitLow = RwLw2; //Наклоняет тело вправо до 30 градусов

            stabilizatorBody.AngularVelocity = new Vec3(0, 0, RL * Type.SpeedRotations); //применение силы к телу для поворота
            //по оси Z. Обратите внимание, что поворачиваться по оси Z должно не тело вертолета, а тело стабилизатора, которое
            //плавно тянет за собой тело вертолета
        }

        private void Stabilization()
        {
            if (rotationJoint.Broken)
            {
                if (!suspensionJoint.Broken && suspensionMotor.Throttle != 0)
                    stabilizatorBody.AngularVelocity = new Vec3(0, 0, 3);
            }
            else stabilizatorBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta,
                                         -PhysicsWorld.Instance.MainScene.Gravity * Mass, Vec3.Zero);
            //Автоматическое выравнивание вертолета
            if (RL > 0) RL -= 0.1f;
            if (RL < 0) RL += 0.1f;
            if (FB1 > 0) FB1 -= 1f;
            if (FB2 < 0) FB2 += 1f;
            if (RwLw1 > 0) RwLw1 -= 1f;
            if (RwLw2 < 0) RwLw2 += 1f;
        }

        //not ideal true
        private Vec3 GetSpeed()
        {
            Vec3 v = Vec3.Zero;
            Vec3 linearVelocity = stabilizatorBody.LinearVelocity;
            Vec3 angularVelocity = stabilizatorBody.AngularVelocity;
            //optimization
            if (linearVelocity.Equals(Vec3.Zero, .2f) && angularVelocity.Equals(Vec3.Zero, .2f)) return v;
            Vec3 localLinearVelocity = linearVelocity * stabilizatorBody.Rotation.GetInverse();

            v.X = localLinearVelocity.X + Math.Abs(angularVelocity.X) * 2;
            v.Y = localLinearVelocity.Y + Math.Abs(angularVelocity.Y) * 2;
            v.Z = localLinearVelocity.Z + Math.Abs(angularVelocity.Z) * 2;

            return v;
        }

        protected override void OnTick()
        {
            base.OnTick();

            bool lastMotorOn = motorOn;
            motorOn = Intellect != null && Intellect.IsActive();

            if (motorOn != lastMotorOn)
            {
                if (motorOn)
                    SoundPlay3D(Type.SoundOn, .7f, true);
            }
            if (motorSoundChannel != null && !motorOn)
            {
                motorSoundChannel.Pause = true;
                if (motorOn != lastMotorOn)
                {
                    if (!motorOn)
                        SoundPlay3D(Type.SoundOff, .7f, true);
                }
            }
            else if (motorSoundChannel != null && Intellect != null && isWorking == true)
                motorSoundChannel.Pause = false;

            TickTowerTurn();
            firstTick = false;
            Starting();

            if (!isWorking)
                return;

            Stabilization();

            if (!suspensionJoint.Broken)
            {
                MoveUpDown();
                MoveForwardBackward();
                MoveLeftRight();
                Rotate();
            }
            else
                isWorking = false;

            TickMotorSound();
            TickCurrentGear();

            if (Intellect != null)
            {
                if (Intellect.IsControlKeyPressed(GameControlKeys.Fire1))
                    if (GunsTryFire(false))
                        if (Intellect.IsControlKeyPressed(GameControlKeys.Fire2))
                            GunsTryFire(true);
            }
            {
                //send tower local direction to clients
                if (EntitySystemWorld.Instance.IsServer())
                    Server_TickSendTowerLocalDirection();

                //!!!!!should use for disabled renderer
                if (EntitySystemWorld.Instance.IsDedicatedServer())
                    UpdateTowerTransform();
            }
        }

        void Print(string Text)
        {
            //Метод для проверки работы кода.
            //Чтобы его задействовать, впишите в нужный вам метод: Print("какой-то текст" + переменная, например Health);
            //В игре в вызванной командной строке при помощи тильды "~" будет отображаться ваш текст
            if (EngineConsole.Instance == null) return;
            EngineConsole.Instance.Print(Text);
        }

        void TickMotorSound()
        {
            string needSoundName = null;
            if (currentGear != null)
                needSoundName = currentGear.SoundMotor;

            if (needSoundName != currentMotorSoundName)
            {
                //change motor sound

                currentMotorSoundName = needSoundName;

                if (!string.IsNullOrEmpty(needSoundName))
                {
                    Sound sound = SoundWorld.Instance.SoundCreate(
                        RelativePathUtils.ConvertToFullPath(Path.GetDirectoryName(Type.FilePath), needSoundName),
                        SoundMode.Mode3D | SoundMode.Loop);

                    if (sound != null)
                    {
                        motorSoundChannel = SoundWorld.Instance.SoundPlay(
                            sound, EngineApp.Instance.DefaultSoundChannelGroup, .3f, true);
                        motorSoundChannel.Position = Position;
                        switch (Type.SoundRolloffMode)
                        {
                            case DynamicType.SoundRolloffModes.Logarithmic:
                                motorSoundChannel.SetLogarithmicRolloff(Type.SoundMinDistance, Type.SoundMaxDistance,
                                    Type.SoundRolloffLogarithmicFactor);
                                break;
                            case DynamicType.SoundRolloffModes.Linear:
                                motorSoundChannel.SetLinearRolloff(Type.SoundMinDistance, Type.SoundMaxDistance);
                                break;
                        }
                        motorSoundChannel.Pause = false;
                    }
                }
            }

            //update motor channel position and pitch
            if (motorSoundChannel != null)
            {
                Range speedRangeAbs = currentGear.SpeedRange;
                if (speedRangeAbs.Minimum < 0 && speedRangeAbs.Maximum < 0)
                    speedRangeAbs = new Range(-speedRangeAbs.Maximum, -speedRangeAbs.Minimum);
                Range pitchRange = currentGear.SoundMotorPitchRange;

                float speedCoef = 0;
                MathFunctions.Clamp(ref speedCoef, 0, 1);

                //update channel
                motorSoundChannel.Pitch = pitchRange.Minimum + speedCoef * pitchRange.Size();
                motorSoundChannel.Position = Position;
            }
        }

        protected override void Client_OnTick()
        {
            base.Client_OnTick();

            TickCurrentGear();
            TickMotorSound();
            firstTick = false;
        }

        void TickCurrentGear()
        {
            //currently gears used only for sounds

            if (currentGear == null)
                return;

            if (motorOn)
            {
                float speed = Math.Max(leftTrack.speed, rightTrack.speed);

                HelicopterType.Gear newGear = null;

                if (speed < currentGear.SpeedRange.Minimum || speed > currentGear.SpeedRange.Maximum)
                {
                    //find new gear
                    newGear = Type.Gears.Find(delegate(HelicopterType.Gear gear)
                    {
                        return speed >= gear.SpeedRange.Minimum && speed <= gear.SpeedRange.Maximum;
                    });
                }

                if (newGear != null && currentGear != newGear)
                {
                    //change gear
                    HelicopterType.Gear oldGear = currentGear;
                    OnGearChange(oldGear, newGear);
                    currentGear = newGear;
                }
            }
            else
            {
                if (currentGear.Number != 0)
                {
                    currentGear = Type.Gears.Find(delegate(HelicopterType.Gear gear)
                    {
                        return gear.Number == 0;
                    });
                }
            }
        }

        void OnGearChange(HelicopterType.Gear oldGear, HelicopterType.Gear newGear)
        {
            if (!firstTick && Health != 0)
            {
                bool up = Math.Abs(newGear.Number) > Math.Abs(oldGear.Number);
                string soundName = up ? Type.SoundGearUp : Type.SoundGearDown;
                SoundPlay3D(soundName, .7f, true);
            }
        }

        [Browsable(false)]
        public Gun MainGun
        {
            get { return mainGun; }
        }

        void UpdateTowerTransform()
        {
            if (towerBody == null || helicopterBody == null || mainGunAttachedObject == null)
                return;

            Radian horizontalAngle = towerLocalDirection.Horizontal;
            Radian verticalAngle = towerLocalDirection.Vertical;

            Range gunRotationRange = Type.GunRotationAngleRange * MathFunctions.PI / 180.0f;
            if (verticalAngle < gunRotationRange.Minimum)
                verticalAngle = gunRotationRange.Minimum;
            if (verticalAngle > gunRotationRange.Maximum)
                verticalAngle = gunRotationRange.Maximum;

            //update tower body
            towerBody.Position = GetInterpolatedPosition() +
                GetInterpolatedRotation() * towerBodyLocalPosition;
            towerBody.Rotation = GetInterpolatedRotation() *
                new Angles(0, 0, -horizontalAngle.InDegrees()).ToQuat();
            towerBody.Sleeping = true;

            //update gun vertical rotation
            Quat verticalRotation = new Angles(0, verticalAngle.InDegrees(), 0).ToQuat();
            mainGunAttachedObject.RotationOffset = verticalRotation;
        }

        bool GunsTryFire(bool alternative)
        {
            bool fire = false;

            foreach (MapObjectAttachedObject attachedObject in AttachedObjects)
            {
                MapObjectAttachedMapObject attachedMapObject = attachedObject as MapObjectAttachedMapObject;
                if (attachedMapObject == null)
                    continue;

                Gun gun = attachedMapObject.MapObject as Gun;

                if (gun != null)
                {
                    if (gun.TryFire(alternative))
                        fire = true;
                }
            }

            return fire;
        }

        public void SetMomentaryTurnToPosition(Vec3 pos)
        {
            if (towerBody == null)
                return;

            Vec3 direction = pos - towerBody.Position;
            towerLocalDirection = SphereDir.FromVector(Rotation.GetInverse() * direction);
            needTowerLocalDirection = towerLocalDirection;
        }

        public void SetNeedTurnToPosition(Vec3 pos)
        {
            if (towerBody == null)
                return;

            if (Type.TowerTurnSpeed != 0)
            {
                Vec3 direction = pos - towerBody.Position;
                needTowerLocalDirection = SphereDir.FromVector(Rotation.GetInverse() * direction);
            }
            else
                SetMomentaryTurnToPosition(pos);
        }

        protected override void Server_OnClientConnectedAfterPostCreate(
            RemoteEntityWorld remoteEntityWorld)
        {
            base.Server_OnClientConnectedAfterPostCreate(remoteEntityWorld);

            RemoteEntityWorld[] worlds = new RemoteEntityWorld[] { remoteEntityWorld };
            Server_SendTowerLocalDirectionToClients(worlds);
        }

        void Server_TickSendTowerLocalDirection()
        {
            float epsilon = new Degree(.5f).InRadians();
            if (!towerLocalDirection.Equals(server_sentTowerLocalDirection, epsilon))
            {
                Server_SendTowerLocalDirectionToClients(EntitySystemWorld.Instance.RemoteEntityWorlds);
                server_sentTowerLocalDirection = towerLocalDirection;
            }
        }

        void Server_SendTowerLocalDirectionToClients(IList<RemoteEntityWorld> remoteEntityWorlds)
        {
            SendDataWriter writer = BeginNetworkMessage(remoteEntityWorlds, typeof(Helicopter),
                (ushort)NetworkMessages.TowerLocalDirectionToClient);
            writer.Write(towerLocalDirection);
            EndNetworkMessage();
        }

        [NetworkReceive(NetworkDirections.ToClient, (ushort)NetworkMessages.TowerLocalDirectionToClient)]
        void Client_ReceiveTowerLocalDirection(RemoteEntityWorld sender, ReceiveDataReader reader)
        {
            SphereDir value = reader.ReadSphereDir();
            if (!reader.Complete())
                return;
            towerLocalDirection = value;
        }

        ///////////////////////////////////////////

        enum NetworkMessages
        {
            TowerLocalDirectionToClient,
            TracksSpeedToClient,
        }

        ///////////////////////////////////////////

    }
}
Также помимо него нужно подправить и другие классы
Класс GameControlKeys. Добавить две новые клавиши. Движение в правый бок и в левый бок. Назначение клавиши Use поменять
Код:
[DefaultKeyboardMouseValue( EKeys.F )]
 Use,

        [DefaultKeyboardMouseValue(EKeys.E)]
        Rightward,

        [DefaultKeyboardMouseValue(EKeys.Q)]
        Leftward,

Класс PlayerIntellect. Найдите метод void ServerOrSingle_RestoreMainControlledUnit() и в нем Tank specific
Код:
if( ControlledObject != null )
{
       //Tank specific
       if( ControlledObject is Tank || ControlledObject is Car )

Добавьте в условие этого метода ControlledObject is Helicopter
Код:
if( ControlledObject != null )
{
 //Tank specific
 if( ControlledObject is Tank || ControlledObject is Car || ControlledObject is Helicopter )

В классе ActionGameWindow, найдите метод void UpdateHUD(). В нем под Tank specific добавьте строки с Helicopter
Код:
//Tank specific
Tank tank = playerUnit as Tank;
if( tank != null )
    weapon = tank.MainGun;

//Helicopter specific
Helicopter heli = playerUnit as Helicopter;
if (heli != null)
    weapon = heli.MainGun;
То же самое напишите в этом же классе, в методе void DrawTarget( GuiRenderer renderer )

А ниже в этом методе, под строкой Tank specific   DrawTankGunTarget(renderer) добавьте аналогичные строки про Helicopter
Код:
//Tank specific
DrawTankGunTarget( renderer );

//Helicopter specific
DrawHeliGunTarget(renderer);
Gedifilyte
Gedifilyte

Сообщения : 2
Рейтинг : 1724
Репутация : 0
Дата регистрации : 2019-08-12

Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения