Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

466
Visualizações
Custom inspector reverting values back to previous values on Play in Unity

So in my game I have an object that I need to move smoothly from Vector3 fromPosition to Vector3 toPosition at speed float speed, and then go back to where it started. All very simple, but to try and make life easier when setting up levels I decided to make a custom inspector for this script with buttons that allow me to set the target positions to the current position of the object, so I can just move it to where it needs to be and click a button, rather that typing in all the coordinates. Thought I had it all working but then started seeing some very strange behaviour, after playing around it seems to be as follows: The first time a button is used all is well. Every time the button is used after that, the values change properly in the inspector, but upon hitting Play the values of toPosition and fromPosition are reverted to what they were the first time the button was used. (They don't revert back again on Stop). However if I type the values in manually, it works perfectly. Very strange, does anyone have any idea what might be happening here? The code for the script and custom inspector are bellow.

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class MovingGrapple : MonoBehaviour
{
    public Vector3 fromPosition;
    public Vector3 toPosition;
    public float speed;

    Rigidbody thisBody;
    Grapple player;
    // Start is called before the first frame update
    void Start()
    {
        thisBody = GetComponent<Rigidbody>();
        player = GameObject.Find("Head").GetComponent<Grapple>();
    }


    private void FixedUpdate()
    {
        thisBody.MovePosition(Vector3.MoveTowards(transform.position, toPosition, Time.fixedDeltaTime * speed));
        if(transform.position == toPosition)
        {
            transform.position = fromPosition;
            if (player.activeTarget != null && GetComponentsInChildren<Transform>().Contains(player.activeTarget.transform))
            {
                player.BreakGrapple();
                GameObject.Destroy(player.activeTarget);
            }
        }
    }

    public void SetFromPosition()
    {
        fromPosition = transform.position;
    }

    public void SetToPosition()
    {
        toPosition = transform.position;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(MovingGrapple))]
public class MovingGrappleInspector : Editor
{
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        MovingGrapple myTarget = (MovingGrapple)target;

        if (GUILayout.Button("Set From position."))
        {
            myTarget.SetFromPosition();
        }
        if (GUILayout.Button("Set To position."))
        {
            myTarget.SetToPosition();
        }
    }
}

Thanks.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

This will not only happen if you press play .. your changes are never saved!

If possible you should never mix editor scripts with direct access to the target except you know exactly what you're doing!

You would especially need to "manually" mark your changed object as dirty. Otherwise the changes are only temporary until your object is deserialized again (Enter/Exit PlayMode or reload of the Scene or asset).

You could before the changes add a Undo.RecordObject

if (GUILayout.Button("Set From position."))
{
    Undo.RecordObject(myTarget, "SetFromPosition");
    myTarget.SetFromPosition();      
}
if (GUILayout.Button("Set To position."))
{
     Undo.RecordObject(myTarget, "SetToPosition");
     myTarget.SetToPosition();
}

Also (sounds unlikely in your use-case but)

Important: To correctly handle instances where objectToUndo is an instance of a Prefab, PrefabUtility.RecordPrefabInstancePropertyModifications must be called after RecordObject.


In general rather always go through SerializedProperty where possible like e.g.

[CustomEditor(typeof(MovingGrapple))]
public class MovingGrappleInspector : Editor
{
    private SerializedProperty fromPosition;
    private SerializedProperty toPosition;

    private MovingGrapple myTarget

    private void OnEnable()
    {
        fromPosition = serializedObject.FindProperty("fromPosition");
        toPosition = serializedObject.FindProperty("toPosition");

        myTarget = (MovingGrapple)target;
    }


    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        // This loads the current real values into the serialized properties
        serializedObject.Update();

        if (GUILayout.Button("Set From position."))
        {
            // Now go through the SerializedProperty
            fromPosition.vector3Value = myTarget.transform.position;
        }
        if (GUILayout.Button("Set To position."))
        {
            toPosition.vector3Value = myTarget.transform.position;
        }

        // This writes back any changes properties into the actual component
        // This also automatically handles all marking the scene and assets dirty -> saving
        // And also handles proper Undo/Redo
        serializedObject.ApplyModifiedProperties();
    }
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda