using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Control))]
public class ControlEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Control control = (Control)target;
if (GUILayout.Toggle(control.isControl, "Control"))
{
control.ToControl();
}
}
}
和
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Control : MonoBehaviour
{
public Rigidbody rigidbody;
public bool isControl = false;
// Start is called before the first frame update
void Start()
{
}
public void ToControl()
{
if(isControl == false)
{
}
else
{
Destroy(rigidbody);
}
}
}
我想要做的是guilayout.toggle或按钮,并且能够销毁并向控制对象上的游戏对象添加刚体。
如何创建将刚体添加回游戏对象?
如何使用isControl标志?这个想法是在编辑器脚本中使用guilayout.toggle。
我想在游戏运行时破坏或添加新的刚体!但是在检查器中使用guilayout.toggle或按钮。
答案 0 :(得分:1)
实际上,您根本不需要检查脚本。只需添加重复检查布尔值,例如在LateUpdate
中,使组件[ExecuteInEditoMode]
像
using UnityEngine;
[ExecuteInEditoMode]
public class Control : MonoBehaviour
{
public Rigidbody rigidbody;
public bool isControl;
// repeatedly check the bool
private void LateUpdate()
{
ToControl();
}
public void ToControl()
{
if (!isControl && rigidbody)
{
// in editmode use DestroyImmediate
if (Application.isEditor && !Application.isPlaying)
{
DestroyImmediate(rigidbody);
}
else
{
Destroy(rigidbody);
}
rigidbody = null;
}
else if(isControl && !rigidbody)
{
rigidbody = gameObject.AddComponent<Rigidbody>();
// adjust settings of rigidbody
}
}
}
通过这种方式LateUpdate
在播放模式和编辑模式下都被调用,并且只会对isControl
的值做出反应。
当然,一直都要调用此LateUpdate
会产生开销,因此,如果要避免使用它,只能从编辑器中调用它。但是,由于您使用的是base.OnInspectorGUI();
,因此您实际上并不需要额外的Toggle
,因为您已经拥有默认检查器之一。
所以可以简单地做
using UnityEngine;
public class Control : MonoBehaviour
{
public Rigidbody rigidbody;
public bool isControl;
public void ToControl()
{
if (!isControl && rigidbody)
{
if (Application.isEditor && !Application.isPlaying)
{
DestroyImmediate(rigidbody);
}
else
{
Destroy(rigidbody);
}
rigidbody = null;
}
else if(isControl && !rigidbody)
{
rigidbody = gameObject.AddComponent<Rigidbody>();
}
}
}
,并且只需在编辑器脚本中执行
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Control))]
public class ControlEditor : Editor
{
private Control control;
// calle when the object gains focus
private void OnEnable()
{
control = (Control)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!control.isControl && control.rigidbody)
{
control.ToControl();
Repaint();
}
else if (control.isControl && !control.rigidbody)
{
control.ToControl();
Repaint();
}
}
}
但是,您已经注意到这可能会影响撤消/重做的工作方式-在这种情况下,重置isControl
的值,但不删除RigidBody
组件,导致错误(请参见下文)
或者因为您询问了它,所以您可以添加ToggleField(由于base.OnInspectorGUI();
还附带了ToggleField,因此您将获得两次)
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Control))]
public class ControlEditor : Editor
{
private Control control;
// calle when the object gains focus
private void OnEnable()
{
control = (Control)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
control.isControl = EditorGUILayout.Toggle("additional isControl", control.isControl);
if (!control.isControl && control.rigidbody)
{
control.ToControl();
Repaint();
}
else if (control.isControl && !control.rigidbody)
{
control.ToControl();
Repaint();
}
}
}
但,您会注意到,使用additional isControl
更改值的解决方案无法完全使用“撤消/重做”功能,并且会不标记您的场景为“脏”,因此Unity可能不会保存这些更改!
因此如果,您确实希望在检查员脚本中包含自定义切换字段,那么我强烈建议您使用正确的SerializedProperty
而不是直接对{{1}进行更改}(有时无法避免,就像添加组件一样):
target
这看起来更加复杂,实际上您有重复的代码,但是它提供了完全的撤消/重做支持,并将对象和场景标记为脏的,以便Unity保存更改。