Ejemplo n.º 1
0
        /// <summary>
        /// Gets a copy of Component and adds it to the transform provided.
        /// </summary>
        /// <typeparam name="T">The Type of Component which will be added to the transform.</typeparam>
        /// <param name="component">The existing component to copy from (and the T if not directly supplied)</param>
        /// <param name="transform">The Transform to add to</param>
        /// <returns></returns>
        public static T GetCopyOf <T>(T component, Transform transform) where T : Component
        {
            var comp = transform.gameObject.AddComponent <T>();

            At.CopyProperties(comp, component, null, true);
            At.CopyFields(comp, component, null, true);

            return(comp as T);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Replaces existingComponent type with desiredType ONLY if desiredType is not assignable from the existingComponent type.
        /// That means if desiredType is Item and existingComponent type is Weapon, this will do nothing.
        /// If both types are the same, this will do nothing.
        /// Otherwise, this will replace existingComponent with a desiredType component and inherit all possible values.
        /// </summary>
        /// <param name="desiredType">The desired class type (the game type, not the SL type)</param>
        /// <param name="existingComponent">The existing component</param>
        /// <returns>The component left on the transform after the method runs.</returns>
        public static Component FixComponentType(Type desiredType, Component existingComponent)
        {
            if (!existingComponent || !existingComponent.transform || desiredType == null || desiredType.IsAbstract)
            {
                return(existingComponent);
            }

            var currentType = existingComponent.GetType();

            // If currentType derives from desiredType (or they are the same type), do nothing
            // This is to allow using basic SL_Item (or whatever) templates on more complex types without replacing them.
            if (desiredType.IsAssignableFrom(currentType))
            {
                return(existingComponent);
            }

            var newComp = existingComponent.gameObject.AddComponent(desiredType);

            while (!currentType.IsAssignableFrom(desiredType) && currentType.BaseType != null && currentType.BaseType != typeof(MonoBehaviour))
            {
                // Desired type does not derive from current type.
                // We need to recursively dive through currentType's BaseTypes until we find a type we can assign from.
                // Eg, current is MeleeWeapon and we want a ProjectileWeapon. We need to get the common base class (Weapon, in that case).
                // When currentType reaches Weapon, Weapon.IsAssignableFrom(ProjectileWeapon) will return true.
                // We also want to make sure we didnt reach MonoBehaviour, and at least got a game class.
                currentType = currentType.BaseType;
            }

            // Final check if the value copying is valid, after operations above.
            if (currentType.IsAssignableFrom(desiredType))
            {
                // recursively get all the values
                At.CopyProperties(newComp, existingComponent, currentType, true);
                At.CopyFields(newComp, existingComponent, currentType, true);
            }
            else
            {
                SL.Log($"FixComponentTypeIfNeeded - could not find a compatible type of {currentType.Name} which is assignable to desired type: {desiredType.Name}!");
            }

            // remove the old component
            GameObject.DestroyImmediate(existingComponent);

            return(newComp);
        }