-
-
Notifications
You must be signed in to change notification settings - Fork 32
Home
- Is the source project free to use?
- The asteroids are not passing through boundaries
- The player ship is moving off screen
- Nothing happens when a bullet hits an asteroid
- How can I make the player wrap to the other side of the screen?
- How can I customize the movement feel?
- Error: 'Bullet' does not contain a definition for 'Project' ...
- How do I write the "β " symbol in the code?
Yes, you are free to use the project for any purpose. However, keep in mind that copyright and/or trademark laws can still apply to the original material since many of the games in my tutorials were not originally authored by me. I open source my own code for the community to learn from, but the project is intended for educational purposes only.
If your asteroids are unable to pass through the boundaries, then this most likely means the two are objects are colliding, but we actually want collision to be disabled between these objects. To do this, we set the game objects to be on different physics layers so we can turn off collision between the two layers in the physics settings.
The asteroids should have their layer set to "Asteroid" and the boundaries should be set to "Boundary". Make sure to set this on the prefabs if you have them so it applies to all instances of the game object. After doing this, we can go to Edit > Project Settings > Physics 2D
and uncheck collision between Asteroid/Boundary
in the collision matrix.
If your player ship is able to move off screen, this implies no collision is being detected between the ship and the boundaries. There could be a couple different reasons for this.
Collision can be enabled/disabled for different layers by changing the collision matrix found in Edit > Project Settings > Physics 2D
. The player ship should have its layer set to "Player" and the boundaries should be set to "Boundary". Make sure the checkbox for Player/Boundary
collision is enabled in the collision matrix. It should already be enabled by default.
Another possible cause could be that either the boundaries or the player ship's collider has the "Is Trigger" property checked on. Any object that is set to be a trigger will detect collisions with other objects but won't affect the actual physics simulation. We want the objects in this game to not be triggers.
If you are still having problem with collision, make sure your player ship has a Rigidbody2D
component attached to it. For collision to work between any two objects, at least one of them must be a rigidbody.
In the Asteroid.cs
script, the code is checking when the asteroid collides with a bullet by comparing the tag of the incoming object. If nothing is happening when a bullet collides with an asteroid, it might be that you have forgotten to set the tag of your bullet prefab to "Bullet", or there could simply be a mistake in the name or spelling.
It is also possible that you are comparing the name of the incoming game object rather than the tag, gameObject.name
vs gameObject.tag
. It's generally a better practice to use tags over names.
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Bullet"))
{
//...
}
}
Alternatively, your objects might be missing a Rigidbody2D
component, without which collisions will not occur. Make sure the collider components do not have the "Is Trigger" property checked on. Lastly, verify the collision matrix in Edit > Project Settings > Physics 2D
has collision enabled for the Asteroid/Bullet
layers.
Source code: https://github.com/zigurous/unity-asteroids-tutorial/blob/wrapping/Assets/Scripts/Player.cs
The simplest way to achieve this is to check the position of the player and move them to the opposite side if they are beyond the bounds of the screen. Before jumping into the code, we simply need to delete or disable the "Boundary" game objects in our scene otherwise the player won't be able to move past the screen bounds to trigger the wrapping.
First, we need to determine what the world-space coordinates are for the edge of the screen. In the Player.cs
script we can add a new variable to keep track of these bounds.
private Bounds screenBounds;
Then, in the Awake
function we can convert the screen-space coordinates to world-space coordinates and encapsulate those points in the bounds. We encapsulate two points: one for the top-left corner (min) and one for the bottom-right corner (max).
private void Awake()
{
//...
screenBounds = new Bounds();
screenBounds.Encapsulate(Camera.main.ScreenToWorldPoint(Vector3.zero));
screenBounds.Encapsulate(Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0f)));
}
Lastly, in the FixedUpdate
function we check the position of the player to see if they are beyond the bounds and if so we change the position to the opposite side. We offset each screen bounds point by half a unit (0.5) because the position of the player is in the center of the object, so this ensures the player is entirely off the screen before wrapping to the other side.
private void FixedUpdate()
{
//...
if (rigidbody.position.x > screenBounds.max.x + 0.5f) {
rigidbody.position = new Vector2(screenBounds.min.x - 0.5f, rigidbody.position.y);
} else if (rigidbody.position.x < screenBounds.min.x - 0.5f) {
rigidbody.position = new Vector2(screenBounds.max.x + 0.5f, rigidbody.position.y);
} else if (rigidbody.position.y > screenBounds.max.y + 0.5f) {
rigidbody.position = new Vector2(rigidbody.position.x, screenBounds.min.y - 0.5f);
} else if (rigidbody.position.y < screenBounds.min.y - 0.5f) {
rigidbody.position = new Vector2(rigidbody.position.x, screenBounds.max.y + 0.5f);
}
}
Make sure to delete or disable the "Boundary" game objects in your scene otherwise the player won't be able to move past the screen bounds.
Since we are using rigidbodies for this game, the movement feel can be fully customized to your preference. I chose to make the game feel "floaty" as I thought that was appropriate for space, but others might want the game to feel more "snappy".
By changing properties on the rigidbodies, as well as the player script, you can customize the feel of the game. For example, the Linear Drag
property on the Rigidbody2D
component changes how quickly the object comes to a stop. A higher value will make the object come to a stop quicker, making the game feel more "snappy". Same thing for the Angular Drag
property in regards to rotation.
The Mass
property can also be changed. A heavier object requires more input to move the object. After changing some of the rigidbody properties, you may need to change the speed variables on the Player script to compensate. Try the following values to make the game more "snappy".
- Mass: 1
- Linear Drag: 100
- Angular Drag: 100
- Thrust Speed: 200
- Rotation speed: 15
This error implies that you are trying to call the function Project
that is defined in the Bullet
class, but it can't find the function. Most likely it is because you have not marked the function as public
. In order to call a function from a different class than where it is declared, the function must be considered public rather than private. This programming mechanism is called "scope" and allows us to control who has and does not have access to certain members of a class.
If this is not the problem, it might just be a simple typo between the name of the function where its declared vs the name used when calling it. Verify both are exactly the same, case-sensitive.
In the video I had font ligatures turned on in my editor which displays certain character combinations differently. This is something I've turned off for future videos to prevent confusion for those who aren't familiar with it. The β
symbol is actually written as !=
, which means "not equal".