Unity Cheat Sheet
I started learning Unity for fun, and I've decided to keep useful snippets here for future reference.
Free Assets
- Create with code series: low-poly vehicles, animals, foods, props, sky dome, fonts... After importing, you'll have to update Package Manager to avoid some compilation error.
- Standard Assets: terrain, trees, models...
- SpeedTree: once imported, I had this error where my trees would appear all pink. In the console it also said "SpeedTree materials need to be generated.". To do so, click on "Apply & Generate Materials".
C#
Access modifiers
In C#, not setting an access modifier defaults to the most restrictive one. Hence no access modifier in a Class will make its declaration private
.
To make a variable visible in the Unity Inspector, but private in code, use the SerializeField annotation.
[SerializeField] float speed = 5;
Formatting text
string.Format("Time left: {0}s", secondsRemaining)
## format it as a number with 0 decimal.
string.Format("Speed: {0:N0} km/s", speed)
Read more at https://docs.microsoft.com/en-us/dotnet/api/system.string.format and https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings.
GameObjects
- Showing/Hiding:
gameObject.setActive(true/false)
.
Vectors
new Vector3(x, y, z)
// Shorthands
Vector3.down, up, left, right, back, forward
// Normalized
(enemy - player).normalized
// Getting the current object's position
transform.position
Finding things
1) Make a public variable (GameObject) for example. In the Inspector, drag the element into the field.
2) Finding a GameObject by name: GameObject player =
.
GameObject.Find("Player");
2.1) Finding a GameObject by tag: GameObject player = GameObject.FindGameObjectWithTag("Player");
.
3) Finding a GameObject's own Component: Rigidbody rigidbody = GetComponent<Rigidbody>();
.
4) Finding a Component (scripts included) in another GameObject: GameManager gameManager =
.
GameObject.Find("Game Manager").GetComponent<GameManager>();
Moving things
No force
# GameObject
transform.position = ...;
transform.position.Translate(...);
transform.position.Rotate(axis, angle);
# Rigidbody
rigidbody.transform.position = some Vector3;
Rigidbody
Apply forces or torques. It can be an impulse or over time.
rigidbody = GetComponent<Rigidbody>();
rigidbody.AddForce(RandomForce(), ForceMode.Impulse);
rigidbody.AddTorque(RandomTorque(), ForceMode.Impulse);
Preventing camera jitter
Apply forces in FixedUpdate
and apply camera movements in LateUpdate
, instead of putting both in the Update
method.
Handling a vehicle using physics
Making it maneuverable
- Preventing the vehicle from randomly tipping over: Replace the MeshCollider with WheelColliders to the wheels.
- Preventing the vehicle from rolling: Place a CenterOfMass child, and set the vehicle's center of mass using that child's position.
- Lastly, the instructor says the force should be applied to the wheels instead of the vehicle itself.
- Also check that the whole Vehicle doesn't have other Colliders. My tank's turret for some reason had two rectangular colliders at the bottom that prevented it from moving.
Checking that it is grounded
Check its WheelColliders.
Creating things
- Make a prefab.
- Declare a public variable to get a reference to it.
- In the Hierarchy window, drag the prefab to the public field you just created. By the way, it does not have to be a GameObject. It can be a ParticleSystem, a Rigidbody, etc.
- Use it in yout script.
public GameObject enemyPrefab;
public ParticleSystem explosionParticle;
// Instantiate an enemy at some position.
Instantiate(enemyPrefab, some position, enemyPrefab.transform.rotation);
// Show a particle effect at the gameObject's current position.
Instantiate(explosionParticle, transform.position, explosionParticle.transform.rotation);
Destroying things
// Destroy itself.
Destroy(gameObject);
Random
Random.Range(min, max)
. Works with ints and floats. For float, max is inclusive. For int, it's exclusive.
Detecting a collision (by collider box)
Let's say you want to detect when your Fruit has dropped down and touched a Sensor. Make sure the Sensor has a Box Collider with Is Trigger set to true, and that your Fruit also has a Box Collider. Then in the Fruit's script:
void OnTriggerEnter(Collider other)
{
// Destroy the fruit if it touches the bottom sensor.
Destroy(gameObject);
}
To do something as long as the collision occurs, use OnTriggerStay
.
Detecting a Rigidbody collision
void OnCollisionEnter(Collision collision)
{
// Do something.
}
Detecting a click
Unity computes that for you, so you can directly override:
void OnMouseDown()
{
...
}
Timers and Delays
The preferred way is to use Coroutines.
// Start the coroutine in a method.
StartCoroutine(SpawnEnemy());
IEnumerator SpawnEnemy() {
while (isGameActive)
{
yield return new WaitForSeconds(spawnRate);
Instantiate(enemyPrefab);
}
}
You can also use Invoke
or InvokeRepeating
. It uses reflection, so it is supposedly much more resource intensive and discouraged.
# Spawn enemies once after 3 seconds.
Invoke("SpawnEnemies", 3);
# Spawn enemies repeatedly. The first wave happens after 2 seconds, then every 3 seconds, it will spawn another one.
InvokeRepeating("SpawnEnemies", 2, 3);
void SpawnEnemies() { ... }
Animations
Creating animations
Source:
- https://learn.unity.com/tutorial/introducing-the-animator.
- https://learn.unity.com/tutorial/control-animation-with-an-animator
Setting up key frames
To make a simple animation, like a chest opening:
- Select the Chest in the Hierarchy.
- Open the Animation window.
- In the Animation window, click the Create button.
- Select the animation's desired fps. 30 is a good value.
- Add the property you want to animate, in this case, Transform, Rotation. This will add the first key frame.
- Click Record.
- Select at what time you want to record the next key frame.
- Change the rotation of the upper part of the chest to simulate opening. This new rotation setting will be recorded in a new key frame at the selected time.
Nice tweaks:
- Look at the curves.
- Select the tangents, move them around.
- If you want the left and right tangent to be separate, set them as Broken.
- You can select points and scale or move them.
Re-timing animations:
- In the Animation window's Dopesheet, select the points to re-time.
- Drag the selected points horizontally.
Triggering events
But it can get messy quick. Instead, in your script, you can use the animation's length.
- Select the time at which the animation should trigger an event.
- Click Add event.
- In the inspector, select which script it should call.
Preventing an animation from looping
- In the Project window, select the animation that's currently looping.
- In the Inspector, disable Loop Time.
Programmatically trigger animations
It is possible to access parameters by name, but it is more efficient to use hashes.
public class EthanScript : MonoBehaviour
{
Animator anim;
// Find a parameter's hash in the default Animator layer.
int jumpHash = Animator.StringToHash("Jump");
// Find a parameter's hash in a nested Animator layer.
int runStateHash = Animator.StringToHash("Base Layer.Run");
void Start ()
{
anim = GetComponent<Animator>();
}
void Update ()
{
float move = Input.GetAxis("Vertical");
// Set a float by name.
anim.SetFloat("Speed", move);
AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
if(Input.GetKeyDown(KeyCode.Space) && stateInfo.nameHash == runStateHash)
{
// Trigger a trigger by hash.
anim.SetTrigger(jumpHash);
}
}
}
Layers
If your animation doesn't show, even if it triggers, check that its weight is not 0.
Override will override what's in the upper layers, while Additive will add to the animation.
Mask certain body parts
Let's say your attack animation overrides the legs from the running animation.
- In the Project window, create a new Avatar Mask, name it Dwarf_lower_body for example.
- Disable what you want to mask. In the screenshot, the instructor masked the root body too, since they want to use the running animation's movement.
Once done, assign it to the Mask field of the Attack Layer.
Note: this particular layer is included in the Create with Code assets, but the name is inverted, you want to use mask_upper.
Rigged animations
Setting up bones
- Click Configure to assign bones, and check muscles (range of motion).
Usually, Mapping, Automap works best.
Tweaking animations
Some animations like walking will move the character, but some may also have some undesired rotation or drift along the X or Y axis. You can offset these by changing a few settings settings.
Adding an extra bone to a humanoid animation
If your character model has extra bones, like a piece of shoulder armor, you can add it to your animation by adding the joint in the Transform list. Once added to the mask, it'll be applied to the other animations too:
UI
Creating Text
In the Hierarchy, Create Object, UI, Text - TextMeshPro.
Dynamically set its content
using TMPro;
public class GameManager : MonoBehaviour
{
public TextMeshProUGUI scoreUI;
void UpdateScore() {
scoreUI.text = "Score: " + score;
}
...
Creating a Button
In the Hierarchy, Create Object, UI, Button - TextMeshPro.
Assigning a listener
1) In the Inspector, select a class, then a public method.
2) Programmatically
Create a Script and assign it to the Button. Then in the Script, add a click listener.
using UnityEngine.UI;
public class DifficultyButton : MonoBehaviour
{
Button button;
void Start() {
button = GetComponent<Button>();
button.onClick.AddListener(SetDifficulty);
}
void SetDifficulty() { ... }
...
Showing/Hiding a Text or Button
Get the UI element's GameObject and make it active or inactive.
// For TextMeshProUGUI
using TMPro;
// For Button
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public TextMeshProUGUI gameOverUI;
public Button restartButtonUI;
void SetVisible(bool visible) {
gameOverUI.gameObject.setActive(visible);
restartButtonUI.gameObject.setActive(visible);
}
...
Alternatively, you can group several UI components into a GameObject, and show/hide it like a regular GameObject.
Restarting a game
using UnityEngine.SceneManagement;
...
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
Mouse (Raycasting & Set cursor)
Create a Layer, call it "Clickable" for example. In the Hierarchy view, assign any object that you want to be clickable to that "Clickable" layer.
Tag the objects so you can decide which cursor to show.
Import cursor textures, then in the inspector, set the texture type to Cursor, to handle alpha values properly.
public class MouseManager : MonoBehaviour {
//Know what objects are clickable
public LayerMask clickableLayer;
//swap cursors per object
//normal cursor
public Texture2D pointer;
//for clickable world objects
public Texture2D target;
public Texture2D doorway;
void Update() {
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 50, clickableLayer.value))
{
bool door = false;
if (hit.collider.gameObject.tag == "Doorway") {
Cursor.SetCursor(doorway, new Vector2(16, 16), CursorMode.Auto);
door = true;
}
else
{
Cursor.SetCursor(target, new Vector2(16, 16), CursorMode.Auto);
}
}
else
{
Cursor.SetCursor(pointer, Vector2.zero, CursorMode.Auto);
}
}
}
Source: https://learn.unity.com/tutorial/prototyping-in-unity-part-1.
Raycasting (continued)
Casting a ray in front of the player:
Ray ray = new Ray(transform.position, transform.forward);
// Draw the line for debugging in the Scene window.
Debug.DrawRay(ray, ray.direction * rayDistance, Color.red);
if (Physics.Raycast(ray, out hit))
{
Debug.Log(hit.distance);
Debug.Log(hit.collider.gameObject);
}
Navmesh
For navigating characters.
Sources:
- https://learn.unity.com/tutorial/prototyping-in-unity-part-1.
- https://docs.unity3d.com/Manual/nav-BuildingNavMesh.html
Setting up the Navmesh
- Window, AI, Navigation.
- Make your walkable and non-walkable objects Static.
- Click Bake.
Excluding the Player
- Make a Player layer.
- Move the Player to that layer.
- In the Navmesh surface, remove the Player layer from Included surfaces.
Excluding a doorway
- Add a Navmesh obstacle Component to the door. Disable Carve.
- Add a Navmesh modifier. Check Ignore from the build.
If I want to make the door shut, and prevent the player from going through, enable Carve. But if the door goes up, it'll no longer carve it, and the player can go through.
Drive the Player
- Add a Navmesh agent component to the Player object.
- In MouseManager, create a serializable UnityEvent<Vector3>.
- Set up a public listener of that type.
- In Update, check that the left button is pressed. If it is, Invoke that listener with the hit position.
- Back to the Hierarchy, Set the Vector3 event listener to Player's Navmesh agent's destination setter.
public class MouseManager : MonoBehaviour
{
public EventVector3 OnClickEnvironment;
public LayerMask clickableLayer;
void Update()
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 50, clickableLayer.value))
{
// Selectively show cursor.
// Fire an event.
if (Input.GetMouseButtonDown(0))
{
OnClickEnvironment.Invoke(hit.point);
}
}
}
}
[System.Serializable]
public class EventVector3 : UnityEvent<Vector3> { }
To prevent the player from going back and forth between the destination, increase the angular speed, to 800 for example.
Add a stopping distance to make it stop before the target. Good for enemies or chests or doors.
More on UnityEvent
Note: the following actually does not work. Gotta find a proper way to do it.
If you want to use UnityEvents to also enable/disable the navMeshAgent, ie the equivalent of setting navMeshAgent.isStopped
to true
or false
, here's how to do it:
- In the code, set up a
public UnityEvent IsStopped;
. Then use it like this:IsStopped.Invoke(true/false);
- In the editor, set the IsStopped event to NavMeshAgent.isStopped (dynamic). Make sure you pick the one at the top in the "Dynamic bool" category, not the one in the "Static Parameters" category.
Support off mesh links (jumping)
When the player jumps down, they cross a "nav mesh link". To make it look like they jump, you have to programmatically disable the agent's autoTraverseOffMeshLink, listen to events when it will traverse an off mesh link, and programmatically set the agent's position over time to look like it's jumping. See snippet of code at https://learn.unity.com/tutorial/the-navmesh-agent-part-1.
Make some areas harder to cross
Source: https://learn.unity.com/tutorial/navmesh-obstacles-and-areas.
- Create a new area.
- Give it a larger cost.
- Select your Grass objects.
- Change its Navigation Area to your new area.
Make a consumable
Make it clickable with the right cursor
Just like the door, but without baking it into the Navmesh.
- Make a GameObject (a Cube for example).
- Assign it to the Clickable layer.
- Create a tag and tag it appropriately.
- In the MouseManager, assign the appropriate cursor based on its tag.
Make it Disappear and have side effects
Use the OnTriggerEnter
method on box collider collision.
NPC behavior
Patrol
- Make an NPC Controller script, assign it to the NPC GameObject.
- In the NPC Controller script, make a
public GameObject[] waypoints
. - Set up empty GameObjects as waypoints in your scene.
- Assign the objects to your NPC's waypoints.
- In the script, make a function that automatically sets the next waypoint as the target. Give it an interval, let's say 10s. Then make another repeating function that sets its NavMeshAgent's destination to that waypoint.
- Another way is to use agent's pathPending and remainingDistance properties to more intelligently decide when to assign the next waypoint. Script below.
Script source: https://learn.unity.com/tutorial/the-navmesh-agent-part-2.
void Update()
{
// If the agent is still moving, do nothing.
if (agent.pathPending)
{
return;
}
if (patrolling) {
if (agent.remainingDistance < agent.stoppingDistance)
{
StartCoroutine(GoToNextPoint());
}
}
else
{
StartCoroutine(GoToNextPoint());
}
}
Attack when spotting the player
One basic way is to compute the distance between the NPC and the player. See below for the second, more advanced way using ray casting.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class NPCController : MonoBehaviour
{
// Every 10s, go to the next patrol point.
public float patrolTime = 10;
public float aggroRange = 10;
public Transform[] waypoints;
int index;
float maxAgentSpeed;
Transform player;
NavMeshAgent agent;
void Awake()
{
agent = GetComponent<NavMeshAgent>();
maxAgentSpeed = agent.speed;
player = GameObject.FindGameObjectWithTag("Player").transform;
InvokeRepeating("Tick", 0, 0.5f);
if(waypoints.Length > 0)
{
InvokeRepeating("AssignNextPatrolPoint", 0, patrolTime);
}
}
void AssignNextPatrolPoint()
{
index++;
if (index == waypoints.Length)
{
index = 0;
}
}
void Tick()
{
agent.destination = waypoints[index].position;
// Walk.
agent.speed = maxAgentSpeed / 2;
if (player != null && Vector3.Distance(transform.position, player.position) < aggroRange)
{
agent.destination = player.position;
// Run.
agent.speed = maxAgentSpeed;
}
}
}
Using ray casting:
// The position of the eye of the NPC.
public Transform eye;
bool CanSee(GameObject target) {
var ray = Ray(eye.position, target.transform.position - eye.position);
RaycastHit hit;
return Physics.Raycast(ray, out hit);
}
Now as the NPC sees the character, you can save it in lastKnownPosition to go to that spot. Later, if the NPC cannot see the character anymore, it will return to patrolling.
NavMesh on non-static elements
Source: https://learn.unity.com/tutorial/navmesh-building-components.
- Download the NavMesh Surface component from GitHub, and import it into your project.
- Add a NavMesh Surface component to your surface. Your surface doesn't have to be static.
- Click Bake.
- Now at runtime, if you modify your surface, the NavMesh will still work.
Then to make some areas more costly to cross:
- In the Nav Mesh Surface, set the Default Area to Grass.
- Select your roads, add a Nav Mesh Modifier component, and select the Area Type to Walkable.
- Bake.
Another option is to use a Nav Mesh Volume. It's easier to set up for areas like non-linear rivers.
Make some areas jumpable
Source: https://learn.unity.com/tutorial/navmesh-building-components.
- Add a NavMesh Link.
- Choose the two points. Cmd+Shift drag to position the points.
- Make the directional or not.
- Select the Area type to choose its cost.
Camera movements
You could programmatically move the camera in UpdateAfter. But a simpler way is to use Cinemachine.
Source:
- https://learn.unity.com/tutorial/final-touches-and-publishing
- https://docs.unity3d.com/Packages/com.unity.cinemachine@2.2/manual/CinemachineVirtualCamera.html
Steps:
- Install the Cinemachine package.
- Open the Cinemachine menu, click Create Virtual Camera.
- Select the Virtual Camera in the Hierarchy.
- Drag the Player into the Virtual Camera's Follow and Look At fields.
- Set Body to Framing Transpose.
- Set Aim to Do Nothing.
- Reset its view with Cmd+Shift+F like a regular camera.
- Adjust the camera distance in Body, Camera distance.
- Now adjust the rectangles to change the following behavior to your liking.
Designing levels
Better just watch the video as it's very visual. https://learn.unity.com/tutorial/level-design-part-1. The process is called grayboxing.
- In Package Manager, import ProBuilder and ProGrids.
- Snap all to grid.
- Optional: Disable lighting recomputation to make it smoother. Window, Rendering, Light Settings, disable Auto Generate.
- New Shape, Cube, Build Cube.
Making a center line edge. Select all the edges of the door, click "Select edge ring". Or set the mode to "Select hidden: on" and drag to select all. Then click "Connect edges".
Holding Shift and drag a surface to extrude it.
Environment assets
- Import models (FBX files), associated textures, and materials.
- Open a material.
- Lock the inspector.
- Browse your textures, and assign each of the 4-5 textures to their corresponding slot in the inspector.
- There might be a shared, detailed normal map for use as secondary normal map, for all similar materials (all stone for example), drag that in too.
- An emission map can make parts of the model glow.
- Now for each model, set its corresponding remapped material, and click Apply.
Lighting
Sources:
- https://learn.unity.com/tutorial/level-design-part-2.
- https://learn.unity.com/tutorial/lighting-overview-part-1
Add lights
- Open Window, Lighting.
- Set Skybox material to black if it's indoors.
- Pick your directional light color. Dark blue for a dungeon.
- Add point lights with orange color for torches. Set shadows to Hard shadows to cast shadows.
Bake light maps
Into what won't move (the environment). This will make objects reflect light onto one another, eg a red wall will emit red light to the statue nearby.
- Set the environment to Static.
- In the lighting tab, enable Global Illumination and Baked Global Illumination.
- Enable Auto Generate or click Generate.
More adjustments to lighting: they also changed the source to Gradient and colors
Make an emissive material
- Add a primitive object.
- Make a Material, called my glow for example.
- Assign the material to the primitive.
- Enable "Emissive".
- Pick a color other than black, and an intensity over 1.
- Make the object static.
- Notice how it will illuminate things around it.
Light probe group
A light probe group will compute global illumination so that dynamic objects receive some approximate light as well. The rule of thumb is to add more probes close to where there is interesting light.
Reflection probes
Useful for scenes with reflective surfaces likes mirrors, metal, rocks and woods.
Add them to the hierarchy and draw the volume inside which it'll reflect. It's ok for probes to overlap. The whole geometry should be covered.
Once done, bake again, this time with Reflection probes.
Without reflection probes
Materials
Source: https://learn.unity.com/tutorial/exploring-maps-and-map-channels
Albedo/Diffuse
Contains the information about the color. It can sometimes also contain an alpha channel. Then in the rendering mode, you can choose how to use that alpha information. For example if a flag is torn around the edges, you want to choose another rendering mode than Opaque. For a flag, Cutout or Fade is appropriate. For something like glass, you want Transparent. This will make it transparent, but still make it cast shadows and reflect light.
Metallic
Makes it more or less metallic. 0 is dull, 1 is like a mirror. You can apply a texture to set the metallic and smoothness values, if you use Source: Metallic Alpha instead of Albedo Alpha. The texture's red channel defines how metallic it is, and its alpha channel defines how smooth it is. That's why those images are usually grayscale.
If you're developing on mobile, you may want to disable forward rendering options for better performance..
Normal maps
A normal map tells the engine in which direction light should bounce off when it hits your surface. This can make your surface look more bumpy without changing your geometry. If you look at it from the side, it'll still appear flat, since you didn't change the geometry.
When importing a normal map, set its texture type to Normal, or hit the "Fix" button.
Height map
That changes your geometry, so that you'll notice some etching on your door even if you see it from the side.
Ambient occlusion
This determines how much shadow an object casts on itself.
For better performance like on mobile, you can use an Albedo texture that has Occlusion info baked in. But then you have less options.
Emission maps
They determine which part of your geometry emits light. Then you can configure what color it emits and at what intensity.
The Emission map texture itself can contain some color information.
To finish, make your object Static so that its emission is taken into account when computing Global Illumination.
Secondary maps
Secondary maps contain noisy textures to make your objet look less flat. They are specifically designed to be tiled, so feel free to change its tiling values.
It's particularly noticeable up close.
Metallic vs Specular
First, check out the charts for realistic albedo, metallic and smoothness values: https://docs.unity3d.com/Manual/StandardShaderMaterialCharts.html.
The Metallic value defines how metallic a component is, so most of its color comes from the Albedo. In Specular, Albedo is mostly ignored, so the color comes from the Specular settings.
They are mostly similar, and it's up to you which to use.
Making maps yourself
Cool tutorial on how the instructor did it in Photoshop.
Shaders
Source: https://learn.unity.com/tutorial/standard-metallic-and-standard-specular
Post-processing
Sources:
- Beginner Fundamentals: Unity Game Dev Course.
- https://learn.unity.com/tutorial/lighting-a-scene-1.
Brings nice visual effects for polish.
- Install the package.
- Two methods. Either create an empty object, add a Post-processing Volume component to it. Or in Project, create a Post-processing profile, then drag it to the camera.
Effects:
- Ambient occlusion is good to improve shadows.
- Bloom is good for making fire particle effects look more lively.
- Anti-aliasing for softer edges.
- Grain to add some texture.
- Vignette darkens the corners. Good to add some feel of mystery.
Sound
Source: https://learn.unity.com/project/unity-audio-fundamentals.
Music
Add an Audio Source. Give it an Audio Clip. Adjust volume.
Sound effect
Upon entering water for example. Create a new script onto your Player Character. Add two variables: an Audio Clip and an Audio Source. OnTriggerEnter, play the sound.
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("water"))
{
audioSource.PlayOneShot(audioClip);
}
}
Create an Audio Source on your Player, and assign it to the script's Audio Source.
For the Audio Source, make sure you set Spatial Blend to 3D, so that it adjusts to where the player is.
Terrain
Source: https://learn.unity.com/project/introduction-to-terrain-editor.
Basics
- Create a terrain.
- Elevate terrain.
- Create layers of texture.
- Paint the layers onto the terrain.
- Import free SpeedTrees.
- Paint trees.
- Paint grass.
Next steps
Use the advanced package "Terrain Toolbox".
Ragdolls
Source: https://learn.unity.com/tutorial/ragdoll-physics.
- Right click in the Hierarchy, create a Ragdoll.
- Assign the bones from your character model to the Ragdoll set up dialog. Look for joints ("Jnt").
- "Shoulder joint" == "arm", "Chest" == "Middle spine"
- Click Create.
- Upon creation, it'll add colliders and Character joint components to the character.
- Disable isKinematic on the character's main Rigidbody. "is Kinematic" means "is controlled by Animation, disable physics".
If the ragdoll looks broken, you'll have to adjust box colliders and joints a bit more yourself.
Disabling Ragdoll mode while the player is alive
- Programmatically disable all child colliders.
- Programmatically enable all child rigidbodies' kinematic.
Enabling Ragdoll mode when they die
- Disable the character's main collider.
- Enable the character's main rigidbody kinematic field.
- Disable the Animator.
- Disable the navmesh agent so they can't move anymore.
- Enable all child colliders.
- Disable all child rigidbodies' kinematic.
Little time savers
Assigning several objects to an array or List in the Hierarchy
Here's how to do it faster than setting the array size to K, then dragging each of the K elements one by one.
- Select the GameObject which array you want to set.
- Lock the inspector.
- Select the K objects you want to assign to the array.
- Drag them to the array field.