【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏4(附项目源码)

简介: 【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏4(附项目源码)

前言

欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中,我们将探索如何制作一个类似于七日杀和森林的生存游戏。


本篇内容会比较多,我会分几篇来实现,感兴趣的可以关注一下,以免错过内容更新。


本节主要实现了一个制作系统,并完成一个制作出石斧的功能。


源码

源码不出意外的话我会放在最后一节


制作系统

简单绘制制作系统面板UI

斧头素材

https://sketchfab.com/3d-models/stone-axe-3b634530c2f54128a150f723b6822d7b

代码控制工具栏操作

新增CraftingSystem,控制控制工具栏

public class CraftingSystem : MonoBehaviour
{
    public GameObject craftingScreenUl; // 制作界面UI对象
    public GameObject toolsScreenUl; // 工具界面UI对象

    // 工具按钮
    Button toolsBTN;

    [HideInInspector]
    public bool isOpen; // 是否打开制作系统界面

    // 所有的蓝图
    public static CraftingSystem Instance { get; set; }

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    void Start()
    {
        isOpen = false;
        toolsBTN = craftingScreenUl.transform.Find("背景").Find("工具按钮").GetComponent<Button>();
        toolsBTN.onClick.AddListener(delegate { OpenToolsCategory(); });
    }

    void OpenToolsCategory()
    {
        craftingScreenUl.SetActive(false); // 关闭制作界面
        toolsScreenUl.SetActive(true); // 打开工具界面
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I))
        {
            // 打开关闭制作界面
            craftingScreenUl.SetActive(!isOpen);

            if (isOpen) toolsScreenUl.SetActive(false); // 关闭工具界面

            isOpen = !isOpen;

            // 设置鼠标锁定模式为无锁定,允许鼠标在界面上移动
            Cursor.lockState = (isOpen ||  InventorySystem.Instance.isOpen) ? CursorLockMode.None : CursorLockMode.Locked;
        }
    }
}

修改MouseLook,控制相机视角

void FreeLook()
{
    if(InventorySystem.Instance.isOpen || CraftingSystem.Instance.isOpen) return;
    //。。。
}

挂载代码,配置

效果

image.png

制作石斧

新增Blueprint,定义制作蓝图

public class Blueprint
{
    public string itemName; // 蓝图对应的物品名称
    public string Req1; // 需求1的物品名称
    public string Req2; // 需求2的物品名称
    public int Req1amount; // 需求1的数量
    public int Req2amount; // 需求2的数量
    public int numOfRequirements; // 需求的总数

    // 构造函数
    public Blueprint(string name, int reqNUM, string R1, int R1num, string R2, int R2num)
    {
        itemName = name; // 设置蓝图对应的物品名称
        numOfRequirements = reqNUM; // 设置需求的总数
        Req1 = R1; // 设置需求1的物品名称
        Req1amount = R1num; // 设置需求1的数量
        Req2 = R2; // 设置需求2的物品名称
        Req2amount = R2num; // 设置需求2的数量
    }
}

修改InventorySystem,实现删除物品 更新库存列表功能

//添加物品
public void AddToInventory(string itemName)
{
    //...

    ReCalculeList();
    CraftingSystem.Instance.RefreshNeededItems();
}
    
//删除物品
public void RemoveItem(string nameToRemove, int amountToRemove)
{
    int counter = amountToRemove; // 计数器,表示还需要删除的数量

    for (var i = slotList.Count - 1; i >= 0; i--) // 倒序遍历所有物品槽
    {
        if (slotList[i].transform.childCount > 0) // 如果该槽有物品
        {
            if (slotList[i].transform.GetChild(0).name == nameToRemove + "(Clone)" && counter != 0) // 如果该物品名称匹配且还需要删除的数量不为 0
            {
                Destroy(slotList[i].transform.GetChild(0).gameObject); // 删除该物品
                counter -= 1; // 计数器减 1
            }
        }
    }
    
    ReCalculeList();
    CraftingSystem.Instance.RefreshNeededItems();
}

//更新库存列表
public void ReCalculeList()
{
    itemList.Clear(); // 清空物品清单

    foreach (GameObject slot in slotList) // 遍历所有的物品槽
    {
        if (slot.transform.childCount > 0) // 如果该槽有物品
        {
            string name = slot.transform.GetChild(0).name; // 获取物品名称,例如 "Stone (Clone)"
            string str2 = "(Clone)";
            string result = name.Replace(str2, ""); // 去掉后缀 "(Clone)",例如 "Stone"
            itemList.Add(result); // 将物品名称添加到物品清单列表中
        }
    }
}

修改CraftingSystem

public Blueprint AxeBLP = new Blueprint("石斧", 2, "小石头", 2, "树枝", 2);//石斧制作蓝图

void Start()
{
    isOpen = false;
    toolsBTN = craftingScreenUl.transform.Find("背景").Find("工具按钮").GetComponent<Button>();
    toolsBTN.onClick.AddListener(delegate { OpenToolsCategory(); });

    //斧头
    AxeReq1 = toolsScreenUl.transform.Find("背景").Find("内容").Find("斧头").Find("材料1").GetComponent<TextMeshProUGUI>();
    AxeReq2 = toolsScreenUl.transform.Find("背景").Find("内容").Find("斧头").Find("材料2").GetComponent<TextMeshProUGUI>();
    craftAxeBTN = toolsScreenUl.transform.Find("背景").Find("内容").Find("斧头").Find("制作按钮").GetComponent<Button>();
    craftAxeBTN.onClick.AddListener(delegate { CraftAnyltem(AxeBLP); });
}
 
//制作事件
void CraftAnyltem(Blueprint blueprintToCraft)
{
    InventorySystem.Instance.AddToInventory(blueprintToCraft.itemName);

    //按需求的总数,删除对应的物品
    if (blueprintToCraft.numOfRequirements == 1)
    {
        InventorySystem.Instance.RemoveItem(blueprintToCraft.Req1, blueprintToCraft.Req1amount);
    }
    else if (blueprintToCraft.numOfRequirements == 2)
    {
        InventorySystem.Instance.RemoveItem(blueprintToCraft.Req1, blueprintToCraft.Req1amount);
        InventorySystem.Instance.RemoveItem(blueprintToCraft.Req2, blueprintToCraft.Req2amount);
    }
}

//刷新需要的物品
private void RefreshNeededItems()
{
    int stone_count = 0; // 石头数量
    int stick_count = 0; // 树枝数量

    inventoryltemList = InventorySystem.Instance.itemList; // 获取物品清单

    foreach (string itemName in inventoryltemList) // 遍历物品清单
    {
        switch (itemName)
        {
            case "小石头":
                stone_count += 1; // 统计石头数量
                break;
            case "树枝":
                stick_count += 1; // 统计树枝数量
                break;
        }
    }

    // 更新需求文本
    AxeReq1.text = "2 石头 [" + stone_count + "]"; // 显示需要的石头数量
    AxeReq2.text = "2 树枝 [" + stick_count + "]"; // 显示需要的树枝数量

    if (stone_count >= 2 && stick_count >= 2)
    {
        craftAxeBTN.gameObject.SetActive(true); // 激活制作斧头按钮
    }
    else
    {
        craftAxeBTN.gameObject.SetActive(false); // 禁用制作斧头按钮
    }
}

效果

image.png

目录
相关文章
|
6月前
|
图形学
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
195 0
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏5(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏5(附项目源码)
56 2
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏5(附项目源码)
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏14(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏14(附项目源码)
37 3
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏8(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏8(附项目源码)
24 1
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏13(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏13(附项目源码)
39 1
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏10(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏10(附项目源码)
26 1
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏12(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏12(附项目源码)
29 1
|
6月前
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏9(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏9(附项目源码)
31 1
|
6月前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(上)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)
237 2
|
6月前
|
人工智能 图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏1(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏1(附项目源码)
59 0