Implementing Spawn Vehicle Script - KimonoBoy/SHVDNTutorial-NucleiLite GitHub Wiki

We've covered all the scripts in the Player Menu - now for a change, let's create our Vehicle Spawner Menu

The Code

  1. Copy and Paste the following code to your Main.cs
using System;
using System.Linq;
using System.Windows.Forms;
using GTA;
using GTA.UI;
using LemonUI;
using LemonUI.Menus;

namespace NucleiLite
{
    public class Main : Script
    {
        ObjectPool menuPool = new ObjectPool();
        NativeMenu mainMenu = new NativeMenu("NucleiLite", "Main Menu");
        NativeMenu playerMenu = new NativeMenu("NucleiLite", "Player Menu");
        NativeMenu vehicleSpawnerMenu = new NativeMenu("NucleiLite", "Vehicle Spawner Menu");
        NativeMenu weaponsMenu = new NativeMenu("NucleiLite", "Weapons Menu");

        bool canSuperJump = false;

        public Main()
        {
            CreateMainMenu();
            CreatePlayerMenu();
            CreateVehicleSpawnerMenu();
            CreateWeaponsMenu();

            AddMenusToPool();

            KeyDown += OnKeyDown;
            Tick += OnTick;
        }

        private void CreateMainMenu()
        {
            mainMenu.AddSubMenu(playerMenu);
            mainMenu.AddSubMenu(vehicleSpawnerMenu);
            mainMenu.AddSubMenu(weaponsMenu);
        }

        private void CreatePlayerMenu()
        {
            // Fix Player
            NativeItem itemFixPlayer = new NativeItem("Fix Player", "Restores Player's Health and Armor");
            itemFixPlayer.Activated += (sender, args) =>
            {
                Game.Player.Character.Health = Game.Player.Character.MaxHealth;
                Game.Player.Character.Armor = Game.Player.MaxArmor;
                Notification.Show("Health and Armor Restored!");
            };
            playerMenu.Add(itemFixPlayer);

            // Invincible
            NativeCheckboxItem checkBoxInvincible = new NativeCheckboxItem("Invincible", "Your character can no longer die.");
            checkBoxInvincible.CheckboxChanged += (sender, args) =>
            {
                Game.Player.Character.IsInvincible = checkBoxInvincible.Checked;
                Notification.Show($"Invincible: {Game.Player.Character.IsInvincible}");
            };
            playerMenu.Add(checkBoxInvincible);

            // Wanted Level
            NativeListItem<int> listItemWantedLevel = new NativeListItem<int>("Wanted Level", "Adjust Player's Wanted Level.", 0, 1, 2, 3, 4, 5);
            listItemWantedLevel.ItemChanged += (sender, args) =>
            {
                Game.Player.WantedLevel = args.Object;
            };
            playerMenu.Add(listItemWantedLevel);

            // Super Jump
            NativeCheckboxItem checkBoxSuperJump = new NativeCheckboxItem("Super Jump", "Allows the Player to Jump higher than a building.");
            checkBoxSuperJump.CheckboxChanged += (sender, args) =>
            {
                canSuperJump = checkBoxSuperJump.Checked;
            };
            playerMenu.Add(checkBoxSuperJump);
        }

        private void CreateWeaponsMenu()
        {
        }

        private void CreateVehicleSpawnerMenu()
        {
            foreach(VehicleHash vehicleHash in Enum.GetValues(typeof(VehicleHash)))
            {
                NativeItem itemSpawnVehicle = new NativeItem(vehicleHash.ToString(), $"Spawns a {vehicleHash} right in front of you!");
                itemSpawnVehicle.Activated += (sender, args) =>
                {
                    Ped character = Game.Player.Character;

                    Model vehicleModel = new Model(vehicleHash);
                    vehicleModel.Request();

                    Vehicle vehicle = World.CreateVehicle(vehicleModel, character.Position + character.ForwardVector * 3.0f, character.Heading + 90.0f);

                    vehicleModel.MarkAsNoLongerNeeded();

                    Notification.Show($"Vehicle: {vehicleHash} has been spawned!");
                };
                vehicleSpawnerMenu.Add(itemSpawnVehicle);
            }
        }

        private void AddMenusToPool()
        {
            menuPool.Add(mainMenu);
            menuPool.Add(playerMenu);
            menuPool.Add(vehicleSpawnerMenu);
            menuPool.Add(weaponsMenu);
        }

        private void OnTick(object sender, EventArgs e)
        {
            menuPool.Process();

            if (canSuperJump)
            {
                Game.Player.SetSuperJumpThisFrame();
            }
        }

        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F5)
            {
                mainMenu.Visible = !mainMenu.Visible;                
            }
        }
    }
}
  1. Build and Reload()

  2. Go to your Vehicle Spawner Menu and select any Vehicle and hit Enter

image

Note: The Spawner Menu features all the vehicles available, making it a cumbersome task to locate your preferred vehicle. However, this is a deliberate decision to maintain the simplicity of NucleiLite's code. To discover ways to alleviate this issue, refer to the Nuclei - Wiki

Code Breakdown - Simplified

