[Unity Actual Combat] The re-enactment of the classic 2D platform jumping game "Celeste" (with project source code)

foreword

, 蔚蓝is a critically acclaimed indie game Giant Squiddeveloped by Game Development Studio and Annapurna Interactivepublished by . The game was first released in 2016 and received widespread acclaim from players and critics.

Azure is known for its unique art style and compelling story. The game is set in the deep sea, and the player will play a mysterious creature who can explore the underwater world. The game brings players an unforgettable gaming experience through stunning visual performance and dynamic marine ecosystems. Whether it is the vast underwater landscape or the sea creatures full of vitality, Azure makes players feel the mystery and beauty of the deep sea.

Weilan focuses on exploration and puzzle solving in terms of gameplay. Players can freely swim in the underwater environment, discover hidden locations and secrets, interact with various creatures, and solve environmental puzzles to progress. The game was also praised for its smooth controls and intuitive interface, making it easy for players to immerse themselves in it.

In addition, Celeste creates a peaceful and mesmerizing atmosphere for players through exquisite music soundtrack and breathtaking visual effects. The storyline is also very engaging, conveying deep thinking and philosophical insights about human existence and the natural world through metaphors and allegories.

Generally speaking, Celeste is considered to be a very artistic and thoughtful independent game. It successfully blends beautiful visuals, relaxing gameplay, and a well-thought-out storyline to provide players with a unique and unforgettable adventure.

The inspiration for today's project comes from the independent game " " 蔚蓝. My goal is to try to achieve a similar movement and experience. The main steps here are: the basic movement of the character includes walking, jumping, grabbing the wall and sprinting, and adding it to the movement of the character Some pixel animation, then some particles and extra effects in the environment to beautify the scene.

Azure Appreciation

Let's enjoy 蔚蓝some beautiful pictures and effects of " " first:
Please add a picture description

Please add a picture description
Please add a picture description
Please add a picture description

accomplish

1. to move

First create a game object with a sprite renderer and apply gravity to it to make the character move by adding a 2d rigidbody component.
insert image description here
The movement script MoveMent modifies the speed of the rigid body by obtaining the input values ​​of the horizontal and vertical axes.

public class Movement : MonoBehaviour
{
    
    
	private Rigidbody2D rb;
	public float speed = 10;
	
	void start(){
    
    
		rb = GetComponent<Rigidbody2D>();
	}
	void Update()
	{
    
    
		float x = Input.GetAxis("Horizontal");
		float y = Input.GetAxis("Vertical");
		Vector2 dir = new Vector2(x,y);
		Walk(dir);
	}
	private void Walk(Vector2 dir)
	{
    
    
		rb.velocity (new vector2(dir.x * speed, rb.velocity.y));
	}
}

2. to jump

When the jump button is pressed, the Y-axis speed of the rigid body is changed to achieve the jump effect

private void Jump()
{
    
    
	rb.velocity = new Vector2(rb.velocity.x,0);
	rb.velocity += Vector2.up * jumpForce;
}

optimization

By doing this, jumping always has the same linear motion, we can improve the game's jumping by modifying the gravity of the character, depending on how long you press the button. More complex effects can be seen in my previous article:
Implementing Mali Long press long jump and short jump with more physical sense like Austrian

using UnityEngine;

public class BetterJumping : MonoBehaviour
{
    
    
    private Rigidbody2D rb;
    public float fallMultiplier = 2.5f;
    public float lowJumpMultiplier = 2f;

    void Start()
    {
    
    
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
    
    
        if(rb.velocity.y < 0)
        {
    
    
            rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
        }else if(rb.velocity.y > 0 && !Input.GetButton("Jump"))
        {
    
    
            rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
        }
    }
}

3. Slide

The next thing is to monitor the player collision, we use the overlap circle function to see if the character is grounded or on a wall,

void Update()
{
    
      
    onGround = Physics2D.OverlapCircle((Vector2)transform.position + bottomOffset, collisionRadius, groundLayer);
    onWall = Physics2D.OverlapCircle((Vector2)transform.position + rightOffset, collisionRadius, groundLayer) 
        || Physics2D.OverlapCircle((Vector2)transform.position + leftOffset, collisionRadius, groundLayer);
}

I can make the object slide when it hits the wall by subtracting the Y axis velocity

