【Unity实战】复刻实现经典2d平台跳跃游戏《蔚蓝 Celeste》(附工程源码)

news2024/11/17 13:34:50

文章目录

  • 前言
  • 蔚蓝欣赏
  • 实现
    • 1. 移动
    • 2. 跳跃
    • 3. 滑动
    • 4. 爬墙
    • 5. 蹬墙跳
    • 6. 移动优化
    • 7. 粒子效果
    • 8. 角色环境素材
    • 9. 编写角色动画控制
    • 10. Tilemap绘制地图环境
    • 11. 环境粒子特效
    • 12. 冲锋残影效果
    • 13. 屏幕震动效果
    • 14. 涟漪效果
  • 最终效果
  • 工程源码
  • 参考
  • 完结

前言

蔚蓝》是一款备受好评的独立游戏,由游戏开发工作室Giant Squid开发并由Annapurna Interactive发行。这款游戏于2016年首次发布,并在玩家和评论界收获了广泛赞誉。

蔚蓝以其独特的艺术风格和引人入胜的故事而著称。游戏以深海为背景,玩家将扮演一个能够探索水下世界的神秘生物。游戏通过惊人的视觉表现和动态的海洋生态系统为玩家带来了令人难忘的游戏体验。无论是广阔的水下景观还是充满生机的海洋生物,蔚蓝都让玩家感受到深海的神秘和美丽。

蔚蓝在玩法上注重探索和解谜。玩家可以在海底环境中自由游动,发现隐藏的地点和秘密,与各种生物互动,并解决环境谜题以继续前进。游戏还以其流畅的操作和直观的界面而受到称赞,使得玩家能够轻松沉浸其中。

此外,蔚蓝还通过精美的音乐配乐和令人叹为观止的视觉效果,为玩家营造了一种宁静而令人心醉的氛围。故事情节也极具吸引力,通过隐喻和寓言的方式传达了关于人类存在和自然界的深层次思考和哲学洞察。

总的来说,蔚蓝被认为是一款极富艺术性和思想性的独立游戏。它成功地将美丽的视觉表现、令人放松的玩法和深思熟虑的故事情节融为一体,为玩家提供了一次独特而难以忘怀的探险之旅。

今天的项目灵感就是来自于独立游戏《蔚蓝》,我的目标是尝试实现类似的运动和体验,这里主要实现的步骤是:角色的基本运动包括步行、跳跃、抓墙和冲刺,在角色移动中添加一些像素动画,然后在环境中添加一些粒子和额外的效果来美化场景。

蔚蓝欣赏

先来欣赏一下《蔚蓝》一些美丽的画面和效果:
请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述

实现

1. 移动

首先创建了一个带有sprite渲染器的游戏对象,并通过添加一个2d刚体组件,来对其施加重力以使角色移动。
在这里插入图片描述
移动脚本MoveMent,通过获取水平和垂直轴的输入值,来修改刚体的速度。

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. 跳跃

当按下跳跃按钮时,改变了刚体的Y轴速度,实现跳跃效果

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

优化

通过这样做,跳跃总是具有相同的线性运动,我们可以通过修改角色的重力,来改善游戏的跳跃,这取决于你按下按钮的时间长短
更加复杂的效果可以看我之前的文章:实现马里奥一样更具物理感的长按长跳与短跳

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. 滑动

接下来的事情就是监测玩家碰撞,我们使用了overlap circlel函数,看看角色是否接地或墙上,

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);
}

我可以通过减去Y轴速度,使物体在撞击墙壁时滑动

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

在这里插入图片描述

4. 爬墙

当角色在墙上并按住shift按键时,我们激活wallGrab ,这使得玩家可以通过改变y轴的速度实现爬墙效果

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

在这里插入图片描述

5. 蹬墙跳

当玩家与墙碰撞时来个墙跳,我想的第一个方法就是,跳跃后暂时停止物体的所有运动,这样就不会让玩家立即又回到墙壁上,但结果并不是很好,我决定在玩家跳跃后移除移动,这样玩家仍然可以控制角色,而且不需要有其他工作要做。

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. 移动优化

得到了基于水平轴和垂直轴的方向,并用它来增加刚体速度,以使速度非常快而不走得很远

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

并增加了在角色冲刺时的刚体阻力特性
在这里插入图片描述

7. 粒子效果

然后我决定在这个项目中添加一个粒子系统,这样这个项目就可以看起来更好一些
在这里插入图片描述

8. 角色环境素材

下载引入素材角色环境素材
请添加图片描述
请添加图片描述

9. 编写角色动画控制

这一部分我就不详细讲了,贴出动画连线图,之前我也写过很多相关的文章教程,不懂得可以先去看看:
旧动画和新动画组件的使用
设置人物移动脚本、动画的切换和摄像机的跟随

