Almost Quit
-
After 2 or 3 weeks of getting absolutely nowhere with scripting, I really felt it was hopeless. Felt I had missed the party by about 5 years or more. Should've been here in 2015. To be honest I'm not passionate about modding, nor machinima. Just wanted to make some educational videos with this amazing sandbox, for myself and anybody else who wanted to share - to try an ease the pain of online learning during the pandemic.
So today I thought to myself, "you just don't get C#, let's try VB instead. One last shot and we'll call it quits". Well it started better but I had all kinds of inconsistencies and probably some caching/memory issues where even on restarting the game I would see residual spawns - go figure.
Then I would run the script several times and get different outcomes - can't even begin to explain that.
Finally I decided to break the script down into subroutines. That did it. Everything I wanted to do, spawn at absolute or relative coordinates, be a passenger in a car, and finally have the car driven by the AI according to absolute coordinates all gelled in about 3 hours of work. Contrast that with 3 or more weeks of getting nowhere with C#.
One challenge that frustrated me, as the player, was getting in the car. Hitting F resulted in a fight with the driver, so finally I realized i had to script the player's entry into the car as well as the driver and the front passenger, both AI. Originally I also scripted my exit but realized doing in manually (F key) gave me more flexibility to get out - ie. not at the same time as the passenger (which could have been done with a wait statement ofc).
Of course I learned a lot by just trial and error, but at last i feel i can now progress and get things done - and sure I know what i accomplished is very simple in the grand scheme.
So here is my first real script.
-
Well done! Very inspiring! Keep up the great work buddy!
-
One problem your going to have with VB is resources and examples available to you, not many people use it for scripting in GTA. So this may be a problem further down the line. As alot of people who will be able to provide you with help, will only do so with examples written in c#.
There is a wealth of information out there, but you have to dig around to find it, this forum being one also gtaforums com is another good place. Also there are a few youtube videos explaining alot of the basics. The 5mods discord has a scripting section that can also be alot of help when you are struggling. They can be a little hostile, but as long as your not wanting everything spoon fed to you, there is alot of learned just by asking questions.
I was in your position a year ago, dont give up!
-
@Wetter42 Thanks!
-
@mcal9909 I understand your point and thank you. However my requirements are fairly simple. I'll make an analogy with learning a second language, say Spanish.
One component is the grammar (syntax etc). Another would be vocabulary (among many others) which could be likened to the object model.
With C# I'm lost for both grammar and vocabulary. With VB I'm just lost with the vocabulary. So for me that's the win.
In practical terms, the code is essentially the same. Where I no longer struggle is in declaring variables that might be global or public.
I'm still very much struggling with lack of proper examples. For example, how Vector 3 parameters can mean pitch, yaw, roll for a prop and how they mean radius and speed for a vehicle. That's my biggest obstacle now - losing so much time doing things by trial and error - but progressing.
I'm including a snipped of the code i'm writing now and you will see how any C# programmer would have no issues understanding it.
If e.KeyCode = Keys.NumPad7 Then
MyPlayer = Game.Player.Character 'needed for relative coordinates only
'spawn car
CarSpawnLoc = MyPlayer.Position + (MyPlayer.ForwardVector * 4)
CarModel = "Baller"
MyCar = World.CreateVehicle(CarModel, CarSpawnLoc)
MyCar.PrimaryColor = VehicleColor.HunterGreen
MyCar.PlaceOnGround()
MyCar.NumberPlate = "STAFF"
End If
-
Its the reverse i was warning you about, alot of information you will find online regarding scripting in GTA will be written in c#, so not learning c# is going to hold you back alot as not understanding them examples will mean implementing them is going to be difficult.
This might help you get your head around vectors.
Also the scripthookVdotnet source code is a great help when trying to figure out how a method uses the arguments it requires.
https://github.com/crosire/scripthookvdotnet/tree/main/source/scripting_v3/GTA
-
@mcal9909 Thanks again for both links.
The documentation is still a puzzle for me. For example I was able, with help on these forums, to make a prop visible.
In C# it's as simple as myProp.IsVisible = true;
However, based on the documentation, how would I get to the statement above, when the docs only provide this:public bool IsVisible
{
get => Function.Call<bool>(Hash.IS_ENTITY_VISIBLE, Handle);
set => Function.Call(Hash.SET_ENTITY_VISIBLE, Handle, value);
}I can see it's a boolean so it will be true or false, but that's quite different from myProp.IsVisble = true, at least for a non-programmer like myself.
That's a relatively easy one, of course, but the challenge for me will be how to change the outfit or textures on a model.
I have no idea how I'm going to get there.
-
Ah i see where the confusion may be.
public bool IsVisible { get => Function.Call<bool>(Hash.IS_ENTITY_VISIBLE, Handle); set => Function.Call(Hash.SET_ENTITY_VISIBLE, Handle, value); };
As you can see its a bool, but its also a property and is used the same way any other variable is used. Its not a method, as it does not have any parentheses after the variable name. So if you want to set the property it must be assigned to using = true/false.
As you can see you can also get a value from this property.If(ped.IsVisible) DoSomething();
This can be similar to a method that returns a value of type bool.
public bool IsVisible(int handle) { return Function.Call<bool>(Hash.IS_ENTITY_VISIBLE, Handle); };
A method can not be assigned to, but will return a value. So can be used in multiple different ways.
if(IsVisible(ped.Handle)) DoSomething();
For setting outfits the use of this native is required. https://alloc8or.re/gta5/nativedb/?n=0x262B14F48D29DE80
-
@mcal9909 Thanks so much for your help and examples. Starting to see the light.
I am confused however on Hash vs Handle.If I "map" the get native function vs the C# Method:
Hash.IS_ENTITY_VISIBLE, Handle -------vs -------- if(IsVisible(ped.Handle))Am I right to assume Hash = entity ped and Handle = Variable to identify spawned ped?
for example, pseudo code:
set => Function.Call(Ped.SET_ENTITY_VISIBLE, Var MyPed_Michael, True);
Is this correct?And if that's right, isn't there confusion in that we also you hash for the name of the ped (pedhash.Michael)?
-
@JohnFromGWN said in Almost Quit:
A Handle is an entities unique ID in the world entity.Handle, A hash usually refers to the entities model. This can be accessed with entity.Model.Hash. A Ped inherits from Entity so has access to these properties.PedHash.Micheal is part of an enum called PedHash, enums are effectively named integer numbers in a list of model hashes.
public enum DayGTA { Sunday = 0, Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6 }
So
int day = Function.Call<int>(Hash.GET_CLOCK_DAY_OF_WEEK); DayGta eDay = (DayGta)day; //cast the int to a DayGta
eDay will = DayGta.Sunday if day returns 0. Which is much easier to read than working with pure numbers.
They can also be cast to an int with (int)eDay. Even turn them into a string with eDay.ToString(). Which will return "Sunday"
-
@mcal9909 Wow. I just had an "aha" moment.
I was under the mistaken impression that hash was a variable waiting to be filled!
int day = Function.Call<int>(Hash.GET_CLOCK_DAY_OF_WEEK);
var mystring = day.ToString();
UI.ShowSubtitle(mystring);This returned 5 as a string for today, Thursday, yet 5 is for Friday?
I don't follow your DayGTA - it won't compile. But more importantly how would you go from a Native such as GET_CLOCK_DAY_OF_WEEK to a GTA method or function?
Thanks for your help and dialog.
-
@JohnFromGWN It was just an example of how an enum works. GET_CLOCK_DAY_OF_WEEK returns the day in game.
public int DayOfWeek() { return Function.Call<int>(Hash.GET_CLOCK_DAY_OF_WEEK); }; public enum DayGTA { Sunday = 0, Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6 };
so if the day in game is Friday.
UI.ShowSubtitle(DayOfWeek().ToString()); will = "5"
UI.ShowSubtitle((DayGta)DayOfWeek().ToString()); will = "Friday"
-
@mcal9909 Got it. I just realized it returns the day in game, not the system day (unless set that way).
I really appreciate your help. I'm now getting comfortable with native functions.
Script is progressing well although I did leave it in VB given it is pretty much advanced.
Managed to port snippets of C# I found here and there to VB without any issues.
Will have something to show later today i hope.
Again, a big thank you.
John
-
Cool, i was worried you might hit some roadblock due to not being able to implement examples written in c# into VB and get disheartened.
Work with the language that your most comfortable with, after all, most languages are similar enough that once you learn one, learning another becomes very easy.
-
@mcal9909 The only difference I've found so far, and it took me 3 seconds to guess the difference, was
Native.Function.Call(Hash.SET_PED_AS_GROUP_MEMBER, Ped1, PlayerGroup)
VB takes Native to start the Function Call.
I find organizing the code more intuitive for me (If then blocks) with VB, same with declaring variables.
Progressing slowly but surely on the learning curve.
-
impressive. keep up the good work.
-
@FoxtrotDelta Thank you for the kind words of encouragement.