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
相关产品推荐
相关产品推荐

