Exemple #1
0
    /// <summary>
    /// Finds a list of memberinfo objects that form a property path. Returns null if no matching path could be found.
    /// </summary>
    public static MemberInfo[] FindPropertyPath(Type startingPoint, string propertyPath)
    {
        string key = startingPoint.FullName + ":" + propertyPath;

        if (propertyPathCache.ContainsKey(key))
        {
            return(propertyPathCache [key]);
        }

        string[] propertyNames = propertyPath.Split('.');
        var      referenceType = startingPoint;

        MemberInfo[] result = new MemberInfo[propertyNames.Length];
        int          index  = 0;

        foreach (var propertyName in propertyNames)
        {
            var matches = referenceType.GetMember(propertyName, MemberTypes.Field | MemberTypes.Property, BindingFlags.Public | BindingFlags.Instance);
            if (matches.Length == 1)
            {
                result[index] = matches[0];
                referenceType = UTInternalCall.GetMemberType(matches[0]);
            }
            else
            {
                result = null;
                break;
            }
            index++;
        }

        propertyPathCache.Add(key, result);
        return(result);
    }
    private void BuildMenu(GenericMenu menu, Type type, string itemVisiblePath, string itemInternalPath, bool addSelf, int depth, GenericMenu.MenuFunction2 function)
    {
        if (addSelf)
        {
            menu.AddItem(new GUIContent(itemVisiblePath + "/" + type.Name), false, function, itemInternalPath);
        }
        var members = UTComponentScanner.FindPublicWritableMembersOf(type);

        foreach (var memberInfo in members.MemberInfos)
        {
            var newInternalPath = string.IsNullOrEmpty(itemInternalPath) ? memberInfo.Name : itemInternalPath + "." + memberInfo.Name;
            var newVisiblePath  = string.IsNullOrEmpty(itemVisiblePath) ? memberInfo.Name : itemVisiblePath + "/" + memberInfo.Name;
            if (memberInfo.DeclaringType != typeof(Component))
            {
                var memberInfoType = UTInternalCall.GetMemberType(memberInfo);
                if (UTInternalCall.HasMembers(memberInfoType) && depth < 2)
                {
                    BuildMenu(menu, memberInfoType, newVisiblePath, newInternalPath, UTInternalCall.IsWritable(memberInfo), depth + 1, function);
                }
                else
                {
                    menu.AddItem(new GUIContent(newVisiblePath), false, function, newInternalPath);
                }
            }
        }
    }
    public override UTVisibilityDecision IsVisible(System.Reflection.FieldInfo fieldInfo)
    {
        if (fieldInfo.Name == "gameObject" || fieldInfo.Name == "property")
        {
            return(base.IsVisible(fieldInfo));
        }

        // only expression field if the type is not clear
        var self = (UTSetComponentPropertyAction)target;

        if (self.property.UseExpression || !self.property.Value.FullyDefined)
        {
            if (fieldInfo.Name == "objectPropertyValue")
            {
                return(UTVisibilityDecision.Visible);
            }
            return(UTVisibilityDecision.Invisible);
        }

        // only expression field if the property is not valid anymore
        var propertyPath = UTComponentScanner.FindPropertyPath(self.property.Value.Type, self.property.Value.FieldPath);

        if (propertyPath == null)
        {
            if (fieldInfo.Name == "objectPropertyValue")
            {
                return(UTVisibilityDecision.Visible);
            }
            return(UTVisibilityDecision.Invisible);
        }

        Type   propertyType = UTInternalCall.GetMemberType(propertyPath[propertyPath.Length - 1]);
        string expectedPropertyFieldName = "objectPropertyValue";

        if (typeof(string).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "stringPropertyValue";
        }
        else if (typeof(bool).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "boolPropertyValue";
        }
        else if (typeof(int).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "intPropertyValue";
        }
        else if (typeof(float).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "floatPropertyValue";
        }
        else if (typeof(Texture).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "texturePropertyValue";
        }
        else if (typeof(Vector3).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "vector3PropertyValue";
        }
        else if (typeof(Vector2).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "vector2PropertyValue";
        }
        else if (typeof(Rect).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "rectPropertyValue";
        }
        else if (typeof(Quaternion).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "quaternionPropertyValue";
        }
        else if (typeof(Material).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "materialPropertyValue";
        }
        else if (typeof(Color).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "colorPropertyValue";
        }
        else if (typeof(GameObject).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "gameObjectPropertyValue";
        }
        else if (typeof(UObject).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "unityObjectPropertyValue";
        }

        if (fieldInfo.Name == expectedPropertyFieldName)
        {
            return(UTVisibilityDecision.Visible);
        }

        return(UTVisibilityDecision.Invisible);
    }
    public override IEnumerator Execute(UTContext context)
    {
        var theGameObject = gameObject.EvaluateIn(context);

        if (theGameObject == null)
        {
            throw new UTFailBuildException("You must specify the game object htat holds the component.", this);
        }

        var theProperty = property.EvaluateIn(context);

        if (theProperty == null || !theProperty.FullyDefined)
        {
            throw new UTFailBuildException("You must specify the component type and its property you want to change.", this);
        }

        var propertyPath = UTComponentScanner.FindPropertyPath(theProperty.Type, theProperty.FieldPath);

        if (propertyPath == null)
        {
            throw new UTFailBuildException("The component type or the property path is no longer valid.", this);
        }

        var theComponent = theGameObject.GetComponent(theProperty.Type);

        if (theComponent == null)
        {
            // nothing to do
            if (UTPreferences.DebugMode)
            {
                Debug.Log("Component " + theProperty.Type.Name + " not found at game object " + theGameObject, this);
            }
        }
        else
        {
            Type   propertyType = UTInternalCall.GetMemberType(propertyPath[propertyPath.Length - 1]);
            object propertyValue;
            if (typeof(string).IsAssignableFrom(propertyType))
            {
                propertyValue = stringPropertyValue.EvaluateIn(context);
            }
            else if (typeof(bool).IsAssignableFrom(propertyType))
            {
                propertyValue = boolPropertyValue.EvaluateIn(context);
            }
            else if (typeof(int).IsAssignableFrom(propertyType))
            {
                propertyValue = intPropertyValue.EvaluateIn(context);
            }
            else if (typeof(float).IsAssignableFrom(propertyType))
            {
                propertyValue = floatPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Texture).IsAssignableFrom(propertyType))
            {
                propertyValue = texturePropertyValue.EvaluateIn(context);
            }
            else if (typeof(Vector3).IsAssignableFrom(propertyType))
            {
                propertyValue = vector3PropertyValue.EvaluateIn(context);
            }
            else if (typeof(Vector2).IsAssignableFrom(propertyType))
            {
                propertyValue = vector2PropertyValue.EvaluateIn(context);
            }
            else if (typeof(Rect).IsAssignableFrom(propertyType))
            {
                propertyValue = rectPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Quaternion).IsAssignableFrom(propertyType))
            {
                propertyValue = quaternionPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Material).IsAssignableFrom(propertyType))
            {
                propertyValue = materialPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Color).IsAssignableFrom(propertyType))
            {
                propertyValue = colorPropertyValue.EvaluateIn(context);
            }
            else if (typeof(GameObject).IsAssignableFrom(propertyType))
            {
                propertyValue = gameObjectPropertyValue.EvaluateIn(context);
            }
            else if (typeof(UObject).IsAssignableFrom(propertyType))
            {
                propertyValue = unityObjectPropertyValue.EvaluateIn(context);
            }
            else
            {
                propertyValue = objectPropertyValue.EvaluateIn(context);
            }

            // TODO: we need a lot more validation here.
            // e.g. is the value assignable?

            // Tested with Vector3 -> BoxCollider:center
            // and float -> BoxCollider:center.y
            UTInternalCall.SetMemberValue(theComponent, propertyPath, propertyValue);
        }
        yield return("");
    }