[Unity C#] Exchanging Data Between Scripts (Fields, Properties and Static Keyword)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello its acacia developer here and today we're going to be talking about transferring data between different scripts in unity so the aim of this tutorial is getting you to be able to set and get values from other scripts and we're going to cover a few different topics so the first goes through public fields the second goes through public properties and the final goes through the static keyword I recommend that you watch the entire video before asking any questions now in this tutorial we are using an analogy and the analogy is going to be a multiplayer server so we have multiple players that connect to a server and we have an admin and the admin wants to retrieve some data from the players so of course the game isn't actually a multiplayer game this is only an analogy to help beginners understand what's going on so to begin with what I'm going to do is create a new C sharp square I'm going to call this script admin I'm going to create another C sharp script and call this one player then in the scenes hierarchy I'm going to right click and then navigate to create empty I'm going to rename this empty game object to admin and then attach my admin script to the game object I'm then going to create another game object which is going to be a capsule and since this represents a player I'm going to rename this to player and then attach my player script to that then I'm just going to duplicate this a few times and then that way we have more than one player so these could represent individual players who have just connected to at your multiplayer server each of these individual players withhold their own player script which can withhold their own data and of course we have our invisible game object which has our admin script attached to it and the objective is is to get the admin script to modify and access data within the player scripts that are attached to these three player objects here so first of all we need some data for the admin class to be able to access so what I'm going to do is declare some public fields in the player class so this is an integer whole number which will represent the player's health we'll have a boolean so this can either be true or false which dictates whether or not the player is dead or not and we'll have a float for the walk speed and then maybe another float for the run speed like so now as they stand these fields aren't actually doing anything really they're just examples of the kind of data that you may be exchanging between scripts you may have noticed that each of these fields are appended with the public access modifier and of course this is crucial because since we want to access all of these fields from outside this class they require to be public so in order for the admin class to any data from the player class what we need to do is access the data from an instance of the player class so it would be private player I'm swinging call this field player obj so of course this is a field that has a data type that directly corresponds to the class that we've declared here and that means that any object that is put into here is required to retain these four fields that we'll be able to access so in the admin script will actually be accessing these fields from our player obj now the reason why this field is private is because I don't want anything outside the admin class changing it or manipulating it a problem with this though is the fact that it's not public so it's not going to appear in the inspector but we can actually solve this problem by appending an attribute the serialized field attribute and what that does is is it make sure that this field down here is always exposed in the inspector despite its access modifier so once we come back to the unity editor we click on one of our players as you can see all of those public fields that we created in the player class earlier are now exposed in the inspector and it makes sense considering they were all public so they'll automatically expose so what I'm going to do here is insert some arbitrary value so I'll give them maybe a health of a hundred and ten and so those are our values on this player script for this capsule object now if you click on our admin on our admin script we can see our player obj field is exposed that was the one with the serialized field attribute and of course it's asking for a player so what we can do is we can drag our player game object directly into the slot what it's doing it's going into player and then it's finding this script here and then it's putting this script into this slot here so now that we've got that script object hooked up to our player obj we can start accessing and manipulating the public fields so I'm going to put this in void start and remember that we're using player obj to access the fields so if we go back to our player class we have things that health is dead walk speed run speed so all we need to do is type in player obj dot so we use what's called the dot operator to access the public field and as you can see intellisense tells us that there's a public field in there called health there's also walk speed run speed as well and of course our infamous is dead well I'm going to do first of all is just print this to the console so basically what these four lines of code will do this will print the health of the player object of the console it will print whether or not it's dead to the console the walk speed and the run speed as well so let's just save that and run our scene and just see how things go as you can see all of the values printed out on the console match up with the values that we inputted in on the inspector and since it's the admin class that is printing this we have definitive proof that the admin class is able to access those values so far all we've done is we've accessed these public fields and what we're doing is we're just passing them in as an argument into this function that's printing it to the console but what I want to show you now are the operations that you can apply to them just prove to you that you can so you could do player obj dot walk speed plus equals zero point two F or something so you can add you can also assign so maybe I have a float for the new walk speed something and that's equal to obj dot walks fees and then I can get my new walk speed and incrementer or something and also the same for all the other public members as well so maybe sorry I'm getting the name wrong here is that we can set that to true so we've now made the payer died and also maybe got health we want to regenerate the player's health or maybe we want to set it to something ridiculous like four hundred of course this is actually going into another issue that will address later on with public properties but really this is just to show you that you're still able to execute all of the same operations and that even if you know player obj dot is dead isn't within the admin class we can still access it and we can still set it and of course we can still get values as well like in this example and then store it in this local float variable and then we can do whatever we want with our afterward so back in our player class we can see all of the public fields that we've declared now unfortunately public fields are actually considered bad practice in c-sharp and this is because this public access modifier actually exposes the field to other classes in your program and they can see all of these fields and they can manipulate them possibly in an unexpected manner and one of the key issues is is being able to check whether or not data is invalid so for example if I'm creating a game where I wouldn't want my health value for any enemy to go below zero or over a hundred how exactly using a public field would I check that because any class could throw in any value I could throw in four hundred four thousand of course an integer datatype can hold values way larger than 100 which is a problem so ideally what we want is a way to be able to check incoming data before we assign it to a certain field and this is where properties come in so to declare a property I'm going to type public int and then the name of the property is going to be health with a capital H like so then in here we can put get four now I'm going to put in here return health and set health equals value and then up here our public field is now going to become private so now this public property here has become the new interface for this private field up here so I'm just going to show you quickly how to trigger the get and the set and and when these blocks of code are triggered and of course if we switch over to our admin class our health is no longer seen the admin class can't see it anymore because it's private so instead what we use is the property so in this case we're actually getting because we're getting the value so this is the block of code that's going to be executed when we pass this into our function here to print to the console and of course that's going to return the value of this private field here and then whenever we set so that would be something like this player obj dot health this is just going to be an arbitrary value that I put in so we've just set it to 20 in that case this line of code would trigger the setter here and that would simply assign our private field with the value which in this case would be our 20 of course as it stands at the moment we're not actually doing any checks so this property is sort of redundant at the moment it was doing exactly the same thing as before when this was just public without the property so I've deleted that code in the setter and I've extended the pair of braces down so I have a bit more room to type my code now this is going to be the block of code that checks the incoming value so like we already know I'm just going to create an if statement but the value keyword is what we use to get the incoming value so that's whatever value this property is being set so we want to check if it's below zero or if it's over 100 and this is this is the block of code that executes if the value is invalid and in that case we want to do a debug log error and then we can say something like health is less than zero or larger than 100 or else so this is a case where the value would be between 0 and 100 then we're all right so we can just set the health with the value like so so really that's just a a simple check so now in the admin class if I go player obj dot health is equal to 2020 should be valid because it's a number between 0 and 100 and as you can see it doesn't complain and it's printing out all the stuff like normal and you can see it's changed to 20 let's try and assign an invalid number so first of all I'm gonna try - maybe minus 1 and as you can see it's created an error message in the console now if I set it to a really awkward number let's say 101 as you can see it's error again so to take things one step further and just to show you the flexibility of public properties we could say that well you have your is dead boolean and when the is dead boolean is equal to true then you want to play some sort of death animation so you could check your is dead boolean every single frame so you could check if it's true or false and if it's true you then play the animation what you want to do is check it every time the health is changed what we can do here is extend these braces here we'll still assign the health the value but we'll just do a little if statement here so if the value is equal to zero then we know that the player is dead so we can set is dead is equal to true you could extend these and then you could play your animation in here so function to function call to play death animation or something and really you're only checking when it's necessary and the only time that you should check would be when the health changes not every single frame in a way I could have written this a bit better so for example if the incoming value was a negative then I could clamp it to 0 and if it's over 100 I can then clamp it to 100 but really this was just to demonstrate the power and flexibility of properties they are really really awesome so use them now one thing that I wanted to outline quickly if you select your capsule as now and you look at the player script for each one you'll see that the health field has disappeared and that's because we made it private but what you can do in the player script is you can use the serialized field attribute like we did before and this private field will still work in conjunction with your public property it's just that it will now be exposed in the in the inspector as well so that was just a little bit of advice if you if that becomes problematic for you so there you go so the health has popped back up in the inspector so now we're going to move on to the static keyword and I'm just going to retract this property because it's a bit too large so let's say we wanted to give every single player the same walk and run speed what we could do is type here static so instead of public float we now have a public static float now many people get caught out with this because what the static keyword does is it makes this field a member of the type as opposed to an instance of the type so if we go back to admin now you'll see that walk speed is no longer a part of this object instance which is our player obj so instead we now have to type player dot and then you'll see our walk and run speed in there now this is a thing you don't need an instance anymore so we could delete this and delete these and this would still work because well these fields are now a member of the actual type you can see that we're now typing in player which is the name of the class itself and then we can access these fields so however many objects we create from the player class our walk speed and run speed are always going to be the same value whereas a non-static fields such as this private field for our health is unique for every single object that is created so a lot of beginner programmers think that they can make fields and properties alike static because it seems to make it simpler to exchange data between different classes but what they're actually doing is is making fields and properties a member of the actual type and in that case there's only one instance of that field I recommend using the static keyword when you're dealing with global variable so basically for any days huh where there's only one of it so to demonstrate the static keyword I'm just going to create a void start method and in this start method all we're going to do is debug log and for now I'm just going to go for the run speed like so so notice because we're actually typing this line of code within the player class we don't actually need the player dot run speed this would be redundant as you can see Visual Studio is telling us that the name can be simplified so we don't actually need this so now what we can do in the adven class in our void awake so we know that void awake is actually called before void star so if I get rid of this we can simply set our player dr. run speed let's say to eight point zero three something quite specific so the admin class is going to set our run speed to this value and then our player class is then going to print that out but remember we have three different player classes because we have three different player objects all with player scripts attached so when we press play as you can see eight point zero three is printed to the console and we can see that it has been printed three times if we click on collapse here that will uncollapse all of these so we can see all of the printed items individually so the fact that we set the static property once and all of them have come out with eight point zero three goes to show that our run speed value is the same across all instances of the player class anyway that concludes today's video I really hope you enjoyed and learned a lot and like always I shall see you soon
Info
Channel: Acacia Developer
Views: 14,703
Rating: undefined out of 5
Keywords: static keyword, C#, public properties, public fields, exchanging data
Id: PEfGcw1_KRc
Channel Id: undefined
Length: 20min 28sec (1228 seconds)
Published: Tue Jul 10 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.