Making Da○Saba○bar (first issue)
table of contents
“Weekly Make Da○Saba○Bar” is launched!
I suddenly started doing it in a Di*goth*ini style.
It has been a while.
This is Mr. Matsuyama from the System Development Department.
When I look at Facebook or manga apps on my smartphone,
I often see advertisements for "Da○saba○bar."
I don't dislike games that have such a messy feel, so
I decided to try making one to see how it could be made.
By the way, I have never played anything other than the trial version, so
please bear with me if there are some parts that are very different from the original work.
Rough requirements
As usual, we will clarify the requirements.
① There is a 2D field (grid type)
② You can control your character (player) up, down, left and right by touching the screen
③ There are multiple weapons and levels
④ Enemies naturally occur and move towards the player
⑤ There is a hit detection for each player, enemy, and weapon.
⑥ When you defeat an enemy, experience points are displayed, and by collecting them you can upgrade new weapons and weapons.
For now, that's it.
I think about the details of each part as I create them.
Let's leave detailed performance elements such as time measurement and SE as future issues (while creating an atmosphere that we may not do it).
Create project
I haven't touched Unity for a long time, so let's install the latest version.
2022.3.18f1 seems to be the latest LTS, so I will install it.
Unity Hub is useful.
Name the project "BeBeSurvivor" and create it as a 2D app.
resource
Check out the resources (sprites) you need to create it in the Asset Store.
When I was looking for free 2D, I found an asset that looked exactly like it.
◾️Undead Survival Asset Pack
Contains the necessary materials such as players, enemies, and weapons.
Everything works, so I'm ready to finish everything with this, but
I'll be thankful for the sprites.
◾️Lowpoly Textures Pack
This is an image pack that can be spread over the field.
It is also included in the Undead Survivor Asset Pack, but let's try using it as well.
Import these two using Package Manager.
fill the field
There are a lot of materials in the Lowpoly Texture Pack, so I choose the ones that I think will be useful.
The size was a bit large, so I'll try adjusting the scale.
It's like this.
Make this into a Prefab and spread it over an appropriate area using a script.
An image like this.
And the script looks like this.
// Generate a field from (-50, -50, 0.5) to (50, 50, 0.5) (5 x 5 grid) Vector2 pos = new Vector2(-50, 50); float size = 5f; int cnt = 20; for(int x = 0; x <= cnt; x++) { for(int y = 0; y <= cnt; y++) { // filed[1 when x, y are 0 and cnt ], otherwise generate filed[0] int idx = (x == 0 || x == cnt || y == 0 || y == cnt) ? 1 : 0; // 1 square in the center generates field[2] if(x == cnt / 2 && y == cnt / 2) { idx = 2; } // generates GameObject obj = Instantiate(field[idx], new Vector3(pos.x + ( x * size), pos.y - (y * size), 0.5f), Quaternion.identity); obj.transform.parent = parent.transform; } }
Let's put different images only on the outer periphery and the center.
This time I'm going to mess around with the finite field, but I feel like infinite scrolling is actually better.
(However, in my opinion, this is a fairly appropriate code...)
player
The Survivor Asset Pack contains some nice materials, so I will use them.
There are also animation patterns, so create animations for waiting, moving, and dying, and
set them in Animator.
This is what it looks like when you move it (standby motion)
Move (Input System)
Move the player character.
The image is to move the character in the direction you tap, with the center of the screen as the origin.
Input System was released
while I was away from Unity for a while Let's also import this from Package Manager.
I tried lightly touching it, but I can't get information from the Input Action properly.
For now, we will skip the Action and proceed with the implementation using old-fashioned script control.
(I'll try playing around with Input Action again when I have time)
var mouse = Mouse.current; if(mouse.press.ReadValue() == 1) // press state { if(holdTime > 0.0f) // wait { holdTime -= Time.deltaTime; if(holdTime < 0.0f) holdTime = 0.0f; } else // move { Vector2 pos = mouse.position.ReadValue(); } } else // release state { holdTime = HoldTime; }
Operation information could be obtained from Mouse.current.
The tap state can be obtained using mouse.press.ReadValue(), which returns 1 if the touch is on, and 0 if the touch is released.
After a certain period of time has elapsed in the touch state, obtain the touch coordinates using mouse.position.ReadValue() and
calculate the movement direction (vector). An image like this.
Since the coordinates of the two points are known, the vector can be calculated by simple subtraction.
Since the length does not matter, normalize it with normalized.
Vector2 vec = (pos - center).normalized;
If you set this to the player's coordinates (localPosition), the character will move.
It's like this. (Wait ↔︎Move)
At the same time, extract only the X component in the direction of movement and switch the character's orientation. (rotate 180° on the y-axis)
camera tracking
In this state, the character will go outside the camera, so the camera will always follow the character so that it is in the center of the screen.
All you have to do is match the localPosition of MainCamera's Transform with the character coordinates.
The code looks like this. Note that the z coordinate is fixed to the camera.
// Make the camera follow Vector3 pos = playerController.GetPosition(); pos.z = -1.0f; mainCamera.gameObject.transform.localPosition = pos;
It will look like this after implementation.
enemy
The scarecrow is fine for now, so place the enemies appropriately.
This is also included in the Survivor Asset Pack, so I will use it. (thank you)
There are also animation patterns, so create movement/death animations and
set them in Animator.
For now, I'll leave it like this.
Collision judgment
Make a hit judgment.
Use Collider2D provided by Unity standard.
First, prepare.
Add Circle Collider 2D to each player and enemy.
Check IsTrigger.
We'll also add his Rigidbody 2D to the player. (Not required for the enemy)
This time, we don't need physical calculations, so set the Body Type to Kinematic.
Get the hit judgment with the script.
Add the following functions to the player and enemy code. (Trigger type)
private void OnTriggerEnter2D(Collider2D collision) { // Called at the moment the collider hits // Damage if it hits an Enemy if (collision.tag == "Enemy") { Debug.Log("Player Hit : " + collision.name ); } } private void OnTriggerStay2D(Collider2D collision) { //Continuously called when the collider hits } private void OnTriggerExit2D(Collider2D collision) { //Called when the collider leaves }
We will use tag to determine what the hit target is.
The Player tag is registered by default, so add the Enemy tag and Weapon tag.
Set the Tag of each object.
If you run it so that it outputs a log when it makes contact, it will look like this.
That's all for this month
That's all for now.
I think the basic mechanism has been largely implemented.
Unity has a complete set of features, so it's relatively easy to implement.
In the next issue
I would like to implement weapons (3 types x 3 levels)
The Unity project will be uploaded to GitHub later.
Please wait for a while.
I will update the article once it is uploaded.
I have uploaded the Unity project to GitHub.
I hope this will be of some help to you.
BeBe Survivor
Well, that's all for now.
*Although it says "weekly" at the beginning, the next issue is scheduled to be uploaded in March.