Creating-your-first-script-csharp

From FiveM Wikipedia

Создание первого скрипта на C #

Начало работы со сценариями для FiveM может быть немного ошеломляющим, учитывая широкий спектр возможностей и слабо распространенную документацию. В этом кратком и простом руководстве мы постараемся показать вам, как начать работу с быстрым ресурсом на C#. Мы будем реализовывать спаунер автомобиля с помощью команды.

Необходимые условия

Перед созданием первого сценария на C# необходимо настроить и понять несколько вещей.

  • Создание проекта C# и настройка среды
  • Общие сведения о ресурсах и файлах манифестов

Написание кода

Теперь, когда вы настроили проект и среду C#, у вас будет два проекта; и.MyResourceNameClientMyResourceNameServer

Любой класс C#, обрабатывающий события, связанные со сценариями FiveM, должен наследоваться от класса. Давайте сделаем это, перейдя в ваш клиентский проект. В то же время мы также определим конструктор, который мы будем использовать в дальнейшем. Убедитесь, что у вас есть директива using для .BaseScriptClass1.csCitizenFX.Core

using CitizenFX.Core;

namespace MyResourceNameClient
{
    public class Class1 : BaseScript
    {
        public Class1()
        {

        }
    }
}

Легко, не так ли? Но как насчет добавления функциональности? Мы начнем с добавления команды, использующей различные концепции сценариев FiveM.

using System;
using System.Collections.Generic;
using CitizenFX.Core;
using static CitizenFX.Core.Native.API;

namespace MyResourceNameClient
{
    public class Class1 : BaseScript
    {
        public Class1()
        {
            EventHandlers["onClientResourceStart"] += new Action<string>(OnClientResourceStart);
        }

        private void OnClientResourceStart(string resourceName)
        {
            if (GetCurrentResourceName() != resourceName) return;

            RegisterCommand("car", new Action<int, List<object>, string>((source, args, raw) =>
            {
                // TODO: make a vehicle! fun!
                TriggerEvent("chat:addMessage", new
                {
                    color = new[] {255, 0, 0},
                    args = new[] {"[CarSpawner]", $"I wish I could spawn this {(args.Count > 0 ? $"{args[0]} or" : "")} adder but my owner was too lazy. :("}
                });
            }), false);
        }
    }
}

Вы можете быть перегружены в этот момент, но не волнуйтесь. Мы пройдемся по всему шаг за шагом.

EventHandlers["onClientResourceStart"] += new Action<string>(OnClientResourceStart);

В конструкторе мы добавили обработчик событий для события onClientResourceStart. Для этого требуется один аргумент; строка с именем запущенного ресурса. Он также имеет метод делегата, который мы определили под конструктором. После запуска ресурса FiveM инициирует это событие и вызывает метод.OnClientResourceStart

if (GetCurrentResourceName() != resourceName) return;

Это если оператор использует собственный оператор . Короче говоря, туземцы, которые не имеют ничего общего с коренными народами, на самом деле являются ярлыком R* для «игровых функций скрипта». Мы можем получить доступ к этим аборигенам через класс. Вы будете использовать других туземцев позже при создании транспортного средства. В этом фрагменте кода возвращается имя ресурса, выполняемого нашим сценарием. Мы сравниваем это с аргументом, чтобы убедиться, что мы вызываем остальную часть метода только один раз. Если мы не выполним эту проверку, остальная часть метода будет запускаться каждый раз, когда какой-либо ресурс запускается.GetCurrentResourceName()CitizenFX.Core.Native.APIGetCurrentResourceName()resourceName

RegisterCommand("car", new Action<int, List<object>, string>((source, args, raw) =>
{
    // TODO: make a vehicle! fun!
    TriggerEvent("chat:addMessage", new
    {
        color = new[] {255, 0, 0},
        args = new[] {"[CarSpawner]", $"I wish I could spawn this {(args.Count > 0 ? $"{args[0]} or" : "")} adder but my owner was too lazy. :("}
    });
}), false);

Для начала мы видим вызов функции. Мы не определили эту функцию. Что ж, мы (как и команда FiveM) это сделали, но не тогда, когда вели вас, читатель, через это удивительно написанное чудо гида. Это означает, что он должен прийти откуда-то еще!

И, угадайте, это на самом деле REGISTER_COMMAND! Щелкните эту ссылку, и вы перейдете к документации для этого нативного носителя. Выглядит это примерно так:

// 0x5fa79b0f
// RegisterCommand
void REGISTER_COMMAND(char* commandName, func handler, BOOL restricted);

