A real use for private: Suppose orcScript has a hitPoint var. When the orc gets hit, the sword script does orcThatGotHit.hitPoints-=damage; and checks for death.
Now you add pits and explosions that also hurt orcs – they also subtract from HP and check for death. Then you add a bloodSpray – you add blood code (maybe just a function call) to swords, pits and explosions. After a while, you realize that for the “sword of wounding” DoT effect, programmers are just subtracting from hitPoints, and not checking for death or adding blood. There’s way too much code to copy around.
So, you create a function in orcScript something like getHit(damage, location, damageType). It changes HP, checks for death, makes the blood, does the lifeBar… . You tell everyone to run just orcThatgotHit.getHit(5,hit.point,"fire"); instead of the old changing HP, death check … .
But, some of the old code still just changes HP, and sometimes you forget and just change HP when you write new stuff (hitPoints is right there in the pop-up.) So, you go to orcScript and make hitPoints be private. Now all the old code in other scripts that used HP directly shows up as easy to find and fix errors, and you can never change HP directly again – won’t even see it in the Inspector. If you bring a new guy in, to write fireBomb code, they will automatically use getHit to do orc damage, without you even needing to explain it to them.
For a NonSerializeable example, suppose someone in game can change clothes. You want to personally save that using C#'s built-in file-writing abilities. You can auto-save the names of the clothes, the sizes … but C# doesn’t know how to automatically save a Unity texture.
So, you save the texture name, “softwool”. On a Continue, you read the name and load Unity’s softWool texture from the Resources folder. To tell C# not to try saving the Texture when you use the SaveToFile command – it doesn’t need to and it can’t – you mark it as NonSerializable.