# Unity

# Project Settings

At first when opening the Unity editor I was a bit overwhelmed by the many options available, and it can be hard to get going without at least knowing how to configure the most basic of settings for a Unity project. In the sections below, I'll cover some simple settings that are worthwhile to consider when creating a new project in Unity.


### Playmode Tint

This option is not found in `Project Settings`, but I think it is something everyone entering into Unity for the first time should consider. Navigate to the menu bar at the top of your editor and select `Edit->Preferences->Colors` and adjust the `Playmode Tint` to something very noticable. This will avoid forgetting you are in play mode and making some changes, only to be forced to revert them all once exiting play mode.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591544219505.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591544219505.png)

For the rest of these sections, we will be working in the `Project Settings` panel opened with `Edit->Project Settings...` in the menu bar of the Unity editor.

[Official Unity Project Settings Documentation](https://docs.unity3d.com/Manual/comp-ManagerGroup.html)

### Project Name

It is not to be assumed that Unity will distribute builds of your game with your local Unity project name as you defined it when creating your project initially. In fact, Unity requires us to specify these details within the `Player` section of `Project Settings`. See the section below is adjusted to suit the needs of your project.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591541753961.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591541753961.png)

### Game / Application Icons

It's important to change things like this from the default settings, otherwise even a finished project can end up looking incomplete. Navigate to the `Player` section and scroll down to adjust icon settings. It's important to be consistent across all platforms, and this can easily be done by checking the `Override for PC, Max & Linux Standalone` tick box at the top of the panel. This will apply your Icon settings on all platforms.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591540882097.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591540882097.png)


### Splash Screen

*This is for Unity Professional Licenses only*

Within the `Player` panel we can find the below settings for modifying the splash screen of a game or application created with Unity.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591541034571.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591541034571.png)

### Quality Settings

It's important to adjust quality settings to suit your development environment so you aren't running your game within the Unity editor in max settings.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591541213761.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591541213761.png)

You can rename quality levels, add new, and adjust platform-specific modes as well. It's important to note that clicking the name of the quality setting in this table (just left of the check-marks) will apply the settings within your editor for testing. The `Default` drop-down arrors correspond with each platform at the top level of the table. 



### Graphics Settings

This is where you'll define the preconfigured graphics settings available to the player. Its important to adjust these to suit the platform the build will be running on. As an example, this feature could be useful when trying to distribute a test build of a Unity game with WebGL. We could reduce the settings to improve performance within the browser to make the game much less demanding. This allows us to build more efficiently to WebGL and not create an unecessarily demanding or slow performing game given this basic platform of WebGL.

Curious what WebGL is or looks like in use? I host some archived examples on my website, [click here](https://shaunreed.com/2017/02/26/webgl/) to check out some Unity WebGL games that I've already built and hosted online for playing. 

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591542267619.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591542267619.png)


### Input Manager

This section is very useful in configuring controls for your game that can then be used for scripting. For example, the section below I have defined a button for `Fire`, which is triggered when the player clicks the left mouse button

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591542336677.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591542336677.png)


