FiveM için komut dosyası yazmaya başlamak, çok çeşitli olasılıklar ve seyrek yayılmış dokümantasyon göz önüne alındığında biraz zor olabilir. Bu hızlı ve basit kılavuzda, size C #'da hızlı bir kaynakla nasıl başlayacağınızı göstermeye çalışacağız. Bir komutla bir araba üretme sistemi uygulayacağız.

Önkoşullar

C # ile ilk komut dosyanızı oluşturmadan önce, ayarlamanız ve anlamanız gereken birkaç şey vardır.

Kod yazma

Artık C # projenizi ve ortamınızı kurduğunuza göre, iki projeniz olacak; MyResourceNameClientve MyResourceNameServer.

FiveM komut dosyasıyla ilgili olayları işleyen herhangi bir C # sınıfı, BaseScriptsınıftan miras almalıdır . Bunu Class1.csmüşteri projenize giderek yapalım . Aynı zamanda ileride kullanacağımız bir kurucu da tanımlayacağız. Bir kullanma yönergesine sahip olduğunuzdan emin olun CitizenFX.Core.

using CitizenFX.Core;

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

        }
    }
}

Kolay değil mi? Peki ya işlevsellik eklemeye ne dersiniz? Çeşitli FiveM betik oluşturma konseptlerini kullanarak bir komut ekleyerek başlayacağız.

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);
        }
    }
}

Bu noktada bunalmış olabilirsiniz ama endişelenmeyin. Her şeyi yavaş yavaş gözden geçireceğiz.

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

Yapıcıda , onClientResourceStart olayı için bir olay işleyicisi ekledik . Bir argüman gerektirir; başlatılan kaynağın adını içeren bir dize. Ayrıca OnClientResourceStartyapıcının altında tanımladığımız bir temsilci yöntemine de sahiptir . Kaynak başladığında, FiveM bu olayı tetikleyecek ve yöntemi çağıracaktır.

if (GetCurrentResourceName() != resourceName) return;

Bu if deyimi yerelden yararlanır GetCurrentResourceName(). Kısacası, yerli halkla hiçbir ilgisi olmayan yerliler, aslında 'oyun tanımlı komut dosyası işlevleri' için bir R * etiketidir. Bu yerlilere CitizenFX.Core.Native.APIsınıf aracılığıyla erişebiliriz . Daha sonra bir araç yaratırken diğer yerlileri kullanacaksınız. Bu GetCurrentResourceName()kod parçacığında, komut dosyamızın çalıştırdığı kaynağın adını döndürür. resourceNameYöntemin geri kalanını yalnızca bir kez çağırdığımızdan emin olmak için bunu argümanla karşılaştırıyoruz . Bu kontrolü yapmazsak, yöntemin geri kalanı herhangi bir kaynak her başladığında çalışacaktır.

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);

Başlamak için bir fonksiyon çağrısı görüyoruz. Bu işlevi tanımlamadık. Evet, biz (FiveM ekibinde olduğu gibi) yaptık, ama bu harika yazılmış bir rehber harikası boyunca size, okuyucuya rehberlik ederken değil. Bu, başka bir yerden gelmesi gerektiği anlamına gelir!

Ve tahmin et ne oldu, aslında REGISTER_COMMAND ! Bu bağlantıya tıkladığınızda bu yerel için belgelere yönlendirileceksiniz. Biraz şuna benziyor:

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

