C# Unity,编辑器时间脚本,在添加到场景事件的游戏对象上
假设你有一个简单的预制件,“盒子”,我们会说它只不过是一个标准的米立方体C# Unity,编辑器时间脚本,在添加到场景事件的游戏对象上,c#,unity3d,unity3d-editor,C#,Unity3d,Unity3d Editor,假设你有一个简单的预制件,“盒子”,我们会说它只不过是一个标准的米立方体 1-预制框位于项目面板中 2-将其拖动到场景中 3-显然,它现在也出现在层次面板中,并且可能在Inspector中被选中并显示 要明确的是,当你们这样做的时候,游戏并不是在玩,你们只是在普通的编辑器模式下 是否可以制作一个脚本(“编辑器脚本”),以便 当您执行上面的“1”和“2”时,(同样是在编辑器模式下,而不是在游戏期间) 发生3时,我们可以影响场景中的新框项目 因此,简单的例子是:我们将始终将Z位置设置为“2”,
- 1-预制框位于项目面板中
- 2-将其拖动到场景中
- 3-显然,它现在也出现在层次面板中,并且可能在Inspector中被选中并显示
- 当您执行上面的“1”和“2”时,(同样是在编辑器模式下,而不是在游戏期间)
- 发生3时,我们可以影响场景中的新框项目
- 因此,简单的例子是:我们将始终将Z位置设置为“2”,无论您将其放置在何处
public class Example : MonoBehaviour
{
void Reset()
{
transform.position =
new Vector3(transform.position.x, 2.22f, transform.position.z);
Debug.Log("Hi ...");
}
}
你可以这样做:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
public class PrintAwake : MonoBehaviour
{
#if UNITY_EDITOR
void Awake() .. Start() also works perfectly
{
if(!EditorApplication.isPlaying)
Debug.Log("Editor causes this Awake");
}
#endif
}
看
分析:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
public class PrintAwake : MonoBehaviour
{
#if UNITY_EDITOR
void Start() {
if(!EditorApplication.isPlaying) {
Debug.Log("Editor causes this START!!");
RandomSpinSetup();
}
}
#endif
private void RandomSpinSetup() {
float r = Random.Range(3,8) * 10f;
transform.eulerAngles = new Vector3(0f, r, 0f);
name = "Cube: " + r + "°";
}
}
请注意,这是正确的,也就是说,当您实际玩游戏时,它不会“运行”。如果按“播放”,则不会再次设置随机旋转:)
很棒的东西您可以添加一个自定义窗口编辑器,它实现了
OnHierarchyChange
来处理层次结构窗口中的所有更改。此脚本必须位于编辑器文件夹内。要使其自动工作,请确保先打开此窗口
using System.Linq;
using UnityEditor;
using UnityEngine;
public class HierarchyMonitorWindow : EditorWindow
{
[MenuItem("Window/Hierarchy Monitor")]
static void CreateWindow()
{
EditorWindow.GetWindow<HierarchyMonitorWindow>();
}
void OnHierarchyChange()
{
var addedObjects = Resources.FindObjectsOfTypeAll<MyScript>()
.Where(x => x.isAdded < 2);
foreach (var item in addedObjects)
{
//if (item.isAdded == 0) early setup
if (item.isAdded == 1) {
// do setup here,
// will happen just after user releases mouse
// will only happen once
Vector3 p = transform.position;
item.transform.position = new Vector3(p.x, 2f, p.z);
}
// finish with this:
item.isAdded++;
}
}
}
请注意,
OnHierarchyChange
被调用两次(一次是在开始将框拖动到场景上时,一次是在释放鼠标按钮时),因此isAdded
被定义为一个int
,以启用与2
的比较。因此,当添加x.isAdded<1
Hmm时,也可以使用初始化逻辑-很好,但是。。。。。。。。。这几乎奏效了。不幸的是,将预置添加到场景时,它不会调用脚本。它仅在您将该组件添加到现有游戏对象时调用脚本(或者,显式单击小的“重置”按钮…(因此从手册中…“当用户点击Inspector上下文菜单中的重置按钮或第一次添加该组件时调用重置”。不幸的是,遗憾的是,这与您所说的不同,“…或首先实例化”)哦,好的,那不是你问题的解决方案!我留下这个(错)作为对其他人的警告回答。这不是真的正确,Jin…否则,你必须向我展示你在整个代码中的意思??我不认为这有统一API,但我认为你应该在问题中添加你尝试过的代码。我这么说是因为你之前的三个问题,包括这一个。我已经研究了这个问题,我也很高兴这是可能的,但很复杂。这不仅仅是使用Selection.activeGameObject
和大量代码。您需要一种方法来区分何时将对象实际拖动到层次结构中以及何时在层次结构中重新排列对象。这两种方法都会触发一个回调函数。您还需要实现saving和l加载变量,因为这是一个编辑器插件,它们将在您单击“播放”时重置“导致bugUnity的按钮应为此添加功能。有EditorApplication.hierarchyChanged
,但在场景中重新排列对象时也会调用它。实际上,这里的Selection.activeGameObject
并不是不相关的,因为当您将对象从“项目”拖动到“层次结构”选项卡时,对象会自动被选中,因此在Selection.activeGameObject
中。它可以与编辑器应用程序一起使用。hierarchyChanged
为什么在场景编辑器中如此重要?这是正确的答案!好极了也许还有另一种方法,但这种方法非常有效。请注意,在执行设置之前,您应该检查是否(item.isAdded==1)
,或者,它将执行两次(这可能无害,也可能无害)。万岁!派了一个赏金@Fattie感谢您的更正和慷慨的赏金=)注意@Bizhan ikkentim的回答部分有效,我想在某些情况下,这是一个有用的快速解决方案
public class MyScript : MonoBehaviour {
public int isAdded { get; set; }
}