Just like in our scripting-section, the Spawn Vehicle Menu is a bit more complicated than what we've created so far, but I believe in you!

        private void CreateVehicleSpawnerMenu()
        {
            foreach(VehicleHash vehicleHash in Enum.GetValues(typeof(VehicleHash)))
            {
                NativeItem itemSpawnVehicle = new NativeItem(vehicleHash.ToString(), $"Spawns a {vehicleHash} right in front of you!");
                itemSpawnVehicle.Activated += (sender, args) =>
                {
                    Ped character = Game.Player.Character;

                    Model vehicleModel = new Model(vehicleHash);
                    vehicleModel.Request();

                    Vehicle vehicle = World.CreateVehicle(vehicleModel, character.Position + character.ForwardVector * 3.0f, character.Heading + 90.0f);

                    vehicleModel.MarkAsNoLongerNeeded();

                    Notification.Show($"Vehicle: {vehicleHash} has been spawned!");
                };
                vehicleSpawnerMenu.Add(itemSpawnVehicle);
            }
        }

Inside our CreateVehicleSpawnerMenu() method we define a loop - we've glanced at loops in the Give All Weapons Script simplified version and covered it somewhat more in-depth in the advanced section, however have a look at the below

foreach(VehicleHash vehicleHash in Enum.GetValues(typeof(VehicleHash)))

Let's try to phrase it in a simple and human-readable manner: Take all VehicleHashes in the collection of all VehicleHashes and go through them one by one, for-each one you find do the following:

Create a new NativeItem with the Title of the VehicleHash (e.g. Annihilator), give it a Description that matches the VehicleHash, set an activated-event for-each of them, when this event is triggered create a new model from the vehicleHash, from the model create the Vehicle by the World.CreateVehicle()-method three units away from the Player with the Vehicle facing with the driver-seat towards the Player, once spawned clear the vehicleModel from resources, finally display a message to the Player about the Vehicle being spawned, then add the itemSpawnVehicle to the vehicleSpawnerMenu

See the Advanced-section for further information

Code Breakdown - Advanced

        private void CreateVehicleSpawnerMenu()
        {
            foreach(VehicleHash vehicleHash in Enum.GetValues(typeof(VehicleHash)))
            {
                NativeItem itemSpawnVehicle = new NativeItem(vehicleHash.ToString(), $"Spawns a {vehicleHash} right in front of you!");
                itemSpawnVehicle.Activated += (sender, args) =>
                {
                    Ped character = Game.Player.Character;

                    Model vehicleModel = new Model(vehicleHash);
                    vehicleModel.Request();

                    Vehicle vehicle = World.CreateVehicle(vehicleModel, character.Position + character.ForwardVector * 3.0f, character.Heading + 90.0f);

                    vehicleModel.MarkAsNoLongerNeeded();

                    Notification.Show($"Vehicle: {vehicleHash} has been spawned!");
                };
                vehicleSpawnerMenu.Add(itemSpawnVehicle);
            }
        }

We've already covered loops in our Give All Weapons - Advanced-section - but let's have a in-depth look at what's going on here

foreach(VehicleHash vehicleHash in Enum.GetValues(typeof(VehicleHash)))
{
    // Code here
}

The VehicleHash enum is a built-in enum in ScriptHookVDotNet that represents all available vehicles in the game. We use the Enum.GetValues method to retrieve an array of all values in the VehicleHash enum, and then loop through each value using a foreach loop.

You can learn more about Enums
You can see the definition of the Enum.GetValues()-method here


NativeItem itemSpawnVehicle = new NativeItem(vehicleHash.ToString(), $"Spawns a {vehicleHash} right in front of you!");

We create a new NativeItem instance for each vehicle hash in the VehicleHash enum, we set the display text to the name of the vehicle using the .ToString() method of the VehicleHash, and we set the description to Spawns a [vehicle name] right in front of you! using string interpolation.

You can learn more about String Interpolation


itemSpawnVehicle.Activated += (sender, args) =>

Create an anonymous method using lambda-expressions to handle the Activated-event for each menu item

You can learn more about Lambda Expressions
You can also learn more about Anonymous Methods


Ped character = Game.Player.Character;

Creates a variable to hold the value of the Game.Player.Character where the Character represents the Character the Player is currently playing.


Model vehicleModel = new Model(vehicleHash);
vehicleModel.Request();

We create a new instance of the vehicle model using the corresponding vehicle hash, and request the model using the Request method to ensure that it's loaded into memory before we attempt to create the vehicle itself.

We've also covered the Model-object and its resources at Vehicle Spawner Script - Advanced


Vehicle vehicle = World.CreateVehicle(vehicleModel, character.Position + character.ForwardVector * 3.0f, character.Heading + 90.0f);

We then create a new instance of the vehicle using the World.CreateVehicle method, passing in the vehicle model, the player's position offset by a distance of 3 units in the forward direction (using the ForwardVector property of the character), and the player's heading plus 90 degrees (to ensure that the vehicle is spawned facing perpendicular to the player's direction - meaning the driver-seat will be right infront of the Player).


vehicleModel.MarkAsNoLongerNeeded();

Finally, we mark the vehicle model as no longer needed using the MarkAsNoLongerNeeded method, since we're done with it after creating the vehicle. We also display a notification to the player indicating that the vehicle has been spawned.

Again, have a look for a more detailed in-depth explanation at Vehicle Spawner Script - Advanced

Conclusion

The CreateVehicleSpawnerMenu() method creates a submenu for spawning vehicles. It loops through all values in the VehicleHash enum and creates a new menu item for each vehicle, using an anonymous method and lambda expression to handle the Activated event for each item. The anonymous method creates a new instance of the corresponding vehicle at the player's position with a heading of 90 degrees to the player's current heading. The submenu is added to the main menu using the AddSubMenu method.

Previous - Implementing Super Jump Script
Next - Implementing Give All Weapons Script

⚠️ **GitHub.com Fallback** ⚠️