【unity实战】FPS实现拾取和丢弃枪

发布时间:2024年01月22日

最终效果

在这里插入图片描述

定义枪物品

定义枪数据

[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是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

文章来源:https://blog.csdn.net/qq_36303853/article/details/135428304
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。