C# 为什么在运行游戏时,门锁定状态会覆盖并设置为false?
当游戏已经运行时,它工作正常。我可以更改每个门锁状态。但在运行游戏之前,我设置了一个或多个要锁定的门(选中将标志设置为true),然后运行游戏,它将所有的门都更改为false unlocked 我想,如果我在运行游戏之前也设置了doors lock状态,它会在游戏运行时保持这种变化 第一个脚本只有一行:C# 为什么在运行游戏时,门锁定状态会覆盖并设置为false?,c#,unity3d,C#,Unity3d,当游戏已经运行时,它工作正常。我可以更改每个门锁状态。但在运行游戏之前,我设置了一个或多个要锁定的门(选中将标志设置为true),然后运行游戏,它将所有的门都更改为false unlocked 我想,如果我在运行游戏之前也设置了doors lock状态,它会在游戏运行时保持这种变化 第一个脚本只有一行: using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class DoorsLockManager : MonoBehaviour
{
public List<HoriDoorManager> Doors = new List<HoriDoorManager>();
}
使用系统集合;
使用System.Collections.Generic;
使用System.Linq;
使用UnityEngine;
公共类DoorsLockManager:MonoBehavior
{
公共列表门=新列表();
}
第二个脚本控制门:
using UnityEditor;
[CustomEditor(typeof(DoorsLockManager))]
public class DoorsLockManagerEditor : Editor
{
DoorsLockManager _manager;
public override void OnInspectorGUI()
{
_manager = (DoorsLockManager)target;
base.OnInspectorGUI();
if (_manager.Doors.Count <= 0)
return;
for (var i = 0; i < _manager.Doors.Count; i++)
{
if (_manager.Doors[i] == null)
continue;
_manager.Doors[i].GetLockState = EditorGUILayout.Toggle("Door " + i + " Lockstate", _manager.Doors[i].GetLockState);
}
}
}
使用UnityEditor;
[CustomEditor(typeof(DoorsLockManager))]
公共类DoorsLockManagerEditor:编辑器
{
门牌经理(DoorsLockManager);;
公共覆盖无效OnInspectorGUI()
{
_经理=(DoorsLockManager)目标;
base.OnInspectorGUI();
如果(_manager.Doors.Count您是否尝试了DoorsLockManagerEditor
编辑器似乎没有保留初始值。您在门SlockManager编辑器中尝试过吗
编辑器似乎没有保留初始值。属性是不可序列化的。
您永远不应该在编辑器脚本中更改它们,因为它们没有序列化=>永远不会保存,并且始终具有默认值
如果它是属性类似,则它将不起作用
public bool GetLockState
{
get { return doorLockState; }
set { doorLockState = value; }
}
如果你的doorLockState
是public
的话,为什么还要使用这个呢
问题在于,这不会将更改的字段doorLockState
标记为“脏”
但是,您应该不要使用EditorUtility.SetDirty
,因为:
从5.3开始,随着多场景编辑的引入,此功能不应再用于修改场景中的对象。相反,在对对象进行更改之前,应使用Undo.RecordObject
。这将对象的场景标记为脏,并在编辑器中提供撤销条目.'
相反,在编辑器脚本中,您必须更改doorLockState
的值
如果它位于private
位置,则必须添加[SerializeField]
[SerializeField] private bool doorLockState;
但在您的情况下,它似乎是公开的,所以它是自动序列化的
而不是在编辑器脚本中直接操作值
开始时它看起来更复杂,但这会自动处理诸如撤消/重做和将内容标记为脏(从而保存更改)之类的事情,因此您不必处理其他任何事情:
[CustomEditor(typeof(DoorsLockManager))]
public class DoorsLockManagerEditor : Editor
{
private SerializedProperty _doors;
private void OnEnable()
{
_doors = serializedObject.FindProperty("Doors");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
for (int i = 0; i < _doors.arraySize; i++)
{
var door = _doors.GetArrayElementAtIndex(i);
// if door == null the script itself has an error since it can't even find the SerializedProperty
if (door == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get door property", target);
return;
}
if (door.objectReferenceValue == null) continue;
// FindPropertyRelative seems not to work for MonoBehaviour classes
// so we have to use this hack around
var serializedDoor = new SerializedObject(door.objectReferenceValue);
// If it's public no worry anyway
// If it's private still works since we made it a SerializeField
var lockState = serializedDoor.FindProperty("doorLockState");
// Fetch current values into the serialized "copy"
serializedDoor.Update();
if (lockState == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get lockState property", target);
return;
}
// for the PropertyField there is
// no return value since it automatically uses
// the correct drawer for the according property
// and directly changes it's value
EditorGUILayout.PropertyField(lockState, new GUIContent("Door " + i + " Lockstate"));
// or alternatively
//lockState.boolValue = EditorGUILayout.Toggle("Door " + i + " Lockstate", lockState.boolValue);
// Write back changes, mark as dirty if changed
// and add a Undo history entry
serializedDoor.ApplyModifiedProperties();
}
}
}
[CustomEditor(typeof(DoorsLockManager))]
公共类DoorsLockManagerEditor:编辑器
{
私有财产门;
私有void OnEnable()
{
_doors=serializedObject.FindProperty(“doors”);
}
公共覆盖无效OnInspectorGUI()
{
base.OnInspectorGUI();
对于(int i=0;i<\u doors.arraySize;i++)
{
var door=\u doors.GetArrayElementIndex(i);
//如果door==null,脚本本身就有一个错误,因为它甚至找不到SerializedProperty
如果(门==null)
{
EditorGUILayout.HelpBox(“编辑器脚本中有错误!\n请检查日志”,MessageType.error);
LogError(“无法获取门属性”,目标);
返回;
}
如果(door.objectReferenceValue==null)继续;
//FindPropertyRelative似乎不适用于单一行为类
//所以我们必须使用这个黑客
var serializedDoor=新SerializedObject(door.objectReferenceValue);
//如果是公众的话,不用担心
//如果它是私有的,自从我们将它设置为一个序列化字段后,它仍然有效
var lockState=serializedDoor.FindProperty(“doorLockState”);
//将当前值提取到序列化的“副本”中
序列化ddoor.Update();
if(lockState==null)
{
EditorGUILayout.HelpBox(“编辑器脚本中有错误!\n请检查日志”,MessageType.error);
LogError(“无法获取lockState属性”,目标);
返回;
}
//对于PropertyField,有
//没有返回值,因为它自动使用
//相应属性的正确抽屉
//直接改变它的价值
EditorGUILayout.PropertyField(lockState,新GUIContent(“门”+i+“锁状态”));
//或者
//lockState.boolValue=EditorGUILayout.Toggle(“门”+i+“锁状态”,lockState.boolValue);
//写回更改,如果更改,则标记为脏
//并添加撤消历史记录条目
serializedDoor.ApplyModifiedProperties();
}
}
}
(当然,该值仅在InspectorGUI上更新,因此,如果您打开了多个Inspector选项卡,则仅在悬停时更新该值)属性是不可序列化的
您永远不应该在编辑器脚本中更改它们,因为它们没有序列化=>永远不会保存,并且始终具有默认值
如果它是属性类似,则它将不起作用
public bool GetLockState
{
get { return doorLockState; }
set { doorLockState = value; }
}
如果你的doorLockState
是public
的话,为什么还要使用这个呢
问题在于,这不会将更改的字段doorLockState
标记为“脏”
但是,您应该不要使用EditorUtility.SetDirty
,因为:
从5.3开始,随着Mul的引入