Esas olarak ikinci satırdaki isme ( RegisterCommandyukarıdaki C # kodunda kullanıldığı gibi) ve argümanlara önem vereceğiz .

Gördüğünüz gibi, ilk argüman komut adıdır . İkinci bağımsız değişken, komut işleyicisi olan bir işlevdir (örneğimizde Eylem temsilcisi tarafından temsil edilir) ve üçüncü bağımsız değişken, bunun sınırlı bir komut olup olmayacağını belirten bir mantıksaldır .

İşlevin kendisi source, yalnızca sunucuda çalışıyorsanız gerçekten önemli olan bir argüman alır (komutu giren oyuncunun istemci kimliği, sahip olması gereken gerçekten yararlı bir şey olacaktır) ve bir argsbunlar temelde varoluşu veya varoluşu /car zentornoyapmak gibi komuttan sonra girdiğiniz şeylerdir .argsnew List<object>{ "zentorno" }/car zentorno unusednew List<object>{ "zentorno", "unused" }

Peki ya ne olacak TriggerEvent()? Bu da bizim tarafımızdan tanımlanmaktadır . Sohbet kaynağının bir chat:addMessageparçası olan etkinliği çağırmak için kullanılır . Yazılı örneğimizde, yazarın adını kırmızıyla ve argüman olarak bir mesaj gönderiyoruz .[CarSpawner]

Bu noktada, müşteri projenizi oluşturabilir, kaynağınıza ekleyebilir / taşıyabilir ve çalıştırabilirsiniz. /carSohbet kutusuna yazarken , tanımladığımız sohbet mesajını döndüren komutumuzu göreceksiniz.ekran görüntüsü-1

Hey! Sohbet kutusunda bunu uygulayamayacak kadar tembel olmanızdan şikayetçi. Onlara kesinlikle tembel olmadığınızı göstereceğiz ve bunu şimdi uygulayacağız.

Bir araba çıkma yeri uygulama

İlk betiğinizi oluştururken Lua öğreticisini takip etmiş olabilirsiniz ve ezici görünebilecek çok sayıda standart kod olduğunu hatırlayabilirsiniz. Korkmayın, FiveM kodu azaltmamızı sağlayacak, kullanımı kolay bir C # sarıcı sağlar.

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);

Bu, bazı yerelleri ve C # sarmalayıcı yöntemlerini kullanır. Birkaçını birbirine bağlayıp zor kısımları açıklayacağız.

Adım 1: Doğrulama

Modeli kontrol etmekle başladık. Biz ayarladık adder. Herhangi bir argüman varsa, modeli ilk argümana ayarlayıp bir dizgeye çeviririz.

Ardından IS_MODEL_IN_CDIMAGE kullanarak aracın CD görüntüsünde olup olmadığını kontrol ederiz . Bu temelde 'bu oyuna kayıtlı mı' anlamına gelir. IS_MODEL_A_VEHICLE kullanan bir araç olup olmadığını da kontrol ediyoruz . Kontrollerden biri başarısız olursa, oyuncuya söyler ve komuttan geri döneriz.

Burada C # sarmalayıcı olabilir, ancak komut dosyası oluştururken onları çok kullanacağınız için yerellerin kullanımını somutlaştırmak önemlidir. using static CitizenFX.Core.Native.API;Sınıfınızda yönergeye sahip olduğunuzdan emin olun .

Adım 2: Aracın oluşturulması

İstemci tarafı C # sarmalayıcı sınıfını kullanarak, bir modeli, konumu ve başlığı argüman olarak Worldalan CreateVehicleyöntemi çağırırız . Bu, C # ile ilgili harika bir şey. Lua'da yaptığınız gibi bir model talep etmek ve yüklemek zorunda kalmayacağınız şekilde tarafımızdan sağlanan bir yönteme erişiminiz vardır . Bu yöntem bize bir nesne döndürür . ScriptHookV.NET ile deneyiminiz varsa, bu sınıfları tanıyabilirsiniz. FiveM'in C # sarıcısı çok benzer.Vector3floatVehicle

3. Adım: Oynatıcıyı araca yerleştirme

Artık pedimiz ve aracımız olduğu için, Game.PlayerPednesneyle birlikte C # sargısını kullanarak kendimizi aracın sürücü koltuğuna oturtabiliriz.

Bunu çalıştırıyorum

Projenizi oluşturun ve MyResourceNameClient.net.dllen yenisinin kaynağınızın klasöründe olduğundan emin olun . Sunucu konsolunuzda yazın restart mymode(veya kaynağınıza ne isim verirseniz verin) ve /car voltic2oyun istemcisini deneyin (şimdiye kadar yeniden canlanmaktan gerçekten sıkılmış olmalı). Artık kendi Rocket Volticinize sahip olacaksınız!

Sunucu komut dosyaları

Muhtemelen sunucuyla etkileşime giren komut dosyaları da yazmak isteyeceksiniz. Bu bölüm hala yazılacak. :-(


Fivem Oyun Sunucunuzu kurmadan önce bir fivem oyun sunucusuna sahip olmanız gerektiğini unutmayın. Fivem Oyun Sunucusu paketlerimizi incelemek için tıklayın.