By using a custom script that defines global constants, we can reduce the task of changing these values later on. Below, I'll cover an example of using the `Input Manager` paired with a few C# scripts to define controls in global variables which can be easily modified in a central location. This avoids a scenario where we have built a complex game and want to change controls later in development, requiring us to change static values across numerous scripts. This is not only tedious but also makes the project more prone to errors.

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Controls : MonoBehaviour
{
    // Constants used within the game to handle passing control settings to builtin unity functions with string parameters
    // Unity parses these strings against settings in Edit->ProjectSettings->InputSettings

    // Character walking controls for joystick / keyboard
    // Keyboard has boolean movement, joystick has variable 0.0f - 1.0f
    public const string c_MoveStrafe = "Horizontal";
    public const string c_MoveWalk = "Vertical";

    // Character look controls for mouse / joystick
    public const string c_LookMouseVertical = "Mouse Y";
    public const string c_LookMouseHorizontal = "Mouse X";
    public const string c_LookGamePadVertical = "Look Y";
    public const string c_LookGamePadHorizontal = "Look X";

    // Character movement modifiers
    public const string c_ModJump                    = "Jump";
    public const string c_ModSprint                  = "Sprint";
    public const string c_ModCrouch                  = "Crouch";
    
    // Character weapon controls
    public const string c_PrimaryAim                     = "Aim";
    public const string c_PrimaryGamepadAim              = "Gamepad Aim";
    public const string c_PrimaryFire                    = "Fire";
    public const string c_PrimaryGamepadFire             = "Gamepad Fire";
    public const string c_PrimarySwitchWeapon            = "Mouse ScrollWheel";
    public const string c_PrimaryGamepadSwitchWeapon     = "Gamepad Switch";
    public const string c_PrimaryHide              = "Primary Hide";
    public const string c_PrimaryNextWeapon              = "NextWeapon";
    
    // UI controls
    public const string c_UIPauseMenu               = "Pause Menu";
    public const string c_UISubmit                  = "Submit";
    public const string c_UICancel                  = "Cancel";
}
```

These constants can then be used in a relative `PlayerInput` class, which can handle recieving input from the player at a higher level so we won't need to refactor all of our scripts in the scenario that we want to modify our controls.

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// A script to pass player input to a relative GameObject's Controller script

public class PlayerInput : MonoBehaviour
{

    PlayerController playerController;

    // Start is called before the first frame update
    void Start()
    {
        playerController = GetComponent<PlayerController>();
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    // Update is called once per frame
    void Update()
    {
        // Always check if the player wants to unbind their cursor lock state
        UpdateLockState();
    }

    public bool CanProcessInput()
    {
        // If the cursor is locked within the game, return true
        return Cursor.lockState == CursorLockMode.Locked;
    }

    public Vector3 GetMovement() 
    {
        // If the cursor is not locked within the game, do nothing
        if (!CanProcessInput()) return Vector3.zero;
        
        // Create a file / class (Controls.cs) to hold strings which can be passed to functions in all scripts
        // Allows for easy control customization without reefactoring a lot of code
        // GetAxis returns 0.0f-1.0f strength of movement (allows joystick variable movement, keyboard movement is 1.0f if key pressed)
        // Horizontal = a,d     Vertical = w,s
        Vector3 move;
        switch(playerController.targetPov)
        {
            case Kamera.pov.Mounted:
            move = transform.forward * Input.GetAxis(Controls.c_MoveStrafe) * -1.0f  + transform.right * Input.GetAxis(Controls.c_MoveWalk) * 1.0f ;
            break;

            default:
            move = transform.right * Input.GetAxis(Controls.c_MoveStrafe) + transform.forward * Input.GetAxis(Controls.c_MoveWalk);
            break;
        }
        // Return the clamped amnount of movement to apply to a GameObject within some relative Controller script
        return move;
    }

    public float GetLookHorizontal()
    {
        return GetLookAxis(Controls.c_LookMouseHorizontal, Controls.c_LookGamePadHorizontal);
    }

    public float GetLookVertical()
    {
        return GetLookAxis(Controls.c_LookMouseVertical, Controls.c_LookGamePadVertical);
    }

    // If the player presses the UICancel key, the cursor is unlocked.
    void UpdateLockState()
    {
        if (Input.GetButton(Controls.c_UICancel)) Cursor.lockState = CursorLockMode.None;
        else if (Input.GetMouseButton(0)) Cursor.lockState = CursorLockMode.Locked;
    }

    // Checks whether the look input is via mouse or gamepad and returns a float 0.0f-1.0f of the strength 
    float GetLookAxis(string mouseLook, string stickLook)
    {
        if (CanProcessInput())
        {
            
            // Check if there is any input from a gamepad controller on the given axis
            bool isGamePad = Input.GetAxis(stickLook) != 0.0f;
            // If we are using a gamepad use stickLook's strength, otherwise use mouse input
            float str = isGamePad ? Input.GetAxis(stickLook) : Input.GetAxis(mouseLook);

            if (isGamePad)
            {
                // since mouse input is already deltaTime-dependant, only scale input with frame time if it's coming from sticks
                str *= Time.deltaTime;
            }
            else
            {
                // reduce mouse input amount to be equivalent to stick movement
                str *= 0.01f;
    #if UNITY_WEBGL
    // Mouse tends to be even more sensitive in WebGL due to mouse acceleration, so reduce it even more
                // str *= webglLookSensitivityMultiplier;
    #endif
            }

            return str;
        }
        else return 0.0f;

    }

    public bool GetCrouchDown()
    {
        return Input.GetButtonDown(Controls.c_ModCrouch);
    }
    public bool GetCrouchUp()
    {
        return Input.GetButtonUp(Controls.c_ModCrouch);
    }

    public bool GetSprintHeld()
    {
        return Input.GetButton(Controls.c_ModSprint);
    }

    public bool GetJumpPress()
    {
        return Input.GetButtonDown(Controls.c_ModJump);
    }

    public bool GetMouseFire()
    {
        return Input.GetButtonDown(Controls.c_PrimaryFire) || Input.GetButtonDown(Controls.c_PrimaryGamepadFire);
    }
    
    public bool GetMouseAlt()
    {
        return Input.GetButtonDown(Controls.c_PrimaryAim) || Input.GetButtonDown(Controls.c_PrimaryGamepadAim);
    }

    public bool GetLowerPrimary()
    {
        return Input.GetButtonDown(Controls.c_PrimaryHide);
    }


    public int GetNumberPress()
    {
        if(Input.GetKeyDown(KeyCode.Alpha0)) return 9;
        else if(Input.GetKeyDown(KeyCode.Alpha1)) return 0;
        else if(Input.GetKeyDown(KeyCode.Alpha2)) return 1;
        else if(Input.GetKeyDown(KeyCode.Alpha3)) return 2;
        else if(Input.GetKeyDown(KeyCode.Alpha4)) return 3;
        else if(Input.GetKeyDown(KeyCode.Alpha5)) return 4;
        else if(Input.GetKeyDown(KeyCode.Alpha6)) return 5;
        else if(Input.GetKeyDown(KeyCode.Alpha7)) return 6;
        else if(Input.GetKeyDown(KeyCode.Alpha8)) return 7;
        else if(Input.GetKeyDown(KeyCode.Alpha9)) return 8;
        else return -1;
    }

}
```