if(coll.onWall && !coll.onGround)
{
    
    
         WallSlide();
}
private void WallSlide()
{
    
    
	rb.velocity = new Vector2(rb.velocity.x, -slideSpeed);
}

insert image description here

4. Wall climbing

When the character is on the wall and holds down the shift button, we activate wallGrab, which allows the player to climb the wall by changing the speed of the y-axis

float y = Input.GetAxis("Vertical");
wallGrab = coll.onWall && Input.Getkey(KeyCode.Leftshift);
if (wallGrab){
    
    
	rb.velocity = new vector2(rb.velocity.x, y * speed);
}

insert image description here

5. Wall jump

Do a wall jump when the player collides with the wall, the first approach I thought of was to temporarily stop all movement of the object after the jump, so that the player doesn't immediately go back to the wall, but it didn't work out very well, I It was decided to remove the movement after the player jumps, so the player can still control the character and there is no other work to do.

private void Walk(Vector2 dir)
{
    
    
    if (!canMove)
        return;

    if (wallGrab)
        return;

    if (!wallJumped)
    {
    
    
        rb.velocity = new Vector2(dir.x * speed, rb.velocity.y);
    }
    else
    {
    
    
        rb.velocity = Vector2.Lerp(rb.velocity, (new Vector2(dir.x * speed, rb.velocity.y)), 5f * Time.deltaTime);
    }
}

6. Mobile optimization

Got the orientation based on the horizontal and vertical axes and used that to increase the rigidbody velocity to get very fast without going very far

private void Dash(float x, float y)
{
    
    
    wallJumped = true;
    rb.velocity = Vector2.zero;
    Vector2 dir = new Vector2(x, y);
    rb.velocity += dir.normalized * 30;
}

And added the rigid body resistance feature when the character sprints
insert image description here

7. Particle Effects

Then I decided to add a particle system to the project so that the project could look a little better
insert image description here

8. Character environment material

Download import material character environment material
Please add a picture description
Please add a picture description

9. Writing Character Animation Controls


I won’t go into details about this part, and post the animation connection diagram. I have written many related articles and tutorials before
. Switching and camera following

insert image description here
One solution is to create parameters similar to those on the character script on the Animator. and use them as conditions for the transition
insert image description here

10. Tilemap drawing map environment

If you don’t understand, you can read the article I wrote before: the use of drawing maps Tilemap and the use of some skills 1
insert image description here

11. Environmental particle effects

Create footstep dust effects and wind and snow effects. For specific implementation, please refer to my previous article: unity2d particle effects
insert image description here

12. Charge afterimage effect

For the trail left by the protagonist, I created a sequence of three images that move to the character's position while sprinting, and then I made them fade away

This is just a simple implementation. It may be more complicated in actual use, and there will be many more factors to consider. If you want to know more, you can read my article: Design and create the effect of charging afterimage with the object pool
and add the skill cd

insert image description here

13. Screen vibration effect

Here use DOTween to achieve a screen vibration effect

There are many effects of screen vibration. If you want to know more, you can read my previous article: Unity achieves a simple camera vibration effect.
The use of DOTween, you can read my previous article: Use of DoTween animation plug-in

private void Dash(float x, float y)
{
    
    
    Camera.main.transform.DOComplete();
    Camera.main.transform.DOShakePosition(.2f, .5f, 14, 90, false, true);
    
    //...
 }

14. Ripple effect

When you observe Ripple's sprint carefully, you will find that there is a ripple effect.
insert image description here
Here is a shader effect shared by a big guy on github: https://github.com/keijiro/RippleEffec
insert image description here

final effect

insert image description here

Project source code

https://gitcode.net/unity1/Celeste-Movement

reference

[Video]: https://www.youtube.com/channel/UCLyVUwlB_Hahir_VsKkGPIA

end

If you have other better methods, you are welcome to comment and share them. Of course, if you find any problems or questions in the article, please also comment and private message me.

Well, I am Xiang Yu, https://xiangyu.blog.csdn.net/

A developer who worked silently in a small company, out of interest, began to study unity by himself. Recently, I created a new column [You Ask Me Answer], mainly to collect your questions. Sometimes a question may not be clear in a few words, and I will answer it in the form of an article. Although I may not necessarily know some problems, I will check the information of various parties and try to give the best advice. I hope to help more people who want to learn programming. Let's encourage each other~

Guess you like

Origin blog.csdn.net/qq_36303853/article/details/131499234
Recommended