cmdwtf / UnityTools

A small collection of tools that multiple projects make use of.
https://cmd.wtf/projects#unity-tools
BSD Zero Clause License
52 stars 6 forks source link

DynamicsTransform cannot be added at runtime #1

Closed ndumais closed 11 months ago

ndumais commented 11 months ago

I've been trying to add dynamics transform to objects at runtime.

Because of the way they are configured, it did not seem possible, so I came up with a different solution, making a copy of a component stored in a prefab with the following method I found:

public static T GetCopyOfComponent<T>(this T comp, T other) where T : Component {
    var type = comp.GetType();
    var othersType = other.GetType();
    if (type != othersType) {
        Debug.LogError(
            $"The type \"{type.AssemblyQualifiedName}\" of \"{comp}\" does not match the type \"{othersType.AssemblyQualifiedName}\" of \"{other}\"!");
        return null;
    }

    BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                         BindingFlags.Default;
    PropertyInfo[] pinfos = type.GetProperties(flags);

    foreach (var pinfo in pinfos) {
        if (pinfo.CanWrite) {
            try {
                pinfo.SetValue(comp, pinfo.GetValue(other, null), null);
            }
            catch {
                /*
                 * In case of NotImplementedException being thrown.
                 * For some reason specifying that exception didn't seem to catch it,
                 * so I didn't catch anything specific.
                 */
            }
        }
    }

    FieldInfo[] finfos = type.GetFields(flags);

    foreach (var finfo in finfos) {
        finfo.SetValue(comp, finfo.GetValue(other));
    }

    return comp as T;
}

This way of doing it was really close to working, the movement was happening BUT, as soon as there are more than one GameObject with that component, they all get messed up because it seems they will all share the same internal values of position and such.

Any ideas on what would be a better way to achieve this with the code as is OR do you have any interest in providing either a Clone method or a way to instantiate this component at runtime?

Thanks for the amazing tools btw!

ndumais commented 11 months ago

Managed to make the code solution above work with a few tweaks, turns out I was wrong about internal values, or at least I found a way around it with instantiation, there could be more issues, still experimenting. At least there's a way to make it work with UnityTools as is!

nitz commented 11 months ago

Hm, another workaround might be to go ahead and always have the dynamics transform added. Just keep the component "disabled" and it won't have any effect, then turn it on when you'd like it to be active. (Or, unless you want it to just follow completely without dynamics, change the mode to "copy target value on update" and it just blindly copies values from it's target.)