Copying Transforms from one object to another using operators

I am trying to replicate 3DS Max’s WIRE feature, in which 2 objects can be attached together figuratively, for example:

Object2.position.x = Object1.position.x - 1
to have object2 1 unit behind object1
or
Object2.rotation.x = -Object1.rotation
to have object2 mirror object1’s rotation (useful for gears etc)

I am having a little trouble achieving this.

I am aware of the theory, and I am trying to replicate it, but am having trouble with the persistent values (scale for example constantly doubles itself even with a multiplier of 1 (so shouldn’t budge)).

I currently have a few problems:

  • Rotation does nothing, unsure as to how to apply it to an object :expressionless:
  • Scale doubles infinitely
  • Position appears to do little, if anything

I’m sure I have set this up correctly, but am setting the values incorrectly, with the exception of Scale, not sure what’s wrong with that.

My full code is below:

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

[System.Serializable]
public class HookParameters
{
    public bool hookEnabled = true;

    public Transform masterObject;

    public bool externalSlave = false;
    public Transform slaveObject;

    public enum TransformHook { localPosition, Rotation, Scale }
    public TransformHook transformHook = TransformHook.localPosition;

    public enum AxisHook { X, Y, Z }
    public AxisHook axisHook = AxisHook.X;

    public float hookMultiplier = 1.0f;
}

[ExecuteInEditMode]
public class Hook : MonoBehaviour
{
    [SerializeField]
    public List<HookParameters> hookParameters;

    void Update()
    {
        foreach (HookParameters hp in hookParameters)
        {
            if (hp.hookEnabled)
            {
                switch (hp.transformHook)
                {
                    case HookParameters.TransformHook.localPosition:
                        switch (hp.axisHook)
                        {
                            case HookParameters.AxisHook.X:
                                if(hp.externalSlave)
                                {
                                    hp.slaveObject.transform.localPosition = hp.slaveObject.transform.localPosition + new Vector3(hp.slaveObject.transform.localPosition.x * hp.hookMultiplier, hp.slaveObject.transform.localPosition.y, hp.slaveObject.transform.localPosition.z);
                                }
                                else
                                {
                                    this.transform.localPosition = this.transform.localPosition + new Vector3(this.transform.localPosition.x * hp.hookMultiplier, this.transform.localPosition.y, this.transform.localPosition.z);
                                }
                                break;
                            case HookParameters.AxisHook.Y:
                                if (hp.externalSlave)
                                {
                                    hp.slaveObject.transform.localPosition = hp.slaveObject.transform.localPosition + new Vector3(hp.slaveObject.transform.localPosition.x, hp.slaveObject.transform.localPosition.y * hp.hookMultiplier, hp.slaveObject.transform.localPosition.z);
                                }
                                else
                                {
                                    this.transform.localPosition = this.transform.localPosition + new Vector3(this.transform.localPosition.x, this.transform.localPosition.y * hp.hookMultiplier, this.transform.localPosition.z);
                                }
                                break;
                            case HookParameters.AxisHook.Z:
                                if (hp.externalSlave)
                                {
                                    hp.slaveObject.transform.localPosition = hp.slaveObject.transform.localPosition + new Vector3(hp.slaveObject.transform.localPosition.x, hp.slaveObject.transform.localPosition.y, hp.slaveObject.transform.localPosition.z * hp.hookMultiplier);
                                }
                                else
                                {
                                    this.transform.localPosition = this.transform.localPosition + new Vector3(this.transform.localPosition.x, this.transform.localPosition.y, this.transform.localPosition.z * hp.hookMultiplier);
                                }
                                break;
                        }
                        break;
                    case HookParameters.TransformHook.Rotation:
                        switch (hp.axisHook)
                        {
                            case HookParameters.AxisHook.X:
                                if (hp.externalSlave)
                                {
                                    Quaternion rot = hp.slaveObject.transform.rotation;
                                    rot.eulerAngles = hp.slaveObject.transform.rotation.eulerAngles + new Vector3(hp.slaveObject.transform.rotation.x * hp.hookMultiplier, hp.slaveObject.transform.rotation.y, hp.slaveObject.transform.rotation.z);
                                    hp.slaveObject.transform.rotation = rot;
                                }
                                else
                                {
                                    Quaternion rot = this.transform.rotation;
                                    rot.eulerAngles = this.transform.rotation.eulerAngles + new Vector3(this.transform.rotation.x * hp.hookMultiplier, this.transform.rotation.y, this.transform.rotation.z);
                                    this.transform.rotation = rot;
                                }
                                break;
                            case HookParameters.AxisHook.Y:
                                if (hp.externalSlave)
                                {
                                    Quaternion rot = hp.slaveObject.transform.rotation;
                                    rot.eulerAngles = hp.slaveObject.transform.rotation.eulerAngles + new Vector3(hp.slaveObject.transform.rotation.x, hp.slaveObject.transform.rotation.y * hp.hookMultiplier, hp.slaveObject.transform.rotation.z);
                                    hp.slaveObject.transform.rotation = rot;
                                }
                                else
                                {
                                    Quaternion rot = this.transform.rotation;
                                    rot.eulerAngles = this.transform.rotation.eulerAngles + new Vector3(this.transform.rotation.x, this.transform.rotation.y * hp.hookMultiplier, this.transform.rotation.z);
                                    this.transform.rotation = rot;
                                }
                                break;
                            case HookParameters.AxisHook.Z:
                                if (hp.externalSlave)
                                {
                                    Quaternion rot = hp.slaveObject.transform.rotation;
                                    rot.eulerAngles = hp.slaveObject.transform.rotation.eulerAngles + new Vector3(hp.slaveObject.transform.rotation.x, hp.slaveObject.transform.rotation.y, hp.slaveObject.transform.rotation.z * hp.hookMultiplier);
                                    hp.slaveObject.transform.rotation = rot;
                                }
                                else
                                {
                                    Quaternion rot = this.transform.rotation;
                                    rot.eulerAngles = this.transform.rotation.eulerAngles + new Vector3(this.transform.rotation.x, this.transform.rotation.y, this.transform.rotation.z * hp.hookMultiplier);
                                    this.transform.rotation = rot;
                                }
                                break;
                        }
                        break;
                    case HookParameters.TransformHook.Scale:
                        switch (hp.axisHook)
                        {
                            case HookParameters.AxisHook.X:
                                if (hp.externalSlave)
                                {
                                    hp.slaveObject.transform.localScale = hp.slaveObject.transform.localScale + new Vector3(hp.slaveObject.transform.localScale.x * hp.hookMultiplier, hp.slaveObject.transform.localScale.y, hp.slaveObject.transform.localScale.z);
                                }
                                else
                                {
                                    this.transform.localScale = this.transform.localScale + new Vector3(this.transform.localScale.x * hp.hookMultiplier, this.transform.localScale.y, this.transform.localScale.z);
                                }
                                break;
                            case HookParameters.AxisHook.Y:
                                if (hp.externalSlave)
                                {
                                    hp.slaveObject.transform.localScale = hp.slaveObject.transform.localScale + new Vector3(hp.slaveObject.transform.localScale.x, hp.slaveObject.transform.localScale.y * hp.hookMultiplier, hp.slaveObject.transform.localScale.z);
                                }
                                else
                                {
                                    this.transform.localScale = this.transform.localScale + new Vector3(this.transform.localScale.x, this.transform.localScale.y * hp.hookMultiplier, this.transform.localScale.z);
                                }
                                break;
                            case HookParameters.AxisHook.Z:
                                if (hp.externalSlave)
                                {
                                    hp.slaveObject.transform.localScale = hp.slaveObject.transform.localScale + new Vector3(hp.slaveObject.transform.localScale.x, hp.slaveObject.transform.localScale.y, hp.slaveObject.transform.localScale.z * hp.hookMultiplier);
                                }
                                else
                                {
                                    this.transform.localScale = this.transform.localScale + new Vector3(this.transform.localScale.x, this.transform.localScale.y, this.transform.localScale.z * hp.hookMultiplier);
                                }
                                break;
                        }
                        break;
                }
            }
        }
    }
}

