这是完整的代码,但你并不真的需要它完整。我需要访问"Update"至少。我不知道如何改变原来的变量在那个空白,因为他们就是不能改变。有一些笔记。
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEditor;
using UnityEditor.TerrainTools;
using UnityEngine;
public class PlayerNetwork : NetworkBehaviour
{
private readonly NetworkVariable<PlayerNetworkData> _netState = new(writePerm: NetworkVariableWritePermission.Owner);
private Vector3 _vel;
private float _rotVel;
[SerializeField] private float _cheapInterpolationTime = 0.1f;
#region Values
// I need to access this variables
private bool _xPos, _yPos, _zPos, _xRot, _yRot, _zRot, _xSca, _ySca, _zSca;
private bool xPos // I have already tried this, but it does not work
{
get { return _xPos; }
set { _xPos = value; }
}
#if UNITY_EDITOR
[CustomEditor(typeof(PlayerNetwork))]
public class Rotation : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
PlayerNetwork network = (PlayerNetwork)target;
EditorFields(network);
}
private static void EditorFields(PlayerNetwork network)
{
PlayerNetwork original = new PlayerNetwork();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Syncing", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Position", GUILayout.MaxWidth(122));
// I must change the original "_xPos" and other variables, but I cannot get them in this void
original.xPos = network._xPos = EditorGUILayout.Toggle(network._xPos, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("X", GUILayout.MaxWidth(30));
original._yPos = network._yPos = EditorGUILayout.Toggle(network._yPos, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("Y", GUILayout.MaxWidth(30));
original._zPos = network._zPos = EditorGUILayout.Toggle(network._zPos, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("Z", GUILayout.MaxWidth(30));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Rotation", GUILayout.MaxWidth(122));
original._xRot = network._xRot = EditorGUILayout.Toggle(network._xRot, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("X", GUILayout.MaxWidth(30));
original._yRot = network._yRot = EditorGUILayout.Toggle(network._yRot, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("Y", GUILayout.MaxWidth(30));
original._zRot = network._zRot = EditorGUILayout.Toggle(network._zRot, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("Z", GUILayout.MaxWidth(30));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Scale", GUILayout.MaxWidth(122));
original._zSca = network._xSca = EditorGUILayout.Toggle(network._xSca, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("X", GUILayout.MaxWidth(30));
original._zSca = network._ySca = EditorGUILayout.Toggle(network._ySca, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("Y", GUILayout.MaxWidth(30));
original._zSca = network._zSca = EditorGUILayout.Toggle(network._zSca, GUILayout.MaxWidth(14));
EditorGUILayout.LabelField("Z", GUILayout.MaxWidth(30));
EditorGUILayout.EndHorizontal();
}
}
#endif
#endregion
private void Update()
{
print("UPDATE X POSITION: " + xPos); // there should be true as I have selected it in Inspector
if (IsOwner)
{
_netState.Value = new PlayerNetworkData()
{
Position = transform.position,
Rotation = transform.rotation.eulerAngles
};
}
else
{
transform.position = Vector3.SmoothDamp
(transform.position, _netState.Value.Position, ref _vel, _cheapInterpolationTime);
transform.rotation = Quaternion.Euler(0, Mathf.SmoothDampAngle(transform.rotation.eulerAngles.y,
_netState.Value.Rotation.y, ref _rotVel, _cheapInterpolationTime), 0);
}
}
struct PlayerNetworkData : INetworkSerializable
{
private float _xPos, _zPos;
private short _yRot;
internal Vector3 Position
{
get => new Vector3(_xPos, 0, _zPos);
set
{
_xPos = value.x;
_zPos = value.z;
}
}
internal Vector3 Rotation
{
get => new Vector3(0, _yRot, 0);
set => _yRot = (short)value.y;
}
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref _xPos);
serializer.SerializeValue(ref _zPos);
serializer.SerializeValue(ref _yRot);
}
}
}
如果我写错了,我很抱歉,英语不是我的母语。谢谢你的帮助。
我试过这样做,但它也没有工作,直到我在这类事情坏了
private bool xPos
{
get { return _xPos; }
set { _xPos = value; }
}
This
PlayerNetwork original = new PlayerNetwork();
对于来自MonoBehaviour
的东西是不允许的,它没有任何意义,因为一个组件只能作为附属于GameObject
而存在。
我也很确定你有而不是想要创建组件的新实例-甚至更少在每次鼠标移动和输入事件调用不同时间的方法中。
你宁愿把这些值只分配给你已经拥有的network
实例。
在一般情况下注意,虽然这不是真正的CustomEditor
是好的,通常你宁愿序列化这些字段,并通过SerializedProperty
覆盖他们,使他们处理撤销/重做和脏标记,最后序列化(=保存)这些值持久到你的预制和场景资产。
否则这将永远无法在Unity编辑器之外工作,因为一旦应用程序构建完成,就没有人可以使用你的自定义编辑器来设置这些标志了;)
所以通常你宁愿有e.g.(我不会做所有的-你会明白的)
[SerializeField] private bool _xPos;
[SerializeField] private bool _yPos;
[SerializeField] private bool _zPos;
,然后在编辑器
private SerializedProperty x;
private SerializedProperty y;
private SerializedProperty z;
private void OnEnable()
{
// Link the fields
x = serializedObject.FindProperty(nameof(_xPos));
y = serializedObject.FindProperty(nameof(_xPos));
z = serializedObject.FindProperty(nameof(_xPos));
....
}
public override void OnInspectorGUI()
{
...
// Load current values
serializedObject.Update();
EditorGUILayout.PrefixedLabel("Position");
using(new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.LabelField("x", GUILayout.Width(30));
EditorGUILayout.PropertyFiled(x, GUIContent.None);
EditorGUILayout.LabelField("y", GUILayout.Width(30));
EditorGUILayout.PropertyFiled(y, GUIContent.None);
EditorGUILayout.LabelField("z", GUILayout.Width(30));
EditorGUILayout.PropertyFiled(z, GUIContent.None);
}
...
// apply values back
serializedObject.ApplyModifiedProperties();
}
问题是你是否需要那个自定义检查器。你也可以坚持
[Header("Position")]
[SerializeField] private bool _xPos;
[SerializeField] private bool _yPos;
[SerializeField] private bool _zPos;
而不是强迫它们进入水平…