Roll-a-Ball (Unity): различия между версиями
Перейти к навигации
Перейти к поиску
(не показано 17 промежуточных версий этого же участника) | |||
Строка 4: | Строка 4: | ||
=== Create a new Unity project === | === Create a new Unity project === | ||
# Login | # Login | ||
− | # New Project - Universal Render Pipeline | + | # New Project - 3D (URP) - Universal Render Pipeline |
− | + | ||
=== Create a new Scene === | === Create a new Scene === | ||
# Layout | # Layout | ||
Строка 32: | Строка 32: | ||
# Game view | # Game view | ||
# Directional light - set color to white | # Directional light - set color to white | ||
+ | # Directional light rotation: x-50 y-50 z-0 | ||
=== Add colors with Materials === | === Add colors with Materials === | ||
Строка 38: | Строка 39: | ||
# Create player material - 0/220/255 - metallic - 0 / smoothness - 0.75 | # Create player material - 0/220/255 - metallic - 0 / smoothness - 0.75 | ||
# Drag material to object | # Drag material to object | ||
− | |||
== Moving the player == | == Moving the player == | ||
Строка 66: | Строка 66: | ||
=== Apply input data to the Player === | === Apply input data to the Player === | ||
+ | In PlayerController | ||
+ | <syntaxhighlight lang="c#" line> | ||
Vector2 movementVector = movementValue.Get<Vector2>(); | Vector2 movementVector = movementValue.Get<Vector2>(); | ||
private Rigidbody rb; | private Rigidbody rb; | ||
+ | </syntaxhighlight> | ||
In Start function | In Start function | ||
+ | <syntaxhighlight lang="c#" line> | ||
rb = GetComponent<Rigidbody>(); | rb = GetComponent<Rigidbody>(); | ||
+ | </syntaxhighlight> | ||
Add FixedUpdate() function | Add FixedUpdate() function | ||
=== Apply force to the Player === | === Apply force to the Player === | ||
+ | <syntaxhighlight lang="c#" line> | ||
private float movementX; | private float movementX; | ||
private float movementY; | private float movementY; | ||
+ | </syntaxhighlight> | ||
In OnMove | In OnMove | ||
+ | <syntaxhighlight lang="c#" line> | ||
movementX = movementVector.x; | movementX = movementVector.x; | ||
movementY = movementVector.y; | movementY = movementVector.y; | ||
+ | </syntaxhighlight> | ||
In FixedUpdate | In FixedUpdate | ||
+ | <syntaxhighlight lang="c#" line> | ||
Vector3 movement = new Vector3(movementX, 0.0f, movementY); | Vector3 movement = new Vector3(movementX, 0.0f, movementY); | ||
rb.AddForce(movement); | rb.AddForce(movement); | ||
+ | </syntaxhighlight> | ||
=== Fix the Player movement speed === | === Fix the Player movement speed === | ||
− | public float speed = | + | <syntaxhighlight lang="c#" line> |
+ | public float speed = 10; | ||
rb.AddForce(movement * speed); | rb.AddForce(movement * speed); | ||
− | speed in Editor | + | </syntaxhighlight> |
+ | |||
+ | * speed in Editor | ||
== Moving the camera == | == Moving the camera == | ||
Строка 100: | Строка 114: | ||
=== Write a CameraController script === | === Write a CameraController script === | ||
Create CameraController script for camera | Create CameraController script for camera | ||
+ | <syntaxhighlight lang="c#" line> | ||
public GameObject player; | public GameObject player; | ||
private Vector3 offset; | private Vector3 offset; | ||
+ | </syntaxhighlight> | ||
In Start function calculate offset | In Start function calculate offset | ||
+ | <syntaxhighlight lang="c#" line> | ||
offset = transform.position - player.transform.position; | offset = transform.position - player.transform.position; | ||
+ | </syntaxhighlight> | ||
Update functions order undefined so we use LateUpdate | Update functions order undefined so we use LateUpdate | ||
In LateUpdate function | In LateUpdate function | ||
+ | <syntaxhighlight lang="c#" line> | ||
transform.position = player.transform.position + offset; | transform.position = player.transform.position + offset; | ||
+ | </syntaxhighlight> | ||
=== Reference the Player GameObject === | === Reference the Player GameObject === | ||
Строка 131: | Строка 151: | ||
# Scale 0.5 | # Scale 0.5 | ||
# Rotate 45 45 45 | # Rotate 45 45 45 | ||
− | # Material Pickup color 255 200 0 | + | # Material Pickup color 255 200 0 - metallic 0 / smoothness - 0.25 |
=== Rotate the PickUp GameObject === | === Rotate the PickUp GameObject === | ||
Строка 137: | Строка 157: | ||
Remove Start function | Remove Start function | ||
in Update function | in Update function | ||
+ | <syntaxhighlight lang="c#" line> | ||
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime); | transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime); | ||
+ | </syntaxhighlight> | ||
=== Make PickUp a Prefab === | === Make PickUp a Prefab === | ||
Строка 150: | Строка 172: | ||
== Detecting Collisions with Collectibles == | == Detecting Collisions with Collectibles == | ||
=== Disable PickUps with OnTriggerEnter === | === Disable PickUps with OnTriggerEnter === | ||
+ | <syntaxhighlight lang="c#" line> | ||
PlayerController create OnTriggerEnter(Collider other) | PlayerController create OnTriggerEnter(Collider other) | ||
other.gameObject.SetActive(false); | other.gameObject.SetActive(false); | ||
+ | </syntaxhighlight> | ||
=== Add a tag to the PickUp Prefab === | === Add a tag to the PickUp Prefab === | ||
Строка 158: | Строка 182: | ||
=== Write a conditional statement === | === Write a conditional statement === | ||
+ | <syntaxhighlight lang="c#" line> | ||
OnTriggerEnter | OnTriggerEnter | ||
if (other.gameObject.CompareTag("PickUp")) | if (other.gameObject.CompareTag("PickUp")) | ||
+ | </syntaxhighlight> | ||
=== Set the PickUp Colliders as triggers === | === Set the PickUp Colliders as triggers === | ||
Строка 172: | Строка 198: | ||
=== Store the value of collected PickUps === | === Store the value of collected PickUps === | ||
PlayerController | PlayerController | ||
+ | <syntaxhighlight lang="c#" line> | ||
private int count; | private int count; | ||
+ | </syntaxhighlight> | ||
Start function | Start function | ||
+ | <syntaxhighlight lang="c#" line> | ||
count = 0; | count = 0; | ||
+ | </syntaxhighlight> | ||
OnTriggerEnter | OnTriggerEnter | ||
+ | <syntaxhighlight lang="c#" line> | ||
count++; | count++; | ||
+ | </syntaxhighlight> | ||
=== Create a UI text element === | === Create a UI text element === | ||
Строка 191: | Строка 223: | ||
=== Display the count value === | === Display the count value === | ||
PlayerController | PlayerController | ||
− | + | <syntaxhighlight lang="c#" line> | |
+ | using TMPro; | ||
public TextMeshProUGUI countText; | public TextMeshProUGUI countText; | ||
+ | </syntaxhighlight> | ||
new function SetCountText | new function SetCountText | ||
+ | <syntaxhighlight lang="c#" line> | ||
countText.text = "Count: " + count.ToString(); | countText.text = "Count: " + count.ToString(); | ||
+ | </syntaxhighlight> | ||
Add SetCountText() to Start and OnTriggerEnter | Add SetCountText() to Start and OnTriggerEnter | ||
Строка 205: | Строка 241: | ||
=== Create a game end message === | === Create a game end message === | ||
new TextMeshPro | new TextMeshPro | ||
− | Text - Black size 32 | + | # Text - Black size 32 |
− | Set Text - You win! | + | # Set Text - You win! |
− | PosX = 0 posY = 130 | + | # PosX = 0 posY = 130 |
− | Align center | + | # Align center |
Add reference to text as GameObject | Add reference to text as GameObject | ||
+ | |||
Disable in Start function - SetActive(false); | Disable in Start function - SetActive(false); | ||
In SetCountText function | In SetCountText function | ||
− | if (count >= 12) { | + | <syntaxhighlight lang="c#" line> |
+ | if (count >= 12) | ||
+ | { | ||
+ | winText.gameObject.SetActive(true); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
Drop WinText in script | Drop WinText in script | ||
Строка 220: | Строка 262: | ||
== Build the Game == | == Build the Game == | ||
=== Create a build of your game === | === Create a build of your game === | ||
− | Save ALL | + | # Save ALL |
− | Build Settings | + | # Build Settings |
− | For web build 2020 disable compression | + | # For web build 2020 disable compression |
− | Choose platform | + | # Choose platform |
− | Add open scenes | + | # Add open scenes |
− | Scenes list | + | # Scenes list |
− | Player settings | + | # Player settings |
− | Full screen or windowed | + | # Full screen or windowed |
Текущая версия на 16:33, 8 августа 2022
Setting up the Game
Create a new Unity project
- Login
- New Project - 3D (URP) - Universal Render Pipeline
Create a new Scene
- Layout
- All files in "Template" folder
- File - New scene
- File - Save as - Minigame (Scenes folder)
Create a primitive plane
- Add GameObject - Plane
- Rename "Ground"
- Reset transform
- F to focus
- Grid settings
Scale the Ground plane
- Scale x-2 y-1 z-2
Create a player GameObject
- Add GameObject - Sphere
- Reset transform
- F to focus
- Unity unit - 1 meter
- Elevate Sphere y +0.5
Adjust the default lighting
- Game view
- Directional light - set color to white
- Directional light rotation: x-50 y-50 z-0
Add colors with Materials
- Create materials folder
- Create background material - 130/130/130 - metallic - 0 / smoothness - 0.25
- Create player material - 0/220/255 - metallic - 0 / smoothness - 0.75
- Drag material to object
Moving the player
Add a Rigidbody to the player
- Add physics component to player - Rigidbody
Install the Input System package
- Window - Package manager - Input system - Install
- Enable new backend system - Yes
- (Windows only) File - Build settings - Architecture - x86_64
Add a Player Input component
- Add Player Input component to player
- Create Input actions - "Create actions" button
- Create "Input" folder - save action "InputActions"
- In Player Input - Actions field choose created Asset
Create a new script
- Create "Scripts" folder
- Add "PlayerController" script to player
Write the OnMove function declaration
- Remove Update function
- Namespaces
- Add namespace "UnityEngine.InputSystem"
- Create OnMove function (InputValue movementValue)
Apply input data to the Player
In PlayerController
1 Vector2 movementVector = movementValue.Get<Vector2>();
2
3 private Rigidbody rb;
In Start function
1 rb = GetComponent<Rigidbody>();
Add FixedUpdate() function
Apply force to the Player
1 private float movementX;
2 private float movementY;
In OnMove
1 movementX = movementVector.x;
2 movementY = movementVector.y;
In FixedUpdate
1 Vector3 movement = new Vector3(movementX, 0.0f, movementY);
2 rb.AddForce(movement);
Fix the Player movement speed
1 public float speed = 10;
2 rb.AddForce(movement * speed);
- speed in Editor
Moving the camera
Set the Camera position
- Set camera position x=0 y=10 z=-10
- Rotate x=45 y=0 z=0
- Camera child of Player but will rotate with it
Write a CameraController script
Create CameraController script for camera
1 public GameObject player;
2 private Vector3 offset;
In Start function calculate offset
1 offset = transform.position - player.transform.position;
Update functions order undefined so we use LateUpdate In LateUpdate function
1 transform.position = player.transform.position + offset;
Reference the Player GameObject
- Drag player into player slot of the camera script
Setting up the Play Area
Create a wall for the play field
- Create empty object as root for Walls
- Create Cube as West/East/North/South walls
- Scale x=0.5 y=2 z=20.5
- Position -10
- New Material Walls - 79/79/79 - metallic 0 / smoothness - 0.25
Finish the play field walls
- Duplicate object
- Rotate or rescale
Creating collectibles
Create a collectible GameObject
- Add cube
- Move up 0.5
- Scale 0.5
- Rotate 45 45 45
- Material Pickup color 255 200 0 - metallic 0 / smoothness - 0.25
Rotate the PickUp GameObject
Add Rotator script to pickup Remove Start function in Update function
1 transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
Make PickUp a Prefab
- Create Prefabs folder
- Open Prefab edit mode
Add more collectibles
- New Empty Object - PickupParent
- Reset transform
- Duplicate Pickup and move
Detecting Collisions with Collectibles
Disable PickUps with OnTriggerEnter
1 PlayerController create OnTriggerEnter(Collider other)
2 other.gameObject.SetActive(false);
Add a tag to the PickUp Prefab
- Add Pickup tag to PickUp Prefab
- Create & Apply
Write a conditional statement
1 OnTriggerEnter
2 if (other.gameObject.CompareTag("PickUp"))
Set the PickUp Colliders as triggers
Set Pickup Collider prefab as IsTrigger
Add a Rigidbody to the PickUp Prefab
- Add to improve performance
- Disable Use Gravity
- Check IsKinematic - no Physics
Displaying Score and Text
Store the value of collected PickUps
PlayerController
1 private int count;
Start function
1 count = 0;
OnTriggerEnter
1 count++;
Create a UI text element
- Add UI => Text - TextMeshPro
- Import TMP Essentials
- All UI in Canvas
- Rename New Text CountText
- Add CountText as placeholder
- Anchor text left top with Alt + Shift
- PosX = 10 PosY = -10
Display the count value
PlayerController
1 using TMPro;
2 public TextMeshProUGUI countText;
new function SetCountText
1 countText.text = "Count: " + count.ToString();
Add SetCountText() to Start and OnTriggerEnter
Drop Text object to script
EventSystem push "Replace with InputSystemUIInputModule"
Create a game end message
new TextMeshPro
- Text - Black size 32
- Set Text - You win!
- PosX = 0 posY = 130
- Align center
Add reference to text as GameObject
Disable in Start function - SetActive(false);
In SetCountText function
1 if (count >= 12)
2 {
3 winText.gameObject.SetActive(true);
4 }
Drop WinText in script
Build the Game
Create a build of your game
- Save ALL
- Build Settings
- For web build 2020 disable compression
- Choose platform
- Add open scenes
- Scenes list
- Player settings
- Full screen or windowed