最明显的方法是使用预制件和图层或标签。
您可以在预制件中添加标签(例如“可选”)或将预制件移动到某个“可选”层,然后围绕此编写代码,知道所有可选项目都在该层上/具有此标签。
执行此操作的另一种方法(在我看来也是一种更好的方法)是实现您的自定义“可选”组件。如果您已找到该组件,您将在单击的项目上搜索此组件,然后执行选择。这种方式更好,因为您可以在此组件中添加一些额外的选择逻辑,否则这些逻辑将驻留在您的选择主脚本中(在您添加几个可选择项后显示脚本的大小)。
你可以通过实现一个 SelectableItem 脚本(名称是任意的)和它的几个派生来做到这一点:
public class SelectableItem : MonoBehavior {
public virtual void OnSelected() {
renderer.material.color = red;
}
}
public class SpecificSelectable : SelectableItem {
public override void OnSelected() {
//You can do whatever you want in here
renderer.material.color = green;
}
}
//Adding new selectables is easy and doesn't require adding more code to your master script.
public class AnotherSpecificSelectable : SelectableItem {
public override void OnSelected() {
renderer.material.color = yellow;
}
}
在你的主脚本中:
// Somewhere in your master selection script
// These values are arbitrary and this whole mask thing is optional, but would improve your performance when you click around a lot.
var selectablesLayer = 8;
var selectablesMask = 1 << selectablesLayer;
//Use layers and layer masks to only raycast agains selectable objects.
//And avoid unnecessary GetComponent() calls.
if (Physics.Raycast(ray, out hit, 1000.0f, selectablesMask))
{
var selectable = hit.collider.gameObject.GetComponent<SelectableItem>();
if (selectable) {
// This one would turn item red or green or yellow depending on which type of SelectableItem this is (which is controlled by which component this GameObject has)
// This is called polymorphic dispatch and is one of the reasons we love Object Oriented design so much.
selectable.OnSelected();
}
}
假设您有几个不同的可选择项,并且您希望它们在选择时执行不同的操作。这就是你这样做的方式。您的一些可选择项将具有选择组件之一,而其他选项将具有另一个。执行选择的逻辑位于主脚本中,而必须执行的操作位于附加到游戏对象的特定脚本中。
您可以更进一步,在这些 Selectables 中添加 OnUnselect() 操作:
public class SelectableItem : MonoBehaviour {
public virtual void OnSelected() {
renderer.material.color = red;
}
public virtual void OnUnselected() {
renderer.material.color = white;
}
}
然后甚至做这样的事情:
//In your master script:
private SelectableItem currentSelection;
var selectable = hit.collider.gameObject.GetComponent<SelectableItem>();
if (selectable) {
if (currentSelection) currentSelection.OnUnselected();
selectable.OnSelected();
CurrentSelection = selectable;
}
我们刚刚添加了取消选择逻辑。
免责声明:这些只是一堆 sn-ps。如果您只是复制并粘贴它们,它们可能不会立即起作用。