If you want to actually be able to apply damage, we need a `Target` script. See the simple example below for a script which enables this to occur. Later, within `WeaponControl.cs`, we will check if the object we hit has this script attached, and if it does we can deal damage to the set HP amount given to the `Target`


```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Target : MonoBehaviour
{

    [SerializeField]
    private float health;

    [SerializeField]
    [Tooltip("If this is true we spawn the broken GameObject on destruction")]
    public bool isDestructable = false;

    [SerializeField]
    [Tooltip("The GameObject to spawn when this object is broken")]
    public GameObject broken;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void TakeDamage(float amount)
    {
        health -= amount;
        if (health <= 0)
        {
            if(isDestructable) Instantiate(broken, gameObject.transform, false);
            Destroy(gameObject);
        }
    }

}
```

We could then use this `PlayerInput.cs` script within a `WeaponControl.cs` script check if the player presses this button in `Update` called once per frame. If they have tried to shoot and have a weapon equipped, we can call the relative weapon's `ShootWeapon()` function. Note that you will have to attach the `playerInput` and `playerWeapons` variables to relative scripts within your editor.

```csharp
public class WeaponControl : MonoBehaviour
{
    [SerializeField]
    PlayerInput playerInput;
    [SerializeField]
    PlayerWeapons playerWeapons;
    [SerializeField]
    public Transform muzzle;
    [SerializeField]
    public GameObject projectile;
    [SerializeField]
    Camera mainCamera;
    [SerializeField]
    ParticleSystem muzzleFlash;
    [SerializeField]
    GameObject hitEffect;
    private float range = 500.0f;
    private float damage = 10.0f;


    void Update()
    {
        if (playerInput.GetMouseFire() && playerWeapons.hasWeapon) ShootWeapon();
    }

	    void ShootWeapon()
    {
        fireSFX.Play();
        GameObject projectileObj = Instantiate(projectile, muzzle.transform.position + mainCamera.transform.forward, mainCamera.transform.rotation);
        projectileObj.GetComponent<Rigidbody>().AddForce(transform.forward * 100);
            
        
        RaycastHit hit;
        if (Physics.Raycast(muzzle.transform.position, mainCamera.transform.forward, out hit, range))
        {
            Target temp = hit.transform.GetComponent<Target>();
            if (temp != null) temp.TakeDamage(damage);


            Debug.Log(hit.transform.name);
            muzzleFlash.Play();
            GameObject hitObject = Instantiate(hitEffect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(hitObject, 1f);

            if (hit.rigidbody != null) hit.rigidbody.AddForce(-hit.normal * hitForce);

        }
    }

}
```

