我用Unity制作的第一款游戏Demo

Immortal(不朽)

我用Unity制作的第一款游戏Demo_游戏开发

这是我使用 Unity 制作的第一款游戏Demo,一款2D的RPG游戏。

游戏中所有工作均为本人独立完成。

美术方面

哎,早知道该好好学学画画的,对队来说制作这个Demo最耗时、最难的工作就是画画了,画个老半天还是惨不忍睹。

为了不至于不堪入目,果断选择了2D像素风格,游戏中所有的Sprite和Image都是使用Aseprite制作的,比起PS,Aseprite绘制像素画太方便了,爱了爱了。

我用Unity制作的第一款游戏Demo_游戏开发_02不知不觉都肝了150多个小时了。。。

我用Unity制作的第一款游戏Demo_游戏开发_03

角色移动动画

我用Unity制作的第一款游戏Demo_游戏开发_04

爆炸动画

每个像素都是泪呀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;
    }
}

游戏内容

我用Unity制作的第一款游戏Demo_游戏开发_05

游戏目前实现了人物的移动和三种不同类型的技能,怪物的移动和两种不同类型的技能,人物与怪物的受伤提示(颜色变化)和死亡效果,告示牌的互动对话UI系统,游戏的菜单UI系统,游戏的暂停、重开和退出功能,小地图功能等。

技能介绍:

火球术:通过对象池实现。使用了拖尾效果和粒子系统,包括飞行时间限制、碰撞检测、击中碰撞器发生爆炸的效果。

疾步:通过对象池实现人物残影效果,移速增加Buff。

掌心雷:通过Trigger实现检测怪物与三段伤害,通过RaycastHit2D实现遮挡识别。

怪物技能:

旋风:通过对象池实现,通过旋转矩阵实现8个方向同时发射。

风阵:通过Trigger实现检测玩家与持续伤害。

怪物实现:

通过仇恨距离与RaycastHit2D实现怪物仇恨系统与追随玩家功能。

通过随机方式选择怪物技能。

部分C#脚本:

我用Unity制作的第一款游戏Demo_游戏开发_06图片来源:http://www.hp91.cn/  h5游戏