A Concise Guide To Almost All The C# You'll Ever Need To Know Code-Wise To Make A PS4 Game in Unity
A Concise Guide To Almost All The C# You'll Ever Need To Know Code-Wise To Make A PS4 Game in Unity
This guide is to teach yourself. Id advise not watching youtube tutorials where someone spends 20
minutes showing how to use the hierarchy, just fiddle with stuff and drag stuff around until it works.
Add components. Fiddle with classes. If you want to do something, start making a script for it, do the
bit you can do and when youre stuck, google it. Realistically, there wont be any tutorials later for
your hard, specific problems later so its good practice not to use them at the beginning.
This document contains all the variables, functions and other shit youll need to know to make a 2D
PS4 game, minus like some very small things that dont matter. The documents reasonably small
because theres not actually that much stuff. If you just learn every line of this (theres a reason its
so small because it all matters) and you know how to tell a machine to do stuff, you can make a
PS4 game. You need to know how to work the engine too and the nuances but this covers all the
code almost. By the time you can use all of this stuff there wont be much extra stuff youd need to
learn. Knowing maths helps a lot, especially trig (for code based animation e.g.). If you read
something and you dont fully get it, google that thing or experiment with it until you do.
First up, get some good version of Visual Studio and use intellisense first of all, it will speed up
everything about 9000x. Legitimately, it not only speeds up typing probably 5-10x but it speeds up
learning like 10,000 times because it shows you all your variables. Link it TO Unity.
Id advise using C# because js isnt as powerful. It starts very slightly more difficult but then its way
better afterwards. I dont even know what Booscript is, Unity also supports this, I would advise not
using it considering its like.. called Boo. And no one uses it. If you dont know enough c#,
codecademy is a good way of learning.
float (we dont use doubles in c#. Because of that, when you write 3.453 you have to write 3.453f,
not 3.453 everywhere in your code)
string (we wont use chars but understand that chars use and strings use , and a string is an
array of chars)
C# Lists (System.Collections.Generic. These are good for arrays when you dont know the original
size) (blah.Count gets the length)
Vector3 (x, y, z, which you can cast to Vector2 by writing (Vector2)[my vector3]). These also
contain .normalised and .magnitude, which are super useful. If you just want to change x, tough shit,
you have to do:
Quaternion (dont try to understand it, just use its functions. Its a four dimensional rotation tensor
matrix).
Rects (used for gui rectangle shit mainly. Might not need to know this for a long time)
new (e.g. somelist = new List<blah>(); or somearray = new int[5]{1,2,3,4,5};) (You need this for arrays,
colors, color32s, vector2s, vector3s, rects, lists and probably other stuff I forgot)
return (give back a variable at the end of a function. Also in voids you can just say return; to kill it
straight off)
yield return new (you need this for ienumerators. You can stick a function on the end of there and it
wont stop until its finished doing it. E.g. WaitForSeconds() or Instantiate() if youre spawning a
whole scene or something).
Maths shit:
UnityEngine.Random.Range(lowerinclusive,higheruninclusive)
Mathf.PI 3.141592etc.
Mathf.Deg2Rad
System.Int32.Parse(string) -> turns string into number. Tryparse also exists but fuck try, just get it
right.
Mathf.Sin, Mathf.Cos, Mathf.Tan for trig. Mathf.Asin, Mathf.Acos, Mathf.Atan2 for antitrig. Use
Atan2(y,x) not Mathf.Atan or it wont work how you want it to in 99% of cases. Just trust me there.
Mathf.Pow is really good for squared trig functions (generally x*x is faster than Mathf.pow(x,2)
though but it saves you writing it on two lines or doing the calculation twice) and gravity.
Terms:
public (interactable from other classes and you can change it in the editor). Youre going to be using
this a lot.
static (The same for every class, cant change in the editor). Youll use this when youre better at
knowing shit. Its handy to make a public static version of everything theres one of like your camera
and your player, so you can easily call them from anywhere.
Statements:
if
else if
else
for(int i=0;i<blah.length;i++){}
you can use while but.. most of the time theres a better way
== (you can test for blah==null too for gameobjects you havent defined yet). Theres none of this
=== javascript bullshit here.
!=
c# tricks:
isStatic -> this is in the top right of the editor. Tick this shit if the thing never moves, makes it way
more efficient. NEVER TICK IT OTHERWISE.
Tag is a group somethings tagged as. I personally avoid tags except for things like.. if they kill you.
But you can easily do this by checking for a non-null class anyway.
Transform this is the core of all objects. It has their spatial dimensions. It contains (ALL REALLY
IMPORTANT):
transform.rotation -> rotation in world space, this is a Quaternion. More on that later.
transform.localRotation
transform.localScale (YOU HAVE TO MANIPULATE THIS, YOU CANT CHANGE REAL SCALE)
transform.GetChild(0) will get the first child. Also you can get all children of bloop with:
GameObject (you can grab this gameobject component with blah.gameObject to fiddle with it). This
is what youll mostly deal with, spawn, destroy, grab components off.
Collider/Collider2D (this is how things with rigidbodies/rigidbody2ds hit each other. It has a thing
called isTrigger. Triggers are great for starting events where it doesnt stop the player, like making
someone talk when you walk in a room or something. Colliders also send collision messages so you
know whats up. More on that later)
Rigidbody/Rigidbody2D (do all your physics through here. They contain mass, drag, angularvelocity,
angulardrag, gravityScale etc. and you should do movement through here by doing
Rigidbody2D.velocity += blah or using AddForce). isKinematic says whether it collides with stuff or
whether it just moves on its own. Other stuff will still collide with kinematic objects.
Renderer/SpriteRenderer -> enable/disable this to make it appear/disappear. This also has material
on it and sharedMaterial. If you fuck with a sharedMaterial it will change forever in the editor but
change all objects. Changing one Material will change draw calls.
Materials also have the option to setfloats, setcolors etc. which is useful when youre writing shaders,
but you probably arent right now so figure that out when you need to.
Color/Color32, color goes from 0-1, color32 uses bytes from 1-255. You can do maths with bytes but
youll have to cast to byte by writing (byte)*some int+. Thats good for fading shit out. And use
Mathf.RoundToInt first. If you want to grab components you do somecolor.r, somecolor.g,
somecolor.b, somecolor.a and it will return 0-1, so you can use that to find like.. if youre faded.
Also shit like AudioSource/Camera/Light, youll learn as time goes on (e.g light distance, intensity).
Camera.main is important, thats your main camera obvs. You can get that to work in the tags.
Awake() Runs at the very, very beginning. Use this scarcely, for things that NEED to happen before
anything else, like choosing static variables. E.g. in RudeBear the first thing that happens is Bear =
this where Bear is a public static variable, so any other script can say RudeBear.Bear.Die(); or
whatever
Start() This is where you set your variables. You HAVE to. Even if you put int blah=5; if that ever
changes when you reload the scene itll still be changed. You need to set all your variables here and
create your arrays and shit.
Update() Runs every frame. You can handle input here (although I dont). e.g. itll immediately
know if youve clicked. But if when you click, something happens, think about doing it in
FixedUpdate or you game will become framerate dependent. If I apply some force in Update() then
the game will change if youre at 30fps or 60fps. You can divide by Time.deltaTime but thats what
morons do, dont listen to that.
FixedUpdate() This runs every 0.02 seconds by default. This is where all physics happens. Always
control gameplay through here like physics.
OnDestroy() When something gets destroyed. Id really recommend not using this except for
memory stuff and making your own function when you destroy stuff, because ondestroy changes
stuff in the editor
OnTriggerEnter/OnTriggerEnter2D(Collider/Collider2D Hit)
These will let you see if a triggers been triggered. Normally in Start youll set some bool triggered;
to false, then set it to true in here if it reaches the right criteria (like in my case Hit.gameObject ==
RudeBear.Bear.gameObject when RB hits something)
OnTriggerStay/OnTriggerExit and 2D versions also exist and work the same. Stay is every fixedupdate
when youre on it.
[[for every part of your object that touched the other object, like the corners or the bottom or
whatever]]
if(contact.normal.y>0.8f){ [[if the y normal of the point (-1 to 1) is above 0.8, as in.. up]]
Easier still if youre dealing with squares that stay upright you can always just do
if(hit.contacts[0].normal.y>0.8f) blah();
or: GameObject blah = Instantiate(GameObject, position, rotation) as GameObject; [[that way you
can fiddle with it after you spawn it]]
Destroy(object,time) destroys after time. You cant destroy transforms. If you Destroy(audioSource)
or something, it will destroy the audio component, not the object. If you want to destroy the object
use blah.gameObject, but a lot of the time you might just want to disable their colliders and stuff.
Application.loadLevel(blah) can load any levels in the build by string name or int id.
Raycast2D and Raycast. This is how you detect clicking on stuff. Dont use it for physics, if someone
recommends that theyre an idiot. Look up RaycastHit as well. Figure it out once and copy and paste
everywhere. Uses layer mask as well which uses bitwise operations, just know that ~18 will avoid
layer 18, ~18&~12 will avoid both. Only use nots everywhere and combine them, dont use
positives.
Input shit:
Input.GetKeyDown(Keycode.A) gets if the letter A was hit down. Use in input. You can use
Input.GetKey to see if its currently down, Input.GetButton/GetButtonUp/GetButtonDown is for your
defined axes.
Input.GetAxis works for axes you define in the inputmanager. This is great for controllers, also works
for keyboard buttons.
Input.GetAxisRaw does the same thing but without bullshit. In Input.GetAxis if you go from the stick
being 100% down to 0% down in a split second, it will gradually change the value from 100 to 0. You
probably want Raw because you want full control.
Theres also like Input.GetMousePosition or something that gives you that. You can get it as a
percentage of the screen by dividing by Screen.width and Screen.height in a new Vector2
Input.GetMouseButton(0 or 1 for left/right). Theres also getmousebuttondown and up. This will
probs involve raycasting
Theres also Touches you can use but fuck mobile amirite. Its easy anyway, its just a foreach loop
through all touches.
Move instantly:
Also Quaternion.LookAt looks in a particular direction, but its not smooth so I prefer to use
lookrotation with slerp.
Move 1/10th of the way to the desired value every fixedupdate (put this in FixedUpdate()). This will
make it look great.
transform.position += (finalposition-transform.position)*0.1f;
How to do it with physics: (THIS IS IMPORTANT IF YOU WANT STUFF TO COLLIDER PROPERLY)
Move smoothly:
Rigidbody2D.velocity += (desiredposition-transform.position)*0.1f/Time.fixedDeltaTime;
Will get there at the right point. You can even just set a desiredposition that you vary with
trigonometry or.. sometimes I use an effectivedesiredposition and then add some trig onto it to
make my fairy fly up and down at the point it wants to be at.
If you do it as *1f it will do it instantly, but because of orders of errors it will end up wiggling round
the point you want. You can fix that using drag or by adding another (velocity*=0.6f) every turn to
stop that from happening if youre using velocities/angvels, so:
Rigidbody2D.velocity *= 0.6f;
Good for kinematic shit, for non kinematic just use drag.
If you want to move 2d rotations by angularvelocity/torque, tweet me and Ill tell you how to not
make the angles fuck up.
IEnumerator myfunction(){
nowdostuff();
i=0;
i++;
StartCoroutine(myfunction());
i++;
i will be 2 by the time myfunction() ends. So dont fiddle with shit that youre using in your coroutine
in the same time. Hell, avoid coroutines where you can, use counter ints in FixedUpdate, but
coroutines can work well for like.. dialogue and shit. Just try not to put your core game logic in there.
[ExecuteInEditMode] -> lets you do stuff in the editor from Start() OnGizmoDraw or whatever its
called and Update(). Use with if(!Application.isPlaying) and #if UNITY_EDITOR #endif, which is a
preprecessor directive that means the bit in between those tags wont compile. You dont want this
stuff running while your game is on.
One more example, making screen fade to black before loading a new level (you can also use
Application.loadLevelAsync to do this more efficiently but Im assuming you dont have unity pro
right now. If you do, figure that out, its not hard. You just declare it and instantly tell it its not
allowed to load, then when youre done tell it it is).
bool fading;
**drag a giant sprite over the entire camera and set the alpha to 0 so its not visible and turn it off
too on Start()]].
void Start(){
fade.enabled=false;
fading=false;
void FixedUpdate(){
if(fading){
fading=false;
Application.loadLevel(1);
Etc.
Theres probably more stuff I forgot that Ill add at some later point but thats the vast majority of
the stuff you need to know, and once you can do all this youll know enough to just fiddle with stuff
until you get there anyway.
If you want help with particle systems, tweet me. If you dont know maths dont even bother trying
to code with them, just use the editor settings. If you do, I can probs help you on twitter.