# Scripting

Scripting in Unity uses C# and is very well documented. In the sections below, I'll Provide examples and edge cases where possible, and link to the relative documentation for quick reference.

For a collection of classes and structs that are *required* for Unity to function, which means they will *always* be available to you when scripting in Unity, head over to [UnityEngine.CoreModule Documentation](https://docs.unity3d.com/ScriptReference/UnityEngine.CoreModule.html)


### Transform
This class controls and tracks object position, rotation, scale.

[Official Transform Class Documentation](https://docs.unity3d.com/ScriptReference/Transform.html)




#### Local Space

Local space is the transform relative to the object's parent. An example of this can be seen below where I have selected an object and the transform controls are centralized on the exact transform of that object relative to its local position.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591551913335.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591551913335.png)

Take notice of three things in the above screenshot. First, we have selected `Local` position in the top-left near our transform controls. Clicking this button again will toggle between Local and World space. Second, take note of the World Space axis shown at the top-right of the scene view. Third, in contrast to the World space axis, notice the GameObject's axis shown in the scene view are different in orientation. The transform axis shown on the GameObject are modifying and referring to the GameObject's transform within Local space.

#### World Space

World space is the position of the GameObject rooted within the scene. An example of this is seen in selecting the exact same object in the editor and toggling world space transform view. This makes sure the transform controls are the same as the World Space axis, instead of referring directly to the transform of a local object.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591552157841.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591552157841.png)

Again, take notice of three things in the above screenshot. First, we have selected `Global` position in the top-left near our transform controls. Clicking this button again will toggle between Local and World space. Second, take note of the World Space axis shown at the top-right of the scene view. Third, in contrast to the World space axis, notice the GameObject's axis shown in the scene view are different in orientation. The transform axis shown on the GameObject are modifying and referring to the GameObject's transform within World space.

### Vector3

[Official Vector3 Struct Documentation](https://docs.unity3d.com/ScriptReference/Vector3.html)

#### Axis

In Unity 3D you will use the `X`, `Y`, and `Z` axis frequently both in positioning within the editor and scripting. It helps to have a clear understanding of the names these axis can be referred to with, as it will greatly improve your ability to access and modify these values without over complicating things.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591629600009.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591629600009.png)

The `X` axis can be accessed with the `right` keyword when accessing any class which stores axis information\
The `Y` axis can be accessed with the `Up` keyword when accessing any class which stores axis information\
The `Z` axis can be accessed with the `forward` keyword when accessing any class which stores axis information

Similarly, when modifying a `Vector`, we can easily flip these axis by accessing the opposite of these keywords -\
The `X` negative axis can be accessed with the `left` keyword when accessing any class which stores axis information\
The `Y` negative axis can be accessed with the `down` keyword when accessing any class which stores axis information\
The `Z` negative axis can be accessed with the `back` keyword when accessing any class which stores axis information

So, the `Vector3` equivalents to these would be \
`X` axis, `Vector3(1.0f, 0.0f, 0.0f)`, is equivalent to `right`\
`Y` axis, `Vector3(0.0f, 1.0f, 0.0f)`, is equivalent to `up`\
`Z` axis, `Vector3(0.0f, 0.0f, 1.0f)`, is equivalent to `forward`

`X` negative axis, `Vector3(-1.0f, 0.0f, 0.0f)`, is equivalent to `left`\
`Y` negative axis, `Vector3(0.0f, -1.0f, 0.0f)`,  is equivalent to `down`\
`Z` negative axis, `Vector3(0.0f, 0.0f, -1.0f)`, is equivalent to `back`


### Quaternion

[Official Quaternion Struct Documentation](https://docs.unity3d.com/ScriptReference/Quaternion.html)

###

# Shortcuts

Since Unity has many features and shortcuts available that will widen the gap between an experienced developer and a beginner, I'll list some of my most frequently used shortcuts and tricks here. Though these can all be viewed and modified by opening the panel below in `Edit->Shortcuts...`, there is a huge amount of shortcuts and this can be a lot to look at.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591549322011.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591549322011.png)

### Transform Controls

[Official Positioning Documentation](https://docs.unity3d.com/Manual/PositioningGameObjects.html)

At the top-left of your Unity editor, you'll notice the transform control buttons where you can switch between `Hand`, `Move`, `Rotate`, `Scale`, `Rect`, and `Universal` controls. Each of these can also be toggled by pressing `Q`, `W`, `E`, `R`, `T`, and `Y`, respectively.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591548971392.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591548971392.png)

#### Snapping to Collision

There will be many cases where you want to place an object on a table or ground within your scene. You should not need to manually fumble with axis to do this, but instead given that both objects have collision of some kind you can simply hold `Shift+Ctrl` while using the `Move` tool *and dragging the grey box that appears in the center of the object*, NOT the axis themselves. This will immediately snap the object to the collision nearest to your cursor as you drag it around the scene. There may be minor adjustments needed, but overall this should do the trick for most basic items.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591555254244.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591555254244.png)


### Object to Scene View Transform

You will frequently want to move an object to the position and rotation of your current scene view in World space. You could manually drag the object across the scene in unity, adjusting each axis as needed. Alternatively, you can fly to a position near your desired location for the object, select the object, then press `Shift-Ctrl-F` to move the object to your exact position and rotation. This is *very* useful when setting up cameras, as you can just fly to the view you want the camera to display, select the camera, and press `Shift-Ctrl-F` to set it to that exact position with a lot less fumbling around.

### Unclickable Objects

Tired of clicking in the scene view and selecting the terrain or some other GameObject? Within the scene hierarchy you can toggle whether or not an object should be clickable. Simply click the small hand next to the object's name in the hierarchy.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591557456670.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591557456670.png)

You can also toggle hiding and showing objects by clicking the eye icon just to the left of this setting

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591557501040.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591557501040.png)

# Prefabs

Since the Unity workflow is built around prefabs, I figured I'd document some specific use cases for the many features introduced in the Unity LTS 2019 release which added support for prefab variants and nested prefabs. On this page, I'll cover some good practices and features these prefab features provide.

I'd highly recommend heading over to [devassets.com](http://devassets.com/) to grab some of the assets you see featured across the Unity pages on Knoats. They are entirely free and give you a lot to work with when learning. If you can afford it, I would recommend donating to the developers. Not only does this unlock more assets you can get with the package you donated to, but it shows support to the developer that organized all of these great assets in one place for you to learn with.

### Positioning Prefabs

Being relatively new to Unity, I began by grabbing some assets off the Unity Store. Like most free assets on the store, these did not come entirely assembled for me and required me to work a bit to get things in a state that is usable for even the most basic games. This has been a good learning experience, and required no scripting, so if you are new to Unity and not quite ready to script, doing this will give you experience creating prefabs, working with materials, shaders, lighting, textures, and much more. 

At first when creating a prefab of an object that exists within your scene, you may see something like the below when opening the prefab to edit

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591556270971.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591556270971.png)

