gpt4 book ai didi

Unity3D 游戏内上下文菜单 - 奇怪的行为

转载 作者:行者123 更新时间:2023-12-03 18:15:47 25 4
gpt4 key购买 nike

当您将另一个对象的操作添加到字典时会发生什么?

首先,我正在尝试设计一些不错的游戏内上下文菜单。我的目标是动态生成每个项目。每个项目都从存储 Action 的字典中加载。从每个游戏对象的最多 3 个组件访问字典,并附加一个 GamePiece 组件。

首先,有一个字典,其中包含作为每种类型 GamePiece 的组件的 Actions:

public class GamePiece : MonoBehaviour {

protected bool rightClickable = true;

protected StatManager statManager;
Transform ui;
CanvasManager canvas;
SpriteRenderer sprite;
Color spriteColor;

public Dictionary<string, Action> actions;

void Awake(){
statManager = GameObject.Find("StatPanel").GetComponent<StatManager>();
actions = new Dictionary<string, Action>();
actions.Add("Deconstruct", Deconstruct);
}

问题是无论我如何填充字典,都会调用最后添加的字典项。因此,如果我要添加一个“Destroy()”调用和一个“SupplyPower()”调用。字典永远只会称呼“Supply Power”。这特别奇怪,因为菜单本身显示的是正确的按钮。

我怀疑问题出在我在同一个游戏对象上添加来自其他组件的字典项。例如,GamePiece 组件保存字典并添加一些基本操作,然后 Generator 组件将访问它并添加对其自己的 SupplyPower() 方法的引用

public class Generator: MonoBehaviour {

public Structure structure;

void Start () {
structure = gameObject.GetComponent<Structure>();
structure.gamePiece.actions.Add("Supply Power", SupplyPower);
}
}

创建上下文菜单时会发生以下情况:

public class ContextMenu : MonoBehaviour {
public Transform menuItem;

//Takes a ref from the calling gameObject, t. And is called from CanvasManager.cs
public void PopulateContextMenu(GameObject t)
{
Transform selections = transform.FindChild("Selections").transform; //Parent for items.

//gamePiece holds the dictionary.
GamePiece gamePiece = t.GetComponent<GamePiece>();
foreach (KeyValuePair<string, Action> kVp in gamePiece.actions)
{
GameObject menuItem =
(GameObject)Instantiate(Resources.Load("MenuItem"));
menuItem.name = kVp.Key;
menuItem.GetComponent<Text>().text = kVp.Key;

//Adding functuionality.
menuItem.GetComponent<Button>().onClick.AddListener
(() => { kVp.Value.Invoke(); });

menuItem.GetComponent<Button>().onClick.AddListener
(() => { CloseContextMenu(); });

menuItem.transform.SetParent(selections, false);
}
}

public void CloseContextMenu()
{
Destroy(this.gameObject);
}
}

从 CanvasManager 类调用 PopulateContextMenu 函数:

public class CanvasManager : MonoBehaviour {

public void ToggleContextMenu(GameObject t) {
GameObject newMenu = (GameObject)Resources.Load("ContextMenu");
newMenu = Instantiate(newMenu) as GameObject;
//Passing gameObject t into PopulatContextMenu
newMenu.GetComponent<ContextMenu>().PopulateContextMenu(t);
}

}

这里,ToggleContextMenu() 是从 gameObjects OnMouseOver() 回调中调用的:

public class GamePiece : MonoBehaviour {

void OnMouseOver(){
if (Input.GetMouseButtonDown(1) && rightClickable) {
canvas.ToggleContextMenu(this.gameObject);
}
}
}

因此,当它被调用时,它会将对自身的引用传递给 CanvasManager,然后从 ContextMenu 移交。

最佳答案

在调用之前将操作存储在本地,您就可以开始了。

在上下文菜单中:

Action newAction =kVp.Value;
menuItem.GetComponent<Button>().onClick.AddListener(() => {newAction.Invoke();});

关于Unity3D 游戏内上下文菜单 - 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36338477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com