Creating a Da○saba○ber (No. 2)
![]()
table of contents
I don't think we kept you waiting too long this time.
This is Matsuyama from the Systems Development Department.
We are now bringing you the second installment of "Creating a Da○saba○bar," which began abruptly from the last issue
The first issue is here ↓
In the first issue, we displayed the player, enemies, and field, and implemented the ability to move the player
I think the appeal of "Da○saba○ber" is the exhilaration of defeating large numbers of zombies with a wide variety of weapons, so I plan to implement weapons in the second issue
Weapon type
However, it would take too much time and effort to implement all of the numerous weapon types, so for now I'll narrow it down to about three types
① Shotgun (default weapon)
② Brick
③ Guardian
Around here
As usual, I searched for images that could be used as resources from Undead Survivor and used them
① There was a shotgun, exactly as described
. ② There are no bricks. I have farming tools, so I think I'll throw a plow.
③ There are no disc-shaped Guardians either. I'll swing a sickle around.

Shotgun
Identify the requirements
① Fires in the direction the player is facing (direction of movement)
② The number of bullets fired increases with level
③ The firing interval decreases with level
④ The range increases with level
⑤ If a zombie is nearby, fires towards the zombie (auto-aim)
⑥ The bullets fly in the direction of ① for a certain period of time and then disappear
⑦ Bullets do not penetrate zombies if they hit them
It was surprisingly common
Steps ① through ⑤ describe the process leading up to firing (Weapon_1).
Steps ⑥ through ⑦ describe the bullet process (Bullet).
Therefore, we will separate them into different classes.
Weapon_1 will generate a Bullet, and the idea is that the fired Bullet will move on its own and disappear.
Basically, you get the player's orientation from the Player class and determine the reference line of fire.
Then, by rotating the line of fire by ±n° relative to the starting point (player coordinates) according to the number of bullets, you can scatter the bullets in a fan shape.

These parameters are provided for control purposes
// Bullet firing interval (3 levels) private readonly float[] interval = { 1.5f, 1.25f, 1.0f }; // Bullet range (3 levels) private readonly float[] range = { 4.0f, 6.0f, 8.0f }; // Number of simultaneous shots (3 levels) private readonly int[] simultaneous = { 1, 3, 5 }; // Firing angle (5 directions: depends on the number of simultaneous) private readonly float[] angle = { 0, 10, -10, 20, -20 };
For point ⑤,
the EnemyController class is used to search for nearby zombies.
If found, the vector between the player coordinates and the zombie coordinates becomes the line of fire.
The bullet scattering is the same as described above.
After firing a bullet, the Bullet class moves autonomously. If
it moves and hits a zombie, a collision detection is obtained, and it can create a state where it cannot penetrate by deleting its own object.
Even if it doesn't hit, it will still delete itself after a certain period of time.
And so, the shotgun is complete.
Here are the finished products:
Level 1

, Level 2

, Level 3

Brick (plow)
① Throw it upwards.
② It falls in an arc from a certain height.
③ It is deleted when it has finished falling (off-screen).
④ It penetrates zombies even if it hits them (but only up to 3).
⑤ The number of throwing opportunities increases depending on the level. (Throw with a time delay.)
We'll use a class structure similar to a shotgun.
Weapon_2 will generate a Plow. The Plow will then fly in a parabolic arc.
The enemy's position doesn't really matter.
The biggest problem is the formula for drawing a parabola.
After searching a bit, I found a fantastic website.
making an arrow fly in a parabolic trajectory (2D, gravity ignored)
. Thanks to Hatena Blog.
The formula finds the coordinates on the Bézier curve specified by the starting point (p0), vertex (p1), and ending point (p2). I
'll create a coroutine that also rotates the direction of the arrow by 180° near the vertex.
///<summary> /// Draw a parabola ///</summary> ///<param name="p0"> starting point</param> ///<param name="p1"> Vertex (relative coordinates)</param> ///<param name="p2"> End point (relative coordinates)</param> ///<returns> Coroutines</returns> IEnumerator Throw (Vector3 p0, Vector3 p1, Vector3 p2) { float distance = Vector3.Distance(Vector3.zero, p2); float speed = 0.3f; float t = 0f; while (t <= 1 && isAlive) { float Vx = 2 * (1f - t) * t * p1.x + Mathf.Pow (t, 2) * p2.x + p0.x; float Vy = 2 * (1f - t) * t * p1.y + Mathf.Pow (t, 2) * p2.y + p0.y; transform.position = new Vector3 (Vx, Vy, 0); t += 1 / distance / speed * Time.deltaTime; // Rotate gradually by 180 degrees while t is between 0.4 and 0.6 if (t > 0.4f && t < 0.6f) { float angle = Mathf.Lerp(0, courseGoal[course], (t - 0.4f) / 0.2f); transform.rotation = Quaternion.Euler(0, 0, angle); } yield return null; } Destroy (this.gameObject); }
* p1 and p2 needed to be relative coordinate values, so this has been corrected (March 22, 2024)
Then, specify p0 to p2 when generating the Plow.
Adding random numbers to the vertex heights and the width from start to end point will give it a more realistic look.
The finished product is shown below:
Level 1

, Level 2

, Level 3

Guardian (Scythe)
The one that spins around the player
① Rotates around the player
② The number increases as the level increases
③ Does not disappear when it hits a zombie (penetrates)
Yes, it has the fewest requirements
The construction is the same. Create a Sickle class with Weapon_3.
Just place them at equal intervals depending on the number you want to deploy, and make them rotate at the same speed.
For circular motion, you can calculate the coordinates (offset values) using trigonometric functions.
Then, since they follow the player, just add the player's coordinates and you're good to go.
With these definitions in place,
// Radius public const float Radius = 4.0f; // Rotation speed (per second) private const float RotateSpeed = 270f; // Spin speed (per second) private const float SpinSpeed = 1080f; // Angle (angle for determining position) private float rotateAngle = 0.0f; // Angle (rotation) private float spinAngle = 0.0f;
The rest is handled by the framework
void Update() { // Increase angle (revolution) rotateAngle -= RotateSpeed * Time.deltaTime; // Increase angle (rotation) spinAngle -= SpinSpeed * Time.deltaTime; // Convert angle (revolution) to radians float rad = rotateAngle * Mathf.Deg2Rad; // Convert angle (rotation) to radians float spinRad = spinAngle * Mathf.Deg2Rad; // Update position Vector2 pos = player.Position; transform.position = new Vector3( pos.x + Radius * Mathf.Cos(rad), pos.y + Radius * Mathf.Sin(rad), 0.0f ); // Update rotation transform.rotation = Quaternion.Euler(0.0f, 0.0f, spinAngle);
The sickle itself rotates along with the circular motion.
Here are the finished products: ↓
Level 1

, Level 2

, Level 3

Debugging UI
Create a debug UI to check the operation
- All weapons can be set to levels 1-3.
- Weapon 1 is level 1 by default.
- Weapons 2 and 3 are initially unacquired.
You can quickly create it by adding legacy buttons, etc

That's all for this month
That's all for today.
Thanks to the websites I used as references, I think I was able to implement it relatively quickly.
Even at the mini-game level, it's fun to create something with Unity.
By the way, this is what it looks like in full attack mode

Next time
zombie behavior
Obtaining
I hope to be able to implement something like this
The entire project is available on GitHub, as usual.
I hope it's helpful.
BeBe Survivor
Well, that's all for today
7
