MutantOctopus
MutantOctopus

Reputation: 3581

Unity - Resizing one GameObject to match another

I'm working on a project in Unity that involves regions that teleport any non-static object from one to the paired. That part's fine, but for convenience, I'm trying to write a part of the script that will resize one object if its pair is resized, such that they will always be of equal size. And so far it works - mostly. The only problem I encounter is when trying to resize through the Transform component - as in, typing in numbers in Inspector, or using the value sliders on X or Y or Z. The handles work fine. It's not a big deal, I suppose, but if I could figure out why this isn't working, so I can learn what to do in the future, I'd be very glad. Here's the code:

[ExecuteInEditMode]
public class TransferRegion : MonoBehaviour {
    // Unrelated code...

    public bool scaleManuallyAltered {
        get; private set;
    }

    [SerializeField]
    private TransferRegion pair;

    private Vector3 scale;

    // Called whenever the scene is edited
    void Update () {
        if (scale != gameObject.transform.localScale) {
            scaleManuallyAltered = true;
            scale = gameObject.transform.localScale;
        }
        if (pair && scaleManuallyAltered && !pair.scaleManuallyAltered) {
            pair.transform.localScale = scale;
        }
    }

    // Called AFTER every Update call
    void LateUpdate () {
        scaleManuallyAltered = false;
    }

    // Unrelated code...
}

If anyone can see some major logical failure I'm making, I'd like to know. If my code's a bit hard to understand I can explain my logic flow a bit, too, I know I'm prone to making some confusing constructs.
Thanks folks.

Upvotes: 2

Views: 4569

Answers (2)

James Hogle
James Hogle

Reputation: 3040

If you want one object to be the same scale as another, why not just simplify your code by setting the scale of the re sizing game object, directly to the scale of the game object it is based off of? For example, this script re sizes an object to match the scale of its pair while in edit mode:

using UnityEngine;
using UnityEditor;
using System.Collections;

[ExecuteInEditMode]
public class tester : MonoBehaviour
{
    public Transform PairedTransform;

    void Update()
    {
        if (!Selection.Contains(gameObject))
        {
            gameObject.transform.localScale = PairedTransform.localScale;
        }
    }
}

I tested this on two cubes in my scene. I was able to resizing using gizmos as well as manually typing in numbers to the transform edit fields in the inspector.

Edit: By taking advantage of Selection you can apply the scale change only to the object in the pair that is not selected in the hierarchy. This way the pairs wont be competing with each other to re scale themselves.

Upvotes: 1

MutantOctopus
MutantOctopus

Reputation: 3581

So I figured it out.
I'm not sure what was wrong with my original code, but eventually I decided to slip into the realm of good old handy events:

[ExecuteInEditMode]
public class TransferRegion : MonoBehaviour {
    //...
    [SerializeField]
    private UnityEvent rescaled;
    //...
    void Update() {
        if (scale != gameObject.transform.localScale) {
            scale = gameObject.transform.localScale;
            rescaled.Invoke();
        }
    }
    //...
    public void OnPairRescaled() {
        gameObject.transform.localScale = pair.transform.localScale;
        scale = gameObject.transform.localScale;
    }
}

And just set the OnPairRescaled event to be the listener for the paired object's rescaled event.

Ta-da!

Upvotes: 0

Related Questions