我有一个简单的触摸/鼠标点击脚本附加到GameObject作为一种"主脚本"即GameObject是不可见的,除了在游戏运行时持有此Touch脚本时,它不会做任何事情。
如何告诉在运行时生成的其他命名游戏对象执行以下操作:触摸/点击此主脚本时突出显示?
突出显示的脚本似乎是:renderer.material.color = colorRed;
但我不确定如何告诉点击的GameObject从主脚本中突出显示。
请帮忙! (我用C#编程) 谢谢!
答案 0 :(得分:1)
好吧,如果你没有在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“经理”的问题
我会做两种选择之一。 之一:
// 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";
OR
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;
我在另一个答案HERE
中详细介绍了这一点对于鼠标点击,我会查看他们在商店中的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))
解决:强>
在您的经理文件中使用bool true
已被选中,false
未被选中。让您实例化的所有对象都有一个标记,使用从主文件到游戏对象的光线投射。当它是带有该标签的游戏对象时,交换颜色并从主文件中删除bool。可能更好地从主文件内部执行。
(一切都取决于你在做什么)
答案 1 :(得分:0)
如果您知道GameObjects的名称将在运行时,您可以使用GameObject.Find(“”)并将其存储在GameObject变量中。然后,您可以将该GameObject的渲染器设置为您喜欢的任何内容(假设渲染器链接到该GameObject)。
答案 2 :(得分:0)
最明显的做法是使用预制件和图层或标签。 您可以在预制件中添加标签(例如“可选择”)或将预制件移动到某个“可选”图层,然后围绕此编写代码,知道所有可选项都在此图层上/具有此标记。
另一种方法(在我看来也是一种更好的方法)是实现自定义的“可选”组件。如果找到该组件,则可以在单击的项目上搜索此组件,然后执行选择。这种方式更好,因为您可以在此组件中添加一些额外的选择逻辑,否则这些逻辑将驻留在您的选择主脚本中(在您添加几个可选项后,将图像调整为脚本的大小)。
您可以通过实现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();
}
}
所以说你有几个不同的选择,你希望他们在选择时做不同的事情。这是你这样做的方式。您的一些可选择组件将具有一个选择组件,而其他组件将具有另一个组件。执行选择的逻辑驻留在主脚本中,而必须执行的操作位于附加到游戏对象的特定脚本中。
您可以进一步在这些可选项中添加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;
}
我们刚刚添加了取消选择逻辑。
免责声明:这些只是一堆片段。如果你只是复制并粘贴它们,它们可能不会立即起作用。