Portfolio
In this article, I will list all the works I have participated in or completed, as well as some related work!
Game Projects
2020
2020 Net-Ease High School MiniGame Competition - 前世今生狩猎小队
Your browser does not support the video tag.
Art
Introduction:In 前世今生狩猎小队, players take on the role of hunters hunting a giant monster. Each time a hunter dies, a new clone is created to replicate the player’s previous actions. After multiple deaths, a squad is formed, working together to finally defeat the mons ...
项目作品集汇总
在这篇文章里,我会罗列出所有我参与或独立完成的作品,以及一些相关的工作!
参与制作的正式作品
2020
2020网易游戏高校MINI-GAME挑战赛 - 前世今生狩猎小队
Your browser does not support the video tag.
游戏美术
项目介绍:在《前世今生狩猎小队》中,玩家扮演猎人狩猎一个巨型怪物,猎人每次死亡都会制造出一个新的克隆体来复刻玩家生前的操作,死亡多次以后就形成了一个小队,互相配合,最后击败怪物。
主要工作:这是我接触的第一个游戏项目,在本项目中负责给各位大佬端茶倒水游戏场景、道具等素材的绘制。
西二在线第三轮考核 - 合成大西瓜
全栈
站内链接
项目介绍:该项目是我参加本科计算机相关社团“西二在线工作室(West2Online)”Unity方向第三轮考核时的作品,考核内容为在一个月内完成一个小游戏的复刻,我所选择的是当时的热门小游戏《合成大西瓜》。
主要工作:这是由我作为全栈实现的第一个游戏项目,通过该项目接触并熟悉了Unity游戏引擎的各项基础功能。
西二在线第四轮考核 - 复刻明日方舟
全栈
站内链接
项目介绍:该项目是我参加本 ...
CSHARP内存管理
在C#应用的背后…
C#是微软推出的一种基于.NET框架和后来的.NET的、面向对象的高级编程语言。C#衍伸自C和C++,继承了C和C++的强大功能,同时去掉了一些复杂特性,使其成为C语言家族中高效强大的编程语言。C#以.NET框架类库作为基础,拥有类似Visual Basic的快速开发能力。微软在2000年发布了这种语言,希望借助这种语言来取代Java。
.NET 框架中有一些但看缩写非常类似的概念,例如:CLI/CIL/CLR/CTS/CLS/JIT/GC等等。
在通用语言基础架构 (Common Language Infrastructure) 中,C# 在构建时会被编译为 CIL (Common Intermediate Language),即通用中间语言(在一些地方也被称为字节码/ByteCode)。在.Net开发平台下,所有语言(C#、VB.NET、J#、C++/CLI)都会被编译为通用中间语言,再由 CLR (Common Language Runtime),即通用语言运行时负责运行。
在 CLR 中,CLR 通过 JIT (Just In - Time Compi ...
ECS设计模式
什么是ECS?为什么我们需要它?
在传统游戏开发中,开发者习惯于将每个功能写成一个class,例如玩家控制器(PlayerController)。在这个脚本中不但包含了玩家自身的数据(data,例如速度、血量等),还包含了针对这些数据的处理逻辑(behavior)。
有时作为开发者,我们需要在极短时间完成原型发开来验证玩法的可行性(或者我们只是打了个game jam),一些能够被重复利用的“轮子”是相当重要的。我们前面所提到的每个功能一个 class 的做法其实很不适合拓展,因为数据和行为是耦合的,不便于修改。
有没有更好的设计模式呢?接下来让我们隆重推出本文的主角——ECS设计模式!本文将参照轻量级 ECS 解决方案 Entitas 对该设计模式从源码层面进行介绍。首先,什么是ECS ?ECS 即 Entity-Component-System,指“实体-组件-系统”设计模式,是一种有别于传统 OOP(面向对象)类型的设计模式,它是 DOP(面向数据)的。
Entity/实体
实体类似于 GameObject,可以简单理解为“游戏对象”。
Component/组件
组件包含了实体 ...
网络同步-帧同步/状态同步
什么是网络同步
网络同步是指通过网络将数据从一个系统或节点传输到另一个系统或节点,并保持两者之间的数据一致性。换句话说,游戏中的网络同步就是把我的状态同步给远程玩家的“我”的镜像,使双方在屏幕上看到的效果是一致的。
在常见的多人联机游戏(例如下棋、格斗、fps等等等等)中,网络同步是非常重要的一项需求。游戏中的玩家需要时时刻刻了解其他玩家的状态或者行为,才能辅助自己做出下一步决策(例如是否开枪等)。
如何知道其他玩家的状态,又如何让其他玩家知道我的状态呢?这时候就需要网络同步技术了。
同步设计目标
同步设计主要有两个目标,即 一致性 和 及时性 。在实际工程中,我们其实很难同时满足一致性和及时性,因为网络延迟始终存在,客户端在接收到最新状态前只能进行预测(采用一些客户端障眼法,例如插值)。
在这两个核心目标下,我们可以拆解出三个子设计要素,根据实际情况进行优先级权衡。一般来说用户体验是位于首位的。
公平
确定
操作具有幂等性,玩家执行一个操作所得的的结果是确定的。游戏存在明确的规则,玩家知道规则带来的确切的后果,因此才可以基于规则进行博弈。
安全
数据的安全性代表玩家的数据隐私不应 ...
2024GGJ🌏 - CluckCluck复盘——新输入系统与手柄控制
新输入系统(Input System)
Unity的新输入系统是一个基于事件的新系统,它在编辑器里提供了一个中间层(Input Action Asset),用户可以在其中自定义一系列玩家动作和其对应的操作。例如在CluckCluck中,我设定了移动(left joystick)、冲刺(B)、拾取道具(right trigger)三个控制:
完成操作设置之后,保存Input Action资产,在其检查器中可以点击生成对应的C#类,接下来就可以在代码中通过事件绑定的方法使用这些操作监听。
同屏双手柄(1p2p)
由于我们做的是一个比较欢脱的双人派对竞技游戏,这次jam还有一个重要的需求是同屏双手柄控制。我不想像懂哥一样用“PlayerController1.cs”和“PlayerController2.cs”来区分不同玩家(因为如果采取这种模式,如果玩家数量增多,需要维护的脚本就会变多),所以如何在一个脚本中为不同玩家绑定不同的控制器尤为重要。
首先是声明p1/p2,它们都用了同一套InputAction “Player2”(之所以是这个命名是因为Player1是键盘控制)。通过游戏对 ...
游戏AI-状态机与行为树
假设我们需要设计一个敌人 AI,它存在“按照路线巡逻”、“警觉”、“追击玩家”三种状态,它们之间的关系如下:
AI 默认处于“按照路线巡逻”状态
在“按照路线巡逻”中,如果发现了玩家,就进入“警觉”状态
在警觉状态中,如果玩家持续存在,经过两秒后进入“追击玩家”状态
在“警觉”和“追击玩家”状态中,如果玩家逃脱巡查范围或死亡,则回到“按照路线巡逻”状态
对初学者来说,我们很容易会想到为每个状态设置一个bool值,用来判断对象是否处于某个状态中,例如:
12345678910111213141516171819202122232425262728293031bool isPatrol = true; // 初始处于巡逻状态bool isAlert = false;bool isChase = false;void Update(){ if(isPatrol){ if(playerTarget){ isAlert = true; isPartol = false; }else{ // 巡逻 ...
基于Gerstner Wave算法的海洋实现
介绍
Sin Wave的局限
在引入Gerstner Wave之前,人们更多使用正弦波来模拟海浪,因为正弦波天生具有类似海浪的形状。但它的局限也很明显,那就是波峰过于圆润,纵然有办法通过代数方法约束波峰的形状,但效果还是无法达到预期的尖锐。
什么是Gerstner Wave
Gerstner Wave是Sin Wave的后继者,到现在也是一种常用的用来模拟海洋波浪的算法。他的历史其实已经很古老了,可以追溯到1986年。相比于快速傅里叶变换(FFT),Gerstner Wave方法的开销更小,效果也很真实,因此被更多的应用与游戏领域(FFT更适合影视行业,因为它的效果更好但开销更大)。
Gerstner Wave的公式如下:
P(x,y,t)=(x+∑(QiAi∗Di.x∗cos(ωiDi(x,y)+φt))y+∑(QiAi∗Di.y∗cos(ωiDi(x,y)+φt))∑(Ai∗sin(ωiDi(x,y)+φt)))P(x,y,t) = \begin{pmatrix}x + \sum({Q_{i}A_{i} * D_{i}.x * \cos(\omega_{i} D_{i}(x ...
水面、波浪、白沫和焦散
请注意
由于微博图床外链失效,本文部分图片无法获取
介绍与准备
我最近打算开始做毕设项目的场景啦XD!这个项目的名字叫元素宇宙(Elemental Universe),是一个化学元素拟人世界观下的小宇宙的故事,目前只有我一个人在做,第一步是搭场景。主场景打算用polyBrush磨出来,其中有一些湖泊和海洋。海洋部分我打算用GerstnerWave的方法来做,湖泊部分采用本文所介绍的方法(当然,还有很多可以改进的地方。有改进的部分会在“更新说明”里提及)。
废话交代完了,现在正式开始吧:
首先,准备一个细分好的平面(因为我们需要一定数量的顶点)作为水面。在这个项目中我使用的是:
演示模型来自Sketchfab,使用遵守CC版权协议。如下预览所示,模型原本的水面只是一块普通的、smooth值几乎设置为1的水平面:
Little Pond & fish by Kenny Kwok. on Sketchfab
波浪
波浪的基本原理是顶点动画,通过修改水面顶点y值(高度)实现,这也是为什么前文提到我们需要一块顶点数比较多的面,越多的顶点意味着越高的波浪精细程度。
我们现在希望 ...
贴地雾效实现
接上篇文章画的饼,这回我打算试着实现一下雾效,我们最终的目标就是实现类似下图的效果。当然,纪念碑谷中的不怎么被雾影响的方块和浸泡在雾气中的方块使用的应该是两种shader,他们不会混在一起。但如果我们要实现的是一个可以移动的场景呢?使用我想在纪念碑谷的静态贴地雾效上加点东西,即:当摄像机移动时,雾的范围会随着摄像机的移动而移动,始终做到远处模糊、近处清晰的效果。
思路
其实我们实现纪念碑谷中的这种雾效的思路和全局渐变非常类似。总结一下,主要有以下两点需求:
离摄像机越远,雾气越浓,具体表现在物体整体与雾气的颜色相融
离摄像机越近,雾气越轻,具体表现在雾气很浅,几乎消失
即,离相机较远的物体如下左所示;离相机较近的物体如下右所示:
我们可以调整地平线(渐变中心位置)的值来实现这个效果。当一个物体离摄像机较近时,它的渐变中心也较低;反之则较高。
实现
变量
我们需要这么几个变量:
渐变纹理
主色调
雾的颜色
雾的浓度
12345678Properties{ _RampTex("渐变纹理", 2D) = "white&q ...