简单的CS拾取枪和子弹到背包

该文章描述了在Unity3D中创建一个背包系统的实现过程,包括给枪械和图片添加标签、克隆模型到地图和背包UI、使用触发器进行交互、以及处理预捡和丢弃物品的逻辑。通过遍历和判断,确保物品能正确地在预捡和背包之间转换,并处理重复物品的情况。此外,还涉及到了子弹丢弃功能,每次丢弃减少10发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现这个功能的逻辑

给枪的模型预制体和图片添加标签和对应的名字,模型预制体放在地图上(克隆),图片预制体对应的克隆在背包UI上面,使用触发器触发,这里用了2个背包UI,一个当你邹建触发范围克隆在预捡UI上,给预制体添加一个按钮,添加按钮事件点击把预捡UI上的预制体销毁,克隆到背包中去,销毁预制体模型和预捡UI上的图片预制体

我这里使用多次遍历判断

需要定义出来的

    private int ab = 0;
    private Transform player;
    private GameObject Pan1, Pan2;
    private GameObject[] ge, Ge;
    public GameObject[] Wuqi;//武器预制体
    public GameObject Zd;//子弹预制体
    private bool b = false;//背包开关
    private Button pickup;//预制体按钮

动态获取到对应的东西,这里需要注意一般在项目中预制体是克隆出出来的,我这里是直接拖拽到地图上的;使用背包的格子可以直接通过标签拿,克隆出来的直接拿,可能会出现背包格子没出按顺序放进集合中或者报空的情况出现,这里推荐获取到Pandel,通过循环把子物体(格子)放进集合中;下面是我的简单实现

        ge = GameObject.FindGameObjectsWithTag("Ge");//获取捡武器提示的UI格子
        Ge = GameObject.FindGameObjectsWithTag("BGe");//背包

        Pan1= GameObject.Find("B1");
        Pan2= GameObject.Find("Bag");
        //这里需要注意,必须先把背包格子存进数组,在关闭UI,否则数组为空
        Pan1.SetActive(false);
        Pan2.SetActive(b);

 下面就是一个简单的背包开关, 在Update中调用

    private void Bags()//背包开关
    {
        if (Input.GetKeyDown(KeyCode.B))//判断背包状态给开关
        {
            b = !b;
            Pan2.SetActive(b);
        }
    }

通过ab的值来判断预捡UI的开启和关闭,在update里调用

        if (ab == 0)
        {
            Pan1.SetActive(false);
        }

触发事件