This is clearly not the orientation that we expect this `SciFi_Rover` vehicle to have when initially placed in our scene. To fix this, be sure you are editing the prefab in the prefab editor and NOT directly within your scene. Then adjust the transform to be in the orientation desired. 

Below, we see the initial transform settings

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591556400262.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591556400262.png)

First, set all but the `Scale` of your object to `0`. Shown in the screenshot below, there will be many cases that this does not produce the desired results, so we still need to modify the transform further

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591556607873.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591556607873.png)

After making some adjustments, the object's final orientation within the prefab editor is seen below

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591556709523.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591556709523.png)

And the final transform properties of the root GameObject are now much cleaner -

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591556742042.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591556742042.png)

# Post Processing

Good graphics are good. That's why I was excited to find adding Post Processing to my Unity 3D project was not only easy to do, but a huge improvement to the visuals within my scene. This enables common modern graphics features like Motion Blur, Ambient Occlusion, Depth of Field, and more.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591622057414.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591622057414.png)

### Add Post Processing

Post Processing is added to each scene individually, and not a project as a whole. To add this to a Unity 3D project, we first need to add the `Post-process Layer` component to our scene's main camera. Next we'll add a Post Processing Volume that globally effects our entire scene. Then we can add a `PostProcessing_Profile` for our scene and add new visual effects accordingly. 


