Creating-your-first-script-csharp
Создание первого скрипта на 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
Серверные скрипты
Вероятно, вы также захотите написать сценарии, которые взаимодействуют с сервером. Этот раздел еще предстоит написать. :-(