You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2017中触摸3D物体实现int自增与GameObject隐藏的问题求助

嘿,我太懂你在旧版Unity里找适配方案的抓狂了——2017.1.0f3确实和现在的新版本差异不小,很多教程里的新特性根本用不了。针对你的需求,我给你整理了一套完全适配这个版本的解决方案,分步骤来:

核心实现步骤

1. 搭建全局管理类(单例模式,适配C#4)

首先需要一个全局管理器,用来记录货币数量和每种可收集类型的解锁状态,写法要贴合旧版Unity的特性:

using UnityEngine;

public class CollectibleManager : MonoBehaviour
{
    // 单例实例,保证全局唯一
    public static CollectibleManager Instance;

    // 货币数量(整数类型)
    private int _currency = 0;
    public int Currency { get { return _currency; } }

    // 记录每种类型的可收集状态,key为类型名称(比如"Coin")
    private System.Collections.Generic.Dictionary<string, bool> _typeCollectibleState;

    void Awake()
    {
        // 单例初始化逻辑
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }

        _typeCollectibleState = new System.Collections.Generic.Dictionary<string, bool>();
    }

    // 货币增加方法
    public void AddCurrency(int amount)
    {
        _currency += amount;
        Debug.Log("当前货币: " + _currency);
        // 这里可以添加UI更新逻辑,比如找到Text组件赋值显示
    }

    // 设置指定类型的可收集状态
    public void SetTypeCollectible(string type, bool canCollect)
    {
        if (_typeCollectibleState.ContainsKey(type))
        {
            _typeCollectibleState[type] = canCollect;
        }
        else
        {
            _typeCollectibleState.Add(type, canCollect);
        }
    }

    // 获取指定类型的可收集状态
    public bool CanCollectType(string type)
    {
        if (_typeCollectibleState.ContainsKey(type))
        {
            return _typeCollectibleState[type];
        }
        // 未记录过的类型默认允许收集
        return true;
    }
}

把这个脚本挂在一个空物体上,命名为CollectibleManager,确保场景里只存在一个该物体。

2. 给可收集物体挂交互脚本

每个需要被触摸收集的3D物体,都挂上这个Collectible脚本,记得在Inspector面板里设置类型名称(比如输入"Coin"):

using UnityEngine;

public class Collectible : MonoBehaviour
{
    // 可收集类型名称,在Inspector中配置
    public string collectibleType;

    // 标记物体是否处于可收集状态
    private bool _isActive = true;

    void Start()
    {
        // 初始化时同步管理器的状态,设置自身是否激活
        _isActive = CollectibleManager.Instance.CanCollectType(collectibleType);
        gameObject.SetActive(_isActive);
    }

    // 触发收集逻辑的方法
    public void OnCollected()
    {
        if (!_isActive) return;

        // 1. 隐藏当前物体
        _isActive = false;
        gameObject.SetActive(false);

        // 2. 增加1个货币
        CollectibleManager.Instance.AddCurrency(1);

        // 3. 激活同类型的下一个可收集物体
        FindAndActivateNextCollectible();
    }

    // 查找并激活同类型的下一个未激活物体
    private void FindAndActivateNextCollectible()
    {
        Collectible[] allCollectibles = FindObjectsOfType<Collectible>();
        foreach (Collectible col in allCollectibles)
        {
            if (col.collectibleType == collectibleType && !col.gameObject.activeSelf)
            {
                col._isActive = true;
                col.gameObject.SetActive(true);
                CollectibleManager.Instance.SetTypeCollectible(collectibleType, true);
                break;
            }
        }

        // 如果没有下一个同类型物体,标记该类型不可收集(可选逻辑)
        bool hasUncollected = false;
        foreach (Collectible col in allCollectibles)
        {
            if (col.collectibleType == collectibleType && !col.gameObject.activeSelf)
            {
                hasUncollected = true;
                break;
            }
        }
        if (!hasUncollected)
        {
            CollectibleManager.Instance.SetTypeCollectible(collectibleType, false);
        }
    }
}

3. 触摸3D物体的检测逻辑(适配Unity2017触摸输入)

因为是3D物体,需要用射线检测判断触摸位置是否命中目标,创建TouchInputHandler脚本挂在主相机上:

using UnityEngine;

public class TouchInputHandler : MonoBehaviour
{
    void Update()
    {
        // 处理移动端触摸输入(Unity2017的Input.GetTouch可用)
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            // 只处理触摸开始的阶段,避免重复触发
            if (touch.phase == TouchPhase.Began)
            {
                Ray ray = Camera.main.ScreenPointToRay(touch.position);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    Collectible collectible = hit.collider.GetComponent<Collectible>();
                    if (collectible != null && collectible.gameObject.activeSelf)
                    {
                        collectible.OnCollected();
                    }
                }
            }
        }

        // 编辑器测试用:鼠标点击代替触摸
        #if UNITY_EDITOR
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                Collectible collectible = hit.collider.GetComponent<Collectible>();
                if (collectible != null && collectible.gameObject.activeSelf)
                {
                    collectible.OnCollected();
                }
            }
        }
        #endif
    }
}

4. 旧版本Unity注意事项

  • 确保所有可收集物体都添加了Collider组件(比如Mesh Collider或Box Collider),且不要勾选IsTrigger(射线检测需要实体碰撞体)。
  • 如果物体是动态的,记得添加Rigidbody组件并设置为Kinematic,避免物理影响。
  • C#4不支持部分新语法,代码里已经避开了$字符串插值、?.空判断等特性,完全兼容旧版本。

这样就能实现你要的效果:玩家触摸3D物体后,物体消失、货币+1,同时同类型的下一个物体被激活可收集,直到所有同类型物体收集完毕。

内容的提问来源于stack exchange,提问作者dugofound

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:17:49