实现这个功能的逻辑
给枪的模型预制体和图片添加标签和对应的名字,模型预制体放在地图上(克隆),图片预制体对应的克隆在背包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);
}
}
}
总的来说这个背包需要多次遍历,需要细心,注意跳出循环,不然克隆的位置就不是按顺序克隆在背包格子上;