我用Unity制作的第一款游戏Demo
Posted 不如詩啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我用Unity制作的第一款游戏Demo相关的知识,希望对你有一定的参考价值。
我用Unity制作的第一款游戏Demo
Immortal(不朽)
游戏网址:https://play.unity.com/mg/other/immortal_webgl
或者:点击此处进行游戏
或者:下载游戏 提取码:qv8p
这是我使用 Unity 制作的第一款游戏Demo,一款2D的RPG游戏。
游戏中所有工作均为本人独立完成。
美术方面
哎,早知道该好好学学画画的,对队来说制作这个Demo最耗时、最难的工作就是画画了,画个老半天还是惨不忍睹。
为了不至于不堪入目,果断选择了2D像素风格,游戏中所有的Sprite和Image都是使用Aseprite制作的,比起PS,Aseprite绘制像素画太方便了,爱了爱了。
不知不觉都肝了150多个小时了。。。
角色移动动画
爆炸动画
每个像素都是泪呀T T
技术方面
比较难的点就是对象池的制作,为了保证可扩展性,对象池是用字典存储的,字典通过结构体数组的方式序列化(能在Inspector里直接添加对象简直舒服)。下面是对象池实现的C#代码:
/// <summary>
/// 对象池
/// </summary>
public class ObjectPool : MonoBehaviour
//单例模式
public static ObjectPool instance;
//对象类别
public enum ObjectType
Shadow,
FireBall,
FireExplosion,
Wind
#region 字典的序列化
[System.Serializable]
//可序列化的结构体数组(为了序列化字典)
public struct ObjectDetail
public ObjectType type; //类别
public GameObject prefab; //预制体
public int count; //数量
[Header("对象池中的内容")]
public ObjectDetail[] objectDetails;
#endregion
//缓存字典<对象类别, 对象队列>
public Dictionary<ObjectType, Queue<GameObject>> cache = new Dictionary<ObjectType, Queue<GameObject>>();
private void Awake()
//单例模式
instance = this;
//初始化对象池
Initialization();
/// <summary>
/// 初始化对象池并填满
/// </summary>
private void Initialization()
foreach (var item in objectDetails)
cache.Add(item.type, new Queue<GameObject>());
for (int i = 0; i < item.count; i++)
var newObject = Instantiate(item.prefab);
newObject.transform.SetParent(transform);
newObject.SetActive(false);
cache[item.type].Enqueue(newObject);
/// <summary>
/// 填满对象池
/// </summary>
/// <param name="objectType">对象类别</param>
public void FillPoll(ObjectType type)
foreach (var item in objectDetails)
if (item.type == type)
for (int i = 0; i < item.count; i++)
var newObject = Instantiate(item.prefab);
newObject.transform.SetParent(transform);
newObject.SetActive(false);
cache[type].Enqueue(newObject);
return;
/// <summary>
/// 返还给对象池
/// </summary>
/// <param name="type">对象类别</param>
/// <param name="gameObject">对象</param>
public void ReturnPool(ObjectType type, GameObject gameObject)
gameObject.SetActive(false);
cache[type].Enqueue(gameObject);
/// <summary>
/// 取出一个对象
/// </summary>
/// <param name="type">对象类别</param>
/// <returns>取出的对象</returns>
public GameObject GetFromPool(ObjectType type)
if (cache[type].Count == 0)
FillPoll(type);
//出队
var outObject = cache[type].Dequeue();
//启用
outObject.SetActive(true);
return outObject;
技能系统的设计也比较难,为了保证可扩展性,代码改了又改,下面是技能类的实现和火球术的实现。
技能类的实现:
/// <summary>
/// 技能类
/// </summary>
public class Skill
protected PlayerSkillController playerSkillController; //玩家技能控制器
public Image CDImage; //CD的UI组件
//冷却时间
protected float coolDown;
//冷却时间计时器
protected float cdTimer;
//技能在技能栏中的位置
private int index;
//是否可用
public bool Available get; set;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="coolDown">冷却时间</param>
/// <param name="index">技能在技能栏中的位置</param>
protected Skill(float coolDown, int index, PlayerSkillController playerSkillController)
this.coolDown = coolDown;
cdTimer = coolDown;
Available = true;
this.index = index;
this.playerSkillController = playerSkillController;
/// <summary>
/// 计算冷却时间
/// </summary>
protected void UpdateCD()
if (cdTimer < coolDown)
cdTimer += Time.deltaTime;
else
cdTimer = coolDown;
CDImage.fillAmount = (coolDown - cdTimer) / coolDown;
/// <summary>
/// 使用技能
/// </summary>
/// <returns>使用成功返回true; 失败返回false</returns>
protected bool Use()
if (cdTimer == coolDown && Available)
cdTimer = 0;
return true;
return false;
火球术的实现:
/// <summary>
/// 火球术
/// </summary>
public class FireBall : Skill, ISkill
/// <summary>
/// 构造函数
/// </summary>
/// <param name="coolDown">冷却时间</param>
/// <param name="index">技能在技能栏中的位置</param>
/// <param name="playerSkillController">玩家技能控制器</param>
public FireBall(float coolDown, int index, PlayerSkillController playerSkillController) : base(coolDown, index, playerSkillController)
CDImage = GameObject.FindWithTag("FireBallCD").GetComponent<Image>();
public void Update()
UpdateCD();
public new bool Use()
if (base.Use())
cdTimer = 0;
GameObject fireBall = ObjectPool.instance.GetFromPool(ObjectPool.ObjectType.FireBall);
fireBall.GetComponent<FireBallController>().SetProperty(
playerSkillController.fireBallActiveTime,
playerSkillController.fireBallDamage,
playerSkillController.fireBallSpeed,
playerSkillController.skillDirection,
playerSkillController.transform.position
);
return true;
return false;
游戏内容
游戏目前实现了人物的移动和三种不同类型的技能,怪物的移动和两种不同类型的技能,人物与怪物的受伤提示(颜色变化)和死亡效果,告示牌的互动对话UI系统,游戏的菜单UI系统,游戏的暂停、重开和退出功能,小地图功能等。
技能介绍:
火球术:通过对象池实现。使用了拖尾效果和粒子系统,包括飞行时间限制、碰撞检测、击中碰撞器发生爆炸的效果。
疾步:通过对象池实现人物残影效果,移速增加Buff。
掌心雷:通过Trigger实现检测怪物与三段伤害,通过RaycastHit2D实现遮挡识别。
怪物技能:
旋风:通过对象池实现,通过旋转矩阵实现8个方向同时发射。
风阵:通过Trigger实现检测玩家与持续伤害。
怪物实现:
通过仇恨距离与RaycastHit2D实现怪物仇恨系统与追随玩家功能。
通过随机方式选择怪物技能。
部分C#脚本:
推荐教程:
B站UP主: M_Studio
YouTuber:CouchFerret makes Games或B站搬运
以上是关于我用Unity制作的第一款游戏Demo的主要内容,如果未能解决你的问题,请参考以下文章