在这里插入图片描述
一个解决方案是在Animator.上,创建与角色脚本上类似的参数,并将它们用作过渡的条件
在这里插入图片描述

10. Tilemap绘制地图环境

不懂得可以看我之前写的文章:绘制地图Tilemap的使用及一些技巧的使用1
在这里插入图片描述

11. 环境粒子特效

创建脚步灰尘效果和风雪效果,具体实现可以看我之前的文章:unity2d粒子特效
在这里插入图片描述

12. 冲锋残影效果

主角留下的轨迹,我创建了三个图像序列,冲刺时移动到角色位置上,然后我让它们逐渐消失

这里只是简单的实现,实际运用中可能更加复杂,考虑的因素也会多很多,想了解的可以看我的这篇文章:
用对象池设计制作冲锋残影的效果并加技能cd

在这里插入图片描述

13. 屏幕震动效果

这里使用DOTween实现一个屏幕震动效果

屏幕震动的效果还有很多,想了解的可以看我之前的文章:unity实现简单的摄像机震动效果
DOTween的使用,可以看看我之前的文章:DoTween动画插件的使用

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

14. 涟漪效果

仔细观察蔚蓝的冲刺时,会发现开始有一个涟漪效果
在这里插入图片描述
这里直接使用github上大佬分享的一个shader效果:https://github.com/keijiro/RippleEffec
在这里插入图片描述

最终效果

在这里插入图片描述

工程源码

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

参考

【视频】:https://www.youtube.com/channel/UCLyVUwlB_Hahir_VsKkGPIA

完结

如果你有其他更好的方法也欢迎评论分享出来,当然如果发现文章中出现了什么问题或者疑问的话,也欢迎评论私信告诉我哦

好了,我是向宇,https://xiangyu.blog.csdn.net/

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是开始自习unity。最近创建了一个新栏目【你问我答】,主要是想收集一下大家的问题,有时候一个问题可能几句话说不清楚,我就会以发布文章的形式来回答。 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信号与系统复习笔记——通讯系统

信号与系统复习笔记——通讯系统 复指数与正弦幅度调制 y ( t ) x ( t ) c ( t ) y(t) x(t)c(t) y(t)x(t)c(t) 上式称为调制&#xff0c;其中 x ( t ) x(t) x(t) 称为 调制信号 &#xff0c;而 c ( t ) c(t) c(t) 称为 载波信号 &#xff0c; y ( t ) y(t) y(t) 称为 已…

Redis高可用(主从复制、哨兵模式和Cluster集群)

文章目录 一、Redis高可用1.持久化2.主从复制3.哨兵4.Cluster集群 二、主从复制1.概念2.作用3.主从复制流程4.配置主从复制 三、哨兵模式1.功能2.作用3.组成4.故障转移机制7.故障模拟8.恢复故障节点 四、Cluster群集1.简介2.作用&#xff08;1&#xff09;数据分区&#xff08;…

Redis常用数据类型

Redis 哈希(Hash)&#x1f349; Redis hash 是一个 string 类型的 field&#xff08;字段&#xff09; 和 value&#xff08;值&#xff09; 的映射表&#xff0c;hash 特别适合用于存储对象。 Redis 中每个 hash 可以存储 232 - 1 键值对&#xff08;40多亿&#xff09; 它…

如何动手用js自己写一个分页?

