It's full code, but u do not really nead it full. I need to access varibles in the "Update" at least. I do not know how to change original variables in that void, because they just cannot be changed. There are some notes writen.
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);
}
}
}
I am sorry if I have writen smth not correct, english isn't my native language. Thanks for help.
I have tried to do it with this, but it also does not work until I am bad in this kind of things
private bool xPos
{
get { return _xPos; }
set { _xPos = value; }
}
CodePudding user response:
This
PlayerNetwork original = new PlayerNetwork();
is a no-go for things derived from MonoBehaviour
, it doesn't make any sense since a component can only exist as attached to a GameObject
.
I'm also pretty sure you do not want to create new instances of your component at all - even less in a method that is called various times for each mouse movement and input events.
You rather want to assign those values only to the network
instance you already have.
In general note though that this isn't really what CustomEditor
is good for, usually you would rather serialize those fields and overwrite them via SerializedProperty
so that they are handling Undo/Redo and dirty marking and finally serializing (=saving) those values persistent into your prefabs and scene assets.
Otherwise this will never work outside of the Unity Editor because once the app is built nobody can use your Custom Editor for setting those flags anymore ;)
So usually you would rather have e.g. (I will not do all of them - you will get the point)
[SerializeField] private bool _xPos;
[SerializeField] private bool _yPos;
[SerializeField] private bool _zPos;
and then in the editor
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();
}
Question is if you need that custom inspector at all. You could as well stick to
[Header("Position")]
[SerializeField] private bool _xPos;
[SerializeField] private bool _yPos;
[SerializeField] private bool _zPos;
and not force them into horizontal..