Мы будем в основном заботиться об имени во второй строке (как используется в коде C# выше) и аргументах.RegisterCommand

Как видите, первым аргументом является имя команды. Второй аргумент — это функция (представленная делегатом Action в нашем примере), которая является обработчиком команды, а третий аргумент — логическая, указывающая, должна ли она быть ограниченной командой.

Сама функция получает аргумент, который является , который действительно имеет значение только в том случае, если вы работаете на сервере (это будет идентификатор клиента игрока, который ввел команду, действительно полезная вещь, которую нужно иметь), и список, который в основном является тем, что вы вводите после команды, например, чтобы в конечном итоге быть или быть .sourceargs/car zentornoargsnew List<object>{ "zentorno" }/car zentorno unusednew List<object>{ "zentorno", "unused" }

Но как насчет ? Это тоже определяется нами. Он используется для вызова события, которое является частью ресурса чата. В нашем письменном примере мы отправляем имя автора красным цветом и сообщение в качестве аргументов.TriggerEvent()chat:addMessage[CarSpawner]

На этом этапе вы можете построить свой клиентский проект, добавить/переместить его в свой ресурс и запустить его. При вводе в поле чата вы увидите нашу команду, возвращающую сообщение чата, которое мы определили. /car

Эй! Он жалуется в чате, что вам было лень это реализовать. Мы покажем им, что вы абсолютно не ленивы, и на самом деле реализуем это сейчас.

Реализация автомобильного спауна

Возможно, вы следовали руководству Lua по созданию своего первого скрипта и помните, что было много шаблонного кода, который мог показаться ошеломляющим. Не бойтесь, FiveM предоставляет простую в использовании оболочку C#, которая позволит нам уменьшить код.

RegisterCommand("car", new Action<int, List<object>, string>(async (source, args, raw) =>
{
    // account for the argument not being passed
    var model = "adder";
    if (args.Count > 0)
    {
        model = args[0].ToString();
    }

    // check if the model actually exists
    // assumes the directive `using static CitizenFX.Core.Native.API;`
    var hash = (uint) GetHashKey(model);
    if (!IsModelInCdimage(hash) || !IsModelAVehicle(hash))
    {
        TriggerEvent("chat:addMessage", new 
        {
            color = new[] { 255, 0, 0 },
            args = new[] { "[CarSpawner]", $"It might have been a good thing that you tried to spawn a {model}. Who even wants their spawning to actually ^*succeed?" }
        });
        return;
    }

    // create the vehicle
    var vehicle = await World.CreateVehicle(model, Game.PlayerPed.Position, Game.PlayerPed.Heading);
    
    // set the player ped into the vehicle and driver seat
    Game.PlayerPed.SetIntoVehicle(vehicle, VehicleSeat.Driver);

    // tell the player
    TriggerEvent("chat:addMessage", new 
    {
        color = new[] {255, 0, 0},
        args = new[] {"[CarSpawner]", $"Woohoo! Enjoy your new ^*{model}!"}
    });
}), false);

При этом используются некоторые собственные компоненты и методы оболочки C#. Мы свяжем некоторые из них и объясним сложные части.

Шаг 1: Проверка

Мы начали с проверки модели. Мы установили для него значение . Если есть какие-либо аргументы, мы устанавливаем для модели первый аргумент и приводим его в строку.adder

Затем мы проверяем, находится ли автомобиль в образе компакт-диска, используя IS_MODEL_IN_CDIMAGE. Это в основном означает «зарегистрировано ли это в игре». Мы также проверяем, является ли это транспортным средством, использующим IS_MODEL_A_VEHICLE. Если какая-либо проверка не удалась, мы сообщаем об этом игроку и возвращаемся от команды.

Здесь может быть оболочка C#, но важно повторно использовать собственные носители, так как вы будете часто использовать их при написании сценариев. Убедитесь, что в вашем классе есть директива.using static CitizenFX.Core.Native.API;

Шаг 2: Создание транспортного средства

Используя клиентский класс-оболочку C#, мы вызываем метод, который принимает модель, позицию и заголовок в качестве аргументов. Это самое замечательное в C#. У вас есть доступ к методу, предоставленному нами, так что вам не нужно запрашивать и загружать модель, как в Lua. Этот метод возвращает нам объект. Если у вас есть опыт работы с ScriptHookV.NET вы можете распознать эти классы. C# оболочка FiveM очень похожа.WorldCreateVehicleVector3floatVehicle

Шаг 3: Установка игрока в транспортное средство

Поскольку теперь у нас есть наш пед и транспортное средство, используя оболочку C# с объектом, мы можем установить себя на сиденье водителя автомобиля.Game.PlayerPed

Запуск этого

Постройте свой проект и убедитесь, что последний находится в папке вашего ресурса. В консоли сервера наберите (или как вы назвали свой ресурс) и попробуйте в игровом клиенте (который к настоящему времени должен быть действительно надоеден от возрождения). Теперь у вас будет свой собственный Rocket Voltic!MyResourceNameClient.net.dllrestart mymode/car voltic2

Серверные скрипты

Вероятно, вы также захотите написать сценарии, которые взаимодействуют с сервером. Этот раздел еще предстоит написать. :-(


Введение в написание сценариев