实现效果 实现代码 function generateTableHead() {const tableHead document.getElementById(table-head);tableHead.innerHTML ;// 添加复选框列的表头const checkboxHead document.createElement(th);const checkbox document.createElement(input);checkbox.type che…

项目部署

#修改表的编码 alter table t_course convert to character set utf8 show create table t_course启动docker&#xff1a; service docker startdocker创建redis设置密码&#xff1a; docker pull redis docker run --name my-redis -p 6379:6379 -e REDIS_PASSWORD<pass…

【大数据趋势】7月2日 汇率,美澳,恒指期货的大数据趋势概率分析。

数据源头之一 : 汇率变化 从程序模拟趋势来看&#xff0c;如果没有干预&#xff0c;极大概率要试探顶部7.375的位置。【位置1】从长期趋势来看&#xff0c;在一个上升通道中长期震荡上行&#xff0c;所以正常应该走2.2的路径【趋势2.2】 因为这轮上涨的动能很大&#xff0c;所…

join on 后面的and 与where 的区别及用法

--- 先把数据导入数据库 CREATE TABLE test_join_where_a ( aid int(0) NOT NULL, aname varchar(255) , atimedate datetime(0) , ascore varchar(255) ); INSERT INTO test_join_where_a(aid, aname, atimedate, ascore) VALUES (1, 张三, 2023-05-03 01:13:30, 8…

环境变量的配置

在我上一篇文章中有写到&#xff0c;在编译和运行Hello World这个文档的时候要使用java.c和java这俩个工具&#xff0c;但是我们却没有转换到这俩个工具所在的磁盘位置&#xff0c;而是直接调用了&#xff0c;那么是怎么实现这一功能的嘞&#xff0c;就有下面的理解 首先wine打…

Linux--给指令起别名:alias

示例&#xff1a;给ls-al起了个别名叫kk​ 注意&#xff1a;起别名只在本次登录有效。

Python爬虫-某政务网站文档爬取,并将正文内容保存在word

前言 本文是该专栏的第1篇,后面会持续分享python爬虫案例干货,记得关注。 地址:aHR0cDovL3d3dy5oZWJlaS5nb3YuY24vc2VhcmNoL3BjUmVuZGVyP3BhZ2VJZD1iOTdhMzg4MzNmNzM0M2NlYmMzMWRlYzQ0NTQ0ZjY4NA== 需求:以某政务网网站为例,采集其正文内容,并将其正文内容以docx格式保…

借助APlayer、MetingJS实现 网页音乐播放器

借助APlayer、MetingJS实现 1、src/publi/index.html引入 <script src"https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script> <script src"https://cdn.jsdelivr.net/npm/meting2.0.1/dist/Meting.min.js"></scri…

离线安装ffmpeg源码包【详细教程】

今天分享一下ffmpeg源码包的安装过程&#xff0c;针对在没有网络环境下&#xff0c;且不能直接使用yum如何成功安装ffmpeg源码包。博主本人通过正式服务器测试&#xff0c;记录整个安装过程。值得大家收藏 同时&#xff0c;我会分享一下如何使用ffmpeg对H.264格式视频(MP4)进行…

echarts数据可视化模板相互影响

问题 echarts数据可视化模板相互影响 详细问题 echarts数据可视化模板相互影响,笔者使用由CSSJavaScriptHTML实现的echarts数据可视化模板&#xff0c;对于其中的子图(图A&#xff0c;位于boxA.js下与图B位于boxB.js下)进行数据下钻&#xff0c;更改option配置后&#xff0c…

苹果正在研发具备智能家居显示功能的外接显示器,具备低功耗模式

据彭博社记者 Mark Gurman 在他最新一期的 Power On 时事通讯中报道&#xff0c;苹果公司正致力于研发一款新的 Mac 外接显示器&#xff0c;具备智能家居设备显示器的低功耗模式功能。 根据了解&#xff0c;这款显示器将集成iOS设备芯片&#xff0c;与Studio Display不同的是&a…

最短路径相关算法

文章目录 图论中的图属性最短路径算法- Dijkstra算法1. 算法介绍2. 适用场景3. 场景举例 - Bellman-Ford算法1. 算法介绍2. 适用场景3. 场景举例 - Floyd-Warshall算法1. 算法介绍2. 适用场景3. 场景举例 具体实现方案- JGraphT 小结 图论中的图属性 图论中&#xff0c;图的属…

SpringMVC (三) RestFul和控制器

学习回顾&#xff1a;SpringMVC &#xff08;一&#xff09; 什么是SpringMVC 现在我们来看看里面的控制器和路径请求的具体内容吧&#xff01; 一、控制器Controller 控制器复杂提供访问应用程序的行为&#xff0c;通常通过接口定义或注解定义两种方法实现。控制器负责解析用户…

如何在Centos7下安装Nginx

一、Nginx简介 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 &#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点&#xff08;俄文&#xff1a;Рамблер&#xff09;开发的&#xff0c;公开版本1.19.6…

Self-attention Transformer

参考资料&#xff1a; 《机器学习》李宏毅 1 Self-attention 当模型输入为长度不定的向量序列时&#xff08;如一段文字、一段语音、图模型&#xff09;&#xff0c;要求模型输出为等长的向量序列&#xff08;序列标注&#xff09;时&#xff0c;可以使用 Self-attention S…

文件的概念 + 文件的相对/绝对路径 + 文件IO字符流 / 字节流的读写操作 (java)

文章目录 前言一、文件是什么1.文件的概念2.文件路径1.绝对路径2.相对路径 二、针对文件的IO1.File类2.对文件内容的读写操作1.针对文本文件—— 字符流输入流 Reader类输出流 Writer类 2.针对二进制文件—— 字节流输入流 InputStream类输出流 OutputStream类 总结 前言 本人…

《Reinforcement Learning: An Introduction》第7章笔记

Chapter 7 n-step Bootstrapping 本章的n-step TD方法是前两章的Monte Carlo 方法和one-step TD方法的推广。它使自举法在多个时间步内进行&#xff0c;解决了前两章中的更新时间步不灵活的问题。 7.1 n-step TD Prediction 在用策略 π \pi π下生成的采样回合序列来估计 v…