Neardodge System¶
When we think of Bullet Hell games, we think of a game that rewards the player for playing in a skillful manner. In order to replicate this feeling while playing our game, we wanted to implement a risk-reward factor.
We thought that if we could reward players for nearly dodging enemy attacks, that good players would get more challenged and therefore more rewarded. And so we decided to implement the Neardodging system.
How does it work?¶
Our player has to dodge enemy physical attacks as well as enemy bullets. Typically speaking people want to stay away from attacks as far as possible, since that is the safest way to progress. In order to make gameplay more interesting, we reward the player if they fly close to enemy projectiles by giving them score increases and access to the powerup system.
When flying close to a projectile or enemy, there will be a big triangle about 2.5x the size of the player visible around the player. if an attack is present in this triangle, score and powerup value will go up until there is no more threat in the neardodging field.
Regular player | Player with neardodge active |
In the second image, the white shapes represent enemies, while the bigger grayish triangle represents the neardodging area. Note that there is currently a bug present that offsets the triangle shape. This will be fixed at a later date.
Code¶
As with all Unity/C# scripts, the neardodging system is in its own script called Neardodge.cs. I open up the class with the class name, a connected MonoBehavior script, needed class variables (properties) and a Create() function which will initialize the functionality of the script.
public class Neardodge : MonoBehaviour
{
private Rigidbody2D _rigidbody;
private SpriteRenderer _spriteRenderer;
public Player player;
private LayerMask _detectionMask;
private bool _triggered;
private int _scoreCount;
public static Neardodge Create(Player playerComponent)
{
Neardodge neardodge = new GameObject("Neardodge").AddComponent<Neardodge>();
neardodge.transform.parent = playerComponent.transform;
Triangle neardodgeTriangle = new(0.8f, "neardodgeTriangle");
neardodgeTriangle.GameObject.transform.parent = neardodge.transform;
neardodgeTriangle.GameObject.transform.localPosition = Vector3.zero;
neardodgeTriangle.CreateCollider(neardodge.gameObject, true);
neardodge._rigidbody = neardodge.AddComponent<Rigidbody2D>();
neardodge._rigidbody.isKinematic = true;
neardodge.gameObject.SetLayerByName("Neardodge");
neardodge.player = playerComponent;
neardodge._spriteRenderer = neardodgeTriangle.GameObject.GetComponent<SpriteRenderer>();
neardodge._spriteRenderer.color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
//neardodge._spriteRenderer.color = new Color(1.0f, 1.0f, 1.0f, 0.5f);
neardodge.transform.localScale = new Vector3(2.5f, 2.5f);
neardodge._detectionMask = (1 << LayerMask.NameToLayer("Enemy")) + (1 << LayerMask.NameToLayer("Enemy Bullet"));
return neardodge;
}
. . .
}
Above the Create() are several variables which are used as gateways to access GameObject components outside of the Create() function. Namely ”_rigidbody” and ”_spriteRenderer” are needed to change the look and feel of the visible triangle later in the script.
I first create a new GameObject called “neardodge”, as well as a new Triangle called “neardodgeTriangle”. I then connect the neardodgeTriangle‘s transform to the neardodge‘s transform via c# neardodgeTriangle.GameObject.transform.parent = neardodge.transform;
. This way the big triangle will keep following the smaller player-controlled one.
Next I use the CreateCollider function to make the game recognize that the neardodgeTriangle is something it needs to use collisions on. In addition to that I also give the parent neardodge the RigidBody2D component, to allow the game to recognize that this whole object is collideable.
Since the neardodge is interconnected with the player, Create() requires that a Player object is given in the parameters. This is processed in the c# neardodge.player = playercomponent
section. The player that the neardodge is connected to is then saved in the neardodge.player variable.
The neardodge._spritRenderer section is what gives the big triangle its look and partial fade. Currently not visible because of the solid black background, but its seethrough.
In the neardodge.transform.localScale you manipulate