我有一个简单的触摸/鼠标点击脚本附加到游戏对象作为一种“主脚本”,即游戏对象是不可见的,除了在游戏运行时保持这个触摸脚本之外什么都不做。
我如何告诉在运行时生成的其他命名游戏对象做一些事情,例如从这个主脚本触摸/点击时突出显示?
高亮的脚本似乎是:renderer.material.color= colorRed;
但我不确定如何告诉单击的游戏对象从主脚本中突出显示。
请帮忙!(我用 C# 编程)谢谢!
我有一个简单的触摸/鼠标点击脚本附加到游戏对象作为一种“主脚本”,即游戏对象是不可见的,除了在游戏运行时保持这个触摸脚本之外什么都不做。
我如何告诉在运行时生成的其他命名游戏对象做一些事情,例如从这个主脚本触摸/点击时突出显示?
高亮的脚本似乎是:renderer.material.color= colorRed;
但我不确定如何告诉单击的游戏对象从主脚本中突出显示。
请帮忙!(我用 C# 编程)谢谢!
好吧,如果您不在 GUI 中使用光线投射,您将需要使用它。查看Unity Ray Casting,然后使用
hit.transform.gameObject.renderer.material.color = red;
你可以有一个像这样的开关:
if (hit.transform.gameObject.CompareTag("tag")) {
// turn to red;
} else {
// turn to white;
}
使用ScreenPointToRay
或ScreenPointToWorld
取决于你在做什么。
对于触摸,应如下所示:
void Update () {
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay(touch.position);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000.0f))
{
if (hit.collider.gameObject.CompareTag("tag"))
{
hit.collider.gameObject.renderer.material.color = red;
}
}
}
// You can also add in a "go back" feature in the update but this will "go back" then when the touch ends or moves off
// Also not so good to search for Objects in the update function but that's at your discretion.
GameObject[] gObjs = GameObject.FindGameObjectsWithTag("tag");
foreach (GameObject go in gObjs) {
go.renderer.material.color = white;
}
}
回答您关于 ping 'manager' 的问题
我会做两种选择之一。任何一个:
// Drop the object containing YourManager into the box in the inspector where it says "manage"
public YourManager manage;
// In the update and in the Ray Cast function (right next to your color change line):
manager.yourCall ();
// and
manager.yourString = "cool";
或者
private YourManager manage;
void Awake () {
manager = GameObject.FindObjectWithTag("manager").GetComponent<YourManager> ();
}
// In the update and in the Ray Cast function (right next to your color change line):
// In your manager file have "public bool selected;" at the top so you can access that bool from this file like:
manager.selected = true;
我在这里的另一个答案中对此进行了详细说明
对于鼠标点击,我会查看他们存储的 MonoDevelop 函数,例如:
// This file would be on the game object in the scene
// When the mouse is hovering the GameObject
void OnMouseEnter () {
selected = true;
renderer.material.color = red;
}
// When the mouse moved out
void OnMouseExit () {
selected = false;
renderer.material.color = white;
}
// Or you can use the same system as above with the:
Input.GetMouseButtonDown(0))
解析度:
在您的管理器文件中使用布尔值true
被选中,false
不是。让您实例化的所有对象都有一个标签,使用从主文件到游戏对象的光线投射。当它是带有该标签的游戏对象时,交换颜色并从主文件中删除布尔值。从主文件内部进行可能更好。(一切都取决于你在做什么)
如果您知道运行时 GameObjects 的名称,您可以使用 GameObject.Find("") 并将其存储在 GameObject 变量中。然后,您可以将该游戏对象的渲染器设置为您喜欢的任何内容(假设渲染器链接到该游戏对象)。
最明显的方法是使用预制件和图层或标签。您可以将标签添加到您的预制件(例如“可选”)或将预制件移动到某个“可选”层,然后围绕此编写代码,知道所有可选项目都在此层上/具有此标签。
另一种方法(在我看来也是一种更好的方法)是实现您的自定义“可选”组件。如果您已找到该组件,您将在单击的项目上搜索此组件,然后执行选择。这种方式更好,因为您可以在此组件中添加一些额外的选择逻辑,否则这些逻辑将驻留在您的选择主脚本中(在您添加了几个可选择项后显示脚本的大小)。
你可以通过实现一个 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;
}
我们刚刚添加了取消选择逻辑。
免责声明:这些只是一堆片段。如果您只是复制并粘贴这些内容,它们可能不会立即起作用。