#### Configuring the Camera
Its important that the camera the player views the game from contains this component. Otherwise, if the player can toggle between a camera which has the `Post-process Layer` and one that does not, they effects gained by post processing will only be rendered in one view and not the other.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591571962826.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591571962826.png)

Once we've added the above component to the scene's main camera, we need to adjust the layer of both this component and our main camera to reflect this. Change to the `Postprocessing` Layer in the `Post-process Layer` component. 

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591572189049.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591572189049.png)

Now change the layer of the camera itself to the `Postprocessing` Layer as well

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591572228339.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591572228339.png)


#### Creating the Volume
Now anywhere within your current scene hierarchy, add an empty GameObject and name it `PostProcessingVolume` or otherwise something relative to your specific scenario. Set this GameObject's layer to `Post Processing`. Select this new GameObject and within the inspector `Add Component->Post-processing Volume` as seen below

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591572363971.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591572363971.png)

At a glance, there is not much here. But once we add a Post Process Profile and finish configuring our scene we will use this component to adjust some pretty neat looking visuals. 

<p class="callout warning">Be sure to apply the <code>Post Processing</code> layer to the Camera and Volume GameObjects within your scene before continuing or the effects will not be applied</p>

##### Creating the Profile

Within the GameObject created for our Volume click `New` to the right of the `Profile` field in the new `Post-processing Volume` component.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591572506570.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591572506570.png)

Unity will automatically create a Post Processing Profile and place it in a directory relative to your scene. Now we can check the `Global` tick box to apply this volume to our entire scene and start adding new effects to our scene!

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591572699575.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591572699575.png)

An example of some effects that I added to my scene to achieve the screenshot at the top of this page

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591572848307.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591572848307.png)

That's it! See the glow coming from the lights in the pictures below for an example of how this can be used to add the Bloom effect to an emissive light source.

**Post Processing on** \
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591817450274.png)](https://www.knoats.com/up7loads/images/gallery/2020-06/image-1591817450274.png)
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591817546494.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591817546494.png)

**Post Processing off** \
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591818011855.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591818011855.png)
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591817973490.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591817973490.png)

# Emission

### Emission Lighting

In my screenshot at the beginning of this page, I have a work light that both emits area light from the light source (bulbs) and shines a spot light. This is done using Emission Lighting and Post Processing Bloom within unity. The combination of the two makes for a GameObject which is pretty realistic, and for this Post Processing is required.

**Post Processing Enabled**\
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591573524472.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591573524472.png)

**Post Processing Disabled**\
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591573467518.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591573467518.png)

#### Defining the Source
First, you'll need to define the source of light emission. For my particular object, the only sources of light are isolated to the two bulbs at the top. It is important in this case to have the needed texture maps to configure emission from the source. Otherwise, you will have to create these texture maps yourself and apply them to the material, defining where the light source is. 

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591573267470.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591573267470.png)

For this GameObject's material, the albedo texture is seen below.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591573674029.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591573674029.png)

It's easy to see the bulb near the center of this texture, but how do we define that area as our source of light? Below we see an Emission Color map, which simply shows the bulb in a lit state.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591573802429.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591573802429.png)

Now we can apply the Emission Color map to our material by checking the `Emission` tick-box and applying this texture in the `Color` field. 

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591573869091.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591573869091.png)

#### Picking Color and Intensity

Now we can adjust the color swatch to the right of this texture as needed to adjust the emission light color. It's important to also adjust the `Intensity` of the color emission here to be relevant to your light source. For a work light, they are ultra bright so I wanted to wash the texture out with an ultra-white glow. Since you would literally be blinded by these things in real life if you were to stare into the bulbs, you would not see details of the light bulb or its material.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591574884784.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591574884784.png)

That's it! See the glow coming from the lights in the pictures below for an example of how this can add visuals to any light source.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591574821468.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591574821468.png)
[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591576507242.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591576507242.png)

