C# 使用由不同按钮生成的按钮销毁预制的克隆
我正在做一个Unity项目,在这个项目中,当从下拉按钮列表中选择时,立方体、球体和圆柱体等3D对象会出现在屏幕中央。实例化脚本工作正常,但所有3个对象都会生成并彼此合并。当其中一个被实例化时,它将销毁另外两个。我面临的问题是,生成的对象是一个克隆,我无法将其销毁。我是一个统一的初学者,并试图学习。我粘贴了下面的代码,为每个按钮创建了3个,并根据对象更改了参数C# 使用由不同按钮生成的按钮销毁预制的克隆,c#,unity3d,C#,Unity3d,我正在做一个Unity项目,在这个项目中,当从下拉按钮列表中选择时,立方体、球体和圆柱体等3D对象会出现在屏幕中央。实例化脚本工作正常,但所有3个对象都会生成并彼此合并。当其中一个被实例化时,它将销毁另外两个。我面临的问题是,生成的对象是一个克隆,我无法将其销毁。我是一个统一的初学者,并试图学习。我粘贴了下面的代码,为每个按钮创建了3个,并根据对象更改了参数 using System.Collections; using System.Collections.Generic; using Uni
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Cube_Inst : MonoBehaviour
{
public GameObject box;
public Transform pos;
public bool trigger;
public Button yourButton;
public GameObject Sphere_Destroy;
public GameObject Cylinder_Destroy;
void Start()
{
Button btn = yourButton.GetComponent<Button>();
btn.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
trigger = true;
Destroy(Sphere_Destroy);
Destroy(Cylinder_Destroy);
}
public void Update()
{
if (trigger == true)
{
Instantiate(box, pos.position, pos.rotation);
trigger = false;
}
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.UI;
公共类多维数据集研究所:单一行为
{
公共游戏对象盒;
公共转换pos;
公共布尔触发器;
公共按钮你的按钮;
公共游戏对象球_销毁;
公共游戏对象的圆柱体(u)破坏;;
void Start()
{
Button btn=yourButton.GetComponent();
btn.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
触发器=真;
破坏(球体破坏);
破坏(圆柱体破坏);
}
公共无效更新()
{
如果(触发器==真)
{
实例化(框、位置、位置旋转);
触发器=假;
}
}
}
您更应该实现整个事情的集中化(“单一责任模式”)
不要让单独的按钮有单独的脚本,它们之间有大量的交叉引用
而是有一个中央控制器组件,让按钮将不同的参数传递给通用的spawn方法
此外,您还应该执行事件驱动的操作—您已经知道单击按钮的时刻—而不是在Update
方法中轮询检查标志。
我会用像这样的东西
// Put this on ONE object that is always active in the Scene
public class SpawnController : MonoBehaviour
{
private GameObject _currentClone;
private GameObject _currentPrefab;
public void SetInstance(GameObject prefab, Vector3 position, Quaternion rotation)
{
// Was the same prefab passed again? -> Ignore
if(prefab == _currentPrefab) return;
_currentPrefab = prefab;
// Already exists a clone? -> Destroy it
if(_currentClone) Destroy(_currentClone);
// Create and store the new clone
_currentClone = Instantiate (prefab, position, rotation);
}
}
public class SpawnController : MonoBehaviour
{
private GameObject _currentClone;
private Button _lastClickedButton;
private void Awake()
{
SpawnButton.OnSpawnButtonClicked += SetInstance;
}
private void SetInstance(Button button, GameObject prefab, Vector3 position, Quaternion rotation)
{
// Was the same button pressed again? -> Ignore
if(button == _lastClickedButton) return;
_lastClickedButton = button;
// Already exists a clone? -> Destroy it
if(_currentClone) Destroy(_currentClone);
// Create and store the new clone
_currentClone = Instantiate (prefab, position, rotation);
}
}
因此,如果调用SetInstance
,它会自动销毁任何现有实例
然后在每个按钮上都有相同的组件,但只相应地配置它们
public class SpawnButton : MonoBehaviour
{
// Already reference this via the Inspector if possible
// If not we will get it on runtime as fallback
[SerializeField] private Button _button;
// For each different button reference a different prefab
[SerializeField] private GameObject _prefab;
// Reference the spawn point
[SerializeField] private Transform _spawnPoint;
// Here drag in the SpawnController from the scene if possible
// if not, we will find it on runtime as fallback
[SerializeField] private SpawnController _spawnController;
private void Awake()
{
if(!_button) _button = Get component<Button>();
_button.onClick.AddListener(DoSpawn());
if(!_spawnController) _spawnController = FindObjectOfType<SpawnController>();
}
private void DoSpawn()
{
// Only tell the SpawnController to do its thing
// This button doesn't have to know or care what that means for the Scene
_spawnController.SetInstance(_prefab, _spawnPoint.position, _spawnPoint.rotation);
}
}
然后
public class SpawnButton : MonoBehaviour
{
public static event Action<Button, GameObject, Vector3, Quaternion> OnSpawnButtonClicked;
// Already reference this via the Inspector if possible
// If not we will get it on runtime as fallback
[SerializeField] private Button _button;
// For each different button reference a different prefab
[SerializeField] private GameObject _prefab;
// Reference the spawn point
[SerializeField] private Transform _spawnPoint;
private void Awake()
{
if(!_button) _button = Get component<Button>();
_button.onClick.AddListener(DoSpawn());
}
private void DoSpawn()
{
// Only Invoke the event
// You don't care if or who is listening
OnSpawnButtonClicked?.Invoke(this, _prefab, _spawnPoint.position, _spawnPoint.rotation);
}
}
公共类按钮:单行为
{
公共静态事件动作OnSpawnButtonClicked;
//如果可能的话,已经通过检查员参考了这一点
//如果不是,我们将在运行时将其作为回退
[序列化字段]专用按钮\u按钮;
//对于每个不同的按钮参考,使用不同的预设
[SerializeField]私有游戏对象预制;
//参考繁殖点
[SerializeField]专用转换点;
私人空间
{
如果(!\u按钮)\u按钮=获取组件();
_button.onClick.AddListener(DoSpawn());
}
私人银行
{
//只调用事件
//你不在乎是否或谁在听
OnSpawnButtonClicked?.Invoke(这个,_预置,_spawnPoint.position,_spawnPoint.rotation);
}
}
非常感谢您的支持。真的很感激