定义枪数据
[CreateAssetMenu(menuName = "Data/Gun")]
public class GunData : ScriptableObject
{
public int Index;//索引
public string Name;//名称
public GameObject GunPrefab;//枪预制体
}
在枪预制体上,绑定GunItem 代码,控制拾取和绑定GunData 枪数据
public class GunItem : MonoBehaviour {
public GunData thisGunData;//绑定枪
}
新增GunManager,管理枪支丢弃拾取和切换
public class GunManager : Singleton<GunManager>
{
Dictionary<int, GunData> gunDictionary = new Dictionary<int, GunData>();
[HideInInspector]
public GunData thisGunData;//当前选中
public Transform fpsCam;
public Transform[] childObjects;
private void Update()
{
// 数字切换武器
if (Input.GetKeyDown(KeyCode.Alpha1))
{
SwitchGun(1);
}
else if (Input.GetKeyDown(KeyCode.Alpha2))
{
SwitchGun(2);
}
else if (Input.GetKeyDown(KeyCode.Alpha3))
{
SwitchGun(3);
}
//丢弃枪
if (Input.GetKeyDown(KeyCode.G))
{
// 丢弃物体
Drop();
}
// 遍历资源字典,输出每个资源类型及其对应的数量
foreach (int index in gunDictionary.Keys)
{
Debug.Log(gunDictionary[index].Name);
}
}
private void Drop()
{
if(thisGunData == null) return;
var res = Instantiate(thisGunData.GunPrefab, fpsCam.position+fpsCam.forward * 0.4f, Quaternion.identity);
var rb = res.GetComponent<Rigidbody>();
// 添加力
rb.AddForce(fpsCam.forward * 5f, ForceMode.Impulse);
rb.AddForce(fpsCam.up * 10f, ForceMode.Impulse);
// 添加随机旋转
float random = UnityEngine.Random.Range(-1f, 1f);
rb.AddTorque(new Vector3(random, random, random) * 10);
//隐藏当前武器
childObjects[thisGunData.Index - 1].gameObject.SetActive(false);
RemoveGun();
thisGunData = null;
}
// 切换武器
public void SwitchGun(int index)
{
// 如果资源字典中没有该编号的资源,直接返回
if (!gunDictionary.ContainsKey(index))
{
return;
}
// 隐藏当前武器
if (thisGunData != null)
{
childObjects[thisGunData.Index - 1].gameObject.SetActive(false);
}
// 显示新的武器
thisGunData = gunDictionary[index];
childObjects[thisGunData.Index - 1].gameObject.SetActive(true);
}
//判断是否已存在枪
public bool isGun(GunData gunData)
{
return gunDictionary.ContainsKey(gunData.Index);
}
//添加
public void AddGun(GunData gunData)
{
gunDictionary.Add(gunData.Index, gunData);
}
//删除当前
public void RemoveGun()
{
gunDictionary.Remove(thisGunData.Index);
}
}
记得配置枪支碰撞检测为持续,防止丢弃时掉入地底
并且禁用枪支预制体和人物的碰撞
拾取脚本
using UnityEngine;
//拾取脚本
public class PickUpController : MonoBehaviour
{
public float maxDistance = 3f; // 最大检测距离
public LayerMask layerMask; // 检测层级
public GameObject uiText; // 显示物品名称的 UI 文本组件
void Start()
{
uiText.SetActive(false); // 初始状态下 UI 文本组件不可见
}
void Update()
{
// 从相机屏幕中心向前发射一条射线
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, maxDistance, layerMask))
{
uiText.SetActive(true);
//hitInfo.transform.CompareTag("PickUpItem") 需要的话可以再加标签判断
if (Input.GetKeyDown(KeyCode.E))
{
PickUpItem(hitInfo.transform);
}
}
else
{
uiText.SetActive(false);
}
}
// 拾取物体
void PickUpItem(Transform item)
{
GunData thisGunData = item.GetComponent<GunItem>().thisGunData;
if (GunManager.Instance.isGun(thisGunData))
{
Debug.Log("位置已存在枪");
}
else
{
GunManager.Instance.AddGun(thisGunData);
GunManager.Instance.SwitchGun(thisGunData.Index);
Destroy(item.gameObject);
}
}
}
配置参数,记得修改拾取枪支预制体层级为GunItem,拾取文本就随便添加一个可以了
效果
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~