Unity C#跨类调用方法/变量及代码结构优化咨询
问题解答
能不能直接用className.MethodName()形式跨类调用?
不行。继承自MonoBehaviour的类,非静态方法/变量必须通过实例对象调用,不能直接用类名访问;如果把方法改成静态,会和MonoBehaviour的组件特性冲突(静态类无法挂载为组件,静态方法也无法使用MonoBehaviour的生命周期函数、组件引用等),所以这条路走不通。
低改动优化方案
方案1:直接引用PauseMenu实例(最直观)
在Menu_Buttons类中添加PauseMenu类型的引用字段,通过Unity编辑器绑定实例后调用方法:
public class Menu_Buttons : MonoBehaviour { // 新增:绑定场景中的PauseMenu组件 public PauseMenu pauseMenuRef; // 新增:继续游戏方法 public void Menu_ResumeClick() { pauseMenuRef.ClosePauseMenu(); } // 原有方法保持不变 public void Menu_NewGameClick() { SceneManager.LoadScene(1); } public void Menu_ContinueClick() { Debug.Log("This will continue the game from the last save"); } public void Menu_LoadGameClick() { SceneManager.LoadScene(1); Debug.Log("Another menu will show to choose which save to load"); } public void Menu_SaveGameClick() { SaveItem(); Debug.Log("This will save the game"); } public void Menu_OptionsClick() { Debug.Log("This will show the game options"); } public void Menu_QuitClick() { Application.Quit(); Debug.Log("The Game should quit now"); } }
操作步骤:在Unity编辑器中,找到挂载Menu_Buttons的对象,把场景中挂载PauseMenu的对象拖到pauseMenuRef字段上即可。
方案2:单例模式(适合全局唯一的暂停菜单)
给PauseMenu添加静态单例实例,无需手动绑定引用,直接通过类名访问实例:
public class PauseMenu : MonoBehaviour { // 新增:静态单例实例 public static PauseMenu Instance; public GameObject pauseMenu; void Awake() { // 初始化单例 Instance = this; } void Update() { if (Input.GetKeyDown(KeyCode.B)) { if (pauseMenu.activeSelf) { ClosePauseMenu(); } else { OpenPauseMenu(); } } } public void OpenPauseMenu() { pauseMenu.SetActive(true); Cursor.visible = true; Cursor.lockState = CursorLockMode.Confined; Time.timeScale = 0f; } public void ClosePauseMenu() { pauseMenu.SetActive(false); Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; Time.timeScale = 1f; } }
然后在Menu_Buttons中新增方法:
public class Menu_Buttons : MonoBehaviour { // 新增:继续游戏方法 public void Menu_ResumeClick() { PauseMenu.Instance.ClosePauseMenu(); } // 原有方法保持不变... }
这种方式适合场景中只有一个PauseMenu的情况,改动极小,调用也方便。
方案3:动态查找组件(零编辑器绑定,适合快速测试)
如果不想加字段或单例,可以在调用时动态查找场景中的PauseMenu组件:
public class Menu_Buttons : MonoBehaviour { // 新增:继续游戏方法 public void Menu_ResumeClick() { // 查找场景中第一个PauseMenu组件 PauseMenu pauseMenu = FindObjectOfType<PauseMenu>(); if(pauseMenu != null) { pauseMenu.ClosePauseMenu(); } } // 原有方法保持不变... }
注意:FindObjectOfType会遍历场景对象,效率略低,适合小场景或测试用,正式项目更推荐前两种方案。
内容的提问来源于stack exchange,提问作者Marcin Pagórek
相关产品推荐
相关产品推荐