I hope I am not reading this wrong, but you are adding to the scale?

As for the rotation, you are using Quaternion values in your euler angle calculations, I believe (rather than euler angles). I also want to suggest ‘Quaternion.Inverse’ but tbh, that’s half a guess… :slight_smile:

If I’m way off, sorry… hope you get it working :wink:

The scale is being applied like so:

scale = scale * multiplier

I’m unsure of what you mean by

, is this not how you are meant to work with and apply rotations?

It doesn’t look like scale is being added how you responded. It looks like you’re saying …
if scale is 1,1,1 and multiplier is n … new scale = 1,1,1 + 1,1*n,1 … i dunno, i’m tired, sorry.

and this line (as an example):

this.transform.rotation.eulerAngles + new Vector3(this.transform.rotation.x * hp.hookMultiplier, this.transform.rotation.y, this.transform.rotation.z);

that looks like you’re using 'rotation.x/y/z etc… which are parts of the Quat, rather than euler angles.
I just don’t think that’s what you want in those lines of code.

First of all, the code lines are way too long. Try to shorten them to achieve better readability, it’s way too hard to read.

Anyway, you never use the masterObject.
You only work with the transform itself (or the slave) which basically modifies said object endlessly based on its own values.

That is, you’re basically doing the following (simplified) in Update all the time:

value = value + someValue;

Given x frames, this could also be written as:
valueₓ = value₀ + (x * someValue)

which is obviously not what you want.

Just imagine ‘value’ is your scale: you’ll notice that’s exactly the problem you encounter.

Sorry, maybe wasn’t clear.

I know why this is happening, and what I am doing wrong, I’m just unsure of how to remedy it, but also keep it working.