- Home /
Need help reassigning variables after the deletion of an object has been undone.
~ Problem Summary ~
I'm having trouble with Undo functions and trying to reassign variables after the deletion of an object has been undone. The objects that are attached to the object I've deleted lose their variable references once the object deletion is undone. Meanwhile the Parent Constraints are not adjusted back to the original constraints.
~ Background ~
All of my code is meant to run in the editor, not during play mode. The simplest way I've been testing this has been with three game objects:
- L1 has none for the startLink and L2 for the endLink. L1 has no Parent Constraint.
- L2 has L1 for the startLink and L3 for the endLink. L2 has L1 as a Parent Constraint.
- L3 has L2 for the startLink and none for the endLink. L3 has L2 as a Parent Constraint.
- I delete L2 using the Delete Key, my script runs and adjusts the values for both L1 and L3.
- L1 now has L3 as its endLink and L3 has L1 as its startLink. L3 moves to L2s old position and now has L1 as a Parent Constraint.
- I undo L2's deletion using CTRL + Z and the L2 Object reappears with its variables and Parent Constraint matching what it was previously.
- L1 and L3 now have both their startLinks and endLinks set to none. L3 does not move and still has L1 as a Parent Constraint.
~ Script ~
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
#endif
[SelectionBase]
[ExecuteAlways]
public class ChainLink : MonoBehaviour {
public LinkPiece link;
public ChainLink startLink, endLink;
#if UNITY_EDITOR
void OnDestroy () {
// Stops from running when destroying objects on scene load/switch
if(Time.frameCount == 0){
return;
}
//Same as above along with preventing this from running in Playmode
if (EditorApplication.isPlayingOrWillChangePlaymode || (!EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying)) {
return;
}
// Update the start link
if (startLink) {
PrefabUtility.RecordPrefabInstancePropertyModifications (startLink.gameObject);
Undo.RegisterCompleteObjectUndo(startLink, "Save Start Link Values");
startLink.endLink = endLink;
}
// Handle new end link
if (endLink) {
PrefabUtility.RecordPrefabInstancePropertyModifications (endLink.gameObject);
Undo.RegisterCompleteObjectUndo(endLink, "Save End Link Values");
// Assign the new link
endLink.startLink = startLink;
// Remove itself as the endlink's source
endLink.GetComponent<ParentConstraint> ().RemoveSource (0);
// Adjust Positions Quickly
AdjustLinkPositions (endLink);
// Create a new source using the startlink
ConstraintSource startSource = new ConstraintSource ();
if (startLink) {
PrefabUtility.RecordPrefabInstancePropertyModifications (startLink.gameObject);
Undo.RegisterCompleteObjectUndo(startLink, "Save Start Link Values");
startSource.sourceTransform = startLink.link.pivotObject;
startSource.weight = 1;
}
endLink.GetComponent<ParentConstraint>().AddSource (startSource);
}
}
public void AdjustLinkPositions (ChainLink chainLink) {
//move the positions of the links to their propper locations
if (!chainLink.startLink) {
return;
}
PrefabUtility.RecordPrefabInstancePropertyModifications (chainLink.gameObject);
Undo.RegisterCompleteObjectUndo(chainLink, "Update track positions");
chainLink.transform.position = chainLink.startLink.link.pivotObject.position;
chainLink.transform.rotation = chainLink.startLink.link.pivotObject.rotation;
Physics.SyncTransforms ();
// loop through if there are additional links
if (chainLink.endLink) {
AdjustLinkPositions (chainLink.endLink);
}
}
#endif
}
[System.Serializable]
public class LinkPiece {
public Transform mainObject, pivotObject;
}
~ End ~
I am trying to get the links to go back to the "Normal" state after the deletion of the middle link has been undone. I would appreciate any help you can provide.
Bumping this to ask if I should change the topics I've tagged or if there's anything I can do to make my question clearer. Unsure if there's a better way to store the changes rather thank using the Undo class.