需要对背包的物体进行操作的,给预制体添加脚本获取到对应的按钮添加按钮事件

    private void OnTriggerEnter(Collider other)//开始触发
    {
        if (other.CompareTag("Q1"))//碰到是枪
        {
            Pan1.SetActive(true);
            for (int i = 0; i < Wuqi.Length; i++)
            {
                if (other.name == Wuqi[i].name)
                {
                    GameObject go = Instantiate(Wuqi[i]);
                    for (int j = 0; j < ge.Length; j++)
                    {
                        //预捡UI的格子的子物体为0
                        if (ge[j].transform.childCount == 0)
                        {
                            ab++;
                            //设置这个格子为父物体,居中,台哦出循环
                            go.transform.SetParent(ge[j].transform);
                            go.transform.localPosition = Vector3.zero;
                            //获取到预制体的按钮
                            pickup = go.transform.GetChild(0).GetComponent<Button>();
                            pickup.onClick.AddListener(() =>
                            {
                                //把捡到的预制体放进背包里
                                for (int a = 0; a < Ge.Length; a++)
                                {
                                    GameObject go1 = Instantiate(go);
                                    if (Ge[a].transform.childCount == 0)
                                    {
                                        ab--;
                                        print(ab);
                                        //这里需要注意先在bagUI克隆 再销毁 否则图片可能会消失                                       
                                        go1.transform.SetParent(Ge[a].transform);
                                        go1.transform.localPosition = Vector3.zero;

                                        //销毁对应的UI和物体 
                                        Destroy(go);
                                        Destroy(other.gameObject);                                                                          
                                        break;
                                    }
                                    else if (Ge[a].transform.childCount > 0 && Ge[a].name.Equals(go1.name))
                                    {
                                        //枪的逻辑 这里可以相同的枪只能捡一把
                                        print("你已经拥有此武器,无法拾取");
                                        break;
                                    }
                                }
                            });
                            break;
                        }                        
                    }
                }
            }
        }
        if (other.CompareTag("ZD"))
        {
            Pan1.SetActive(true);
            for (int i = 0; i < Zd.Length; i++)
            {
                if (other.name.Equals(Zd[i].name))
                {
                    GameObject go = Instantiate(Zd[i]);
                    for (int j = 0; j < ge.Length; j++)
                    {
                        if (ge[j].transform.childCount == 0)
                        {
                            ab++;
                            //设置这个格子为父物体,居中,台哦出循环
                            go.transform.SetParent(ge[j].transform);
                            go.transform.localPosition = Vector3.zero;
                            //获取到预制体的按钮
                            pickup = go.transform.GetChild(0).GetComponent<Button>();
                            pickup.onClick.AddListener(() =>
                            {
                                bool c = true;
                                ab--;
                                GameObject go1 = Instantiate(go);
                                for (int a = 0; a < Ge.Length; a++)
                                {
                                    if (Ge[a].transform.childCount > 0 && Ge[a].transform.GetChild(0).name.Equals(go1.name))
                                    {
                                        //获取到文本框  给文本框加值   玩家开枪调用这个文本框
                                        int s = int.Parse(Ge[a].transform.GetChild(0).GetChild(1).GetComponent<Text>().text) + 10;
                                        Ge[a].transform.GetChild(0).GetChild(1).GetComponent<Text>().text = s.ToString();

                                        //销毁对应的UI和物体 
                                        Destroy(go);
                                        Destroy(go1);
                                        Destroy(other.gameObject);
                                        break;
                                    }
                                }
                                if (c)//当背包的格子内没有这个预制体并且格子的子物体为空
                                {
                                    for (int d = 0; d < Ge.Length; d++)
                                    {
                                        go1.transform.SetParent(Ge[d].transform);
                                        go1.transform.localPosition = Vector3.zero;

                                        //销毁对应的UI和物体 
                                        Destroy(go);
                                        Destroy(other.gameObject);
                                        break;
                                    }
                                }
                            });
                            break;
                        }                        
                    }
                }
                break;
            }
        }
    }

结束触发

销毁对应的预捡UI上对应的图片,这里有点小问题这能按照你触发的先后顺序销毁,触发范围调小一点也可以用实现效果(有大佬有好的方法欢迎交流,后面我想到了方法我也会及时更新)

   private void OnTriggerExit(Collider other)//结束触发
    {
        if (other.CompareTag("Q1") || other.CompareTag("ZD"))
        {
            for (int i = 0; i < ge.Length; i++)
            {
                if (ge[i].transform.childCount > 0)
                {
                    Destroy(ge[i].transform.GetChild(0).gameObject);
                    break;
                }
            }
        }
    }

我给子弹做了丢弃按钮,每盒子弹10发,所以我的逻辑是没丢一次-10(这个脚本挂在在子弹图片的预制体上)

public class Cartridge : MonoBehaviour
{
    //子弹预制体脚本
    private Button discardBtn;//丢子弹的按钮
    private Text tag;

    void Start()
    {
        //获取到按钮和文本框
        tag = transform.GetChild(1).GetComponent<Text>();
        discardBtn = transform.GetChild(2).GetComponent<Button>();
        //给按钮添加监听事件
        discardBtn.onClick.AddListener(Discard);       
    }
    void Discard()
    {
        int zd=int.Parse(tag.text);
        if (zd> 10)
        {
            zd-=10;
            tag.text=zd.ToString();
            //克隆一个子弹预制体在玩家的位置  这里我没写哦
        }
        else if (zd <= 10)
        {
            zd = 0;
            tag.text = zd.ToString();
            //克隆一个子弹预制体在玩家的位置
            Destroy(this.gameObject);
        }
    }
   
}

总的来说这个背包需要多次遍历,需要细心,注意跳出循环,不然克隆的位置就不是按顺序克隆在背包格子上;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值