### Emission Material
The other scenario here is just creating a new material which is entirely emissive of one color. This is very simple to do and not very practical, so I figured I'd show a more specific example using an Emission Color map. For simplicity though, it may be benficial to start with a simple setup like this just to see that Bloom and Emission is working correctly. Below, I've left a screenshot of an ultra-simple emssive material and the result of applying this to a barrel object within the same scene as my work light, with the same Post Processing configuration.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591574658308.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591574658308.png)

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591574707703.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591574707703.png)

If you are having difficulties with Bloom not appearing or being very faint, try adjusting the Intensity and Threshold of your Post Processing Volume's Bloom effect.

[![](https://www.knoats.com/uploads/images/gallery/2020-06/scaled-1680-/image-1591577123440.png)](https://www.knoats.com/uploads/images/gallery/2020-06/image-1591577123440.png)

# New Input System

### Setup

Using the default configuration for a keyboard&mouse / Gamepad `Input Actions` asset in unity, we can implement universal controls given various input devices.

[![](https://knoats.com/uploads/images/gallery/2021-04/scaled-1680-/image-1618853283926.png)](https://knoats.com/uploads/images/gallery/2021-04/image-1618853283926.png)


<p class="callout info">Issues getting an input device to work? Click <code>Window->Analysis->Input Debugger</code> and at the top-left of the new window select <code>Options->Add Devices Not Listed in 'Supported Devices'</code> and any input device that was not previously working should now be passing input to unity. <br><br>
This was a weird bug for me to figure out, so I thought it was worth a mention. For me, I had to do this in order to get Unity to accept input from my Corsair gaming mouse. I searched up a lot of information on this new input system thinking I was using it wrong, and later found that my mouse was not passing input to unity and my code was correct.</p>

[![](https://knoats.com/uploads/images/gallery/2021-04/scaled-1680-/image-1618853641994.png)](https://knoats.com/uploads/images/gallery/2021-04/image-1618853641994.png)

---

### Use

We can call a specific function from a specific component

Using PlayerInput component->Behavior->Invoke Unity Events -

```C#
  Rigidbody playerRigidbody;
  public PlayerControls controls;
  Vector2 playerVelocity;
  public float playerSpeed = 5.0f;

  void Awake() {
    playerRigidbody = GetComponent<Rigidbody>();
    controls = new PlayerControls();
  }

  void OnEnable() {
    controls.Player.Enable();
  }

  void OnDisable() {
    controls.Player.Disable();
  }

  public void OnMove(InputAction.CallbackContext context) {
    print("Moving: " + context.ReadValue<Vector2>());
    playerVelocity = context.ReadValue<Vector2>();
  }
  
  public void OnLook(InputAction.CallbackContext context) {
    print("Look: " + context.ReadValue<Vector2>());
  }
  
  public void OnFire(InputAction.CallbackContext context) {
    print("Bang");
  }

  void Update()
  {
    playerRigidbody.position += new Vector3(playerVelocity.x * Time.deltaTime * playerSpeed,
      0,
      playerVelocity.y * Time.deltaTime * playerSpeed);
  }

```


Or we can let Unity call functions defined using the naming convention `void On\[ActionName\](InputValue value)`

Using PlayerInput component->Behavior->Send Messages -

```C#
  Rigidbody playerRigidbody;
  public PlayerControls controls;
  Vector2 playerVelocity;
  public float playerSpeed = 5.0f;


  void Awake() {
    playerRigidbody = GetComponent<Rigidbody>();
    controls = new PlayerControls();
  }

  void OnEnable() {
    controls.Player.Enable();
  }

  void OnDisable() {
    controls.Player.Disable();
  }

  public void OnMove(InputValue value) {
    playerVelocity = value.Get<Vector2>();
    print("Moving: " + value.Get<Vector2>());
  }


  public void OnMove(InputValue value) {
    playerVelocity = value.Get<Vector2>();
    print("Moving: " + value.Get<Vector2>());
  }


  void Update()
  {
    playerRigidbody.position += new Vector3(playerVelocity.x * Time.deltaTime * playerSpeed,
      0,
      playerVelocity.y * Time.deltaTime * playerSpeed);
  }

```

Broadcast messages is the same as Send Messages, except broadcasting invokes the same methods on all child objects who have a component with function definitions that match this naming convention.