예제 #1
0
 /// <summary>
 /// Gets the script extensions ordered by their load order.
 /// </summary>
 public static List <KeyValuePair <object, UTScriptExtension> > GetScriptExtensions()
 {
     if (cachedSortedList == null)
     {
         var           cache             = new Dictionary <object, UTScriptExtension>();
         var           scannedComponents = UTComponentScanner.FindComponentsAnnotatedWith <object, UTScriptExtension>();
         List <string> variableNames     = new List <string>();
         foreach (var item in scannedComponents)
         {
             var annotation = item.Value;
             var component  = item.Key;
             if (annotation.variable != null && variableNames.Contains(annotation.variable))
             {
                 Debug.LogWarning(component.GetType().FullName + " is annotated as " + annotation.variable + " but this variable name is already in use.");
                 continue;
             }
             else
             {
                 cache.Add(item.Key, item.Value);
             }
         }
         cachedSortedList = new List <KeyValuePair <object, UTScriptExtension> >();
         cachedSortedList.AddRange(cache);
         cachedSortedList.Sort((item1, item2) => (item1.Value.loadOrder.CompareTo(item2.Value.loadOrder)));
     }
     return(cachedSortedList);
 }
    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 void Render(UTFieldWrapper fieldWrapper)
    {
        Type baseType        = fieldWrapper.InspectorHint.baseType;
        var  compatibleTypes = UTComponentScanner.FindCompatibleTypes(baseType);

        var val          = (UTMemberInfo)fieldWrapper.Value;
        int currentIndex = -1;

        if (val != null)
        {
            currentIndex = Array.IndexOf(compatibleTypes.TypeNames, val.TypeName);
        }
        EditorGUILayout.BeginVertical();
        int newIndex = -1;

        if (fieldWrapper.Label != null)
        {
            newIndex = EditorGUILayout.Popup(fieldWrapper.Label, currentIndex, compatibleTypes.NicifiedTypeNames);
        }
        else
        {
            newIndex = EditorGUILayout.Popup(currentIndex, compatibleTypes.NicifiedTypeNames);
        }

        if (currentIndex != newIndex)
        {
            if (newIndex == -1)
            {
                fieldWrapper.Value = null;
                val = null;
            }
            else
            {
                var    type            = UTInternalCall.GetType(compatibleTypes.TypeNames [newIndex]);
                var    writableMembers = UTComponentScanner.FindPublicWritableMembersOf(type);
                string propertyPath    = null;
                if (writableMembers.MemberInfos.Length > 0)
                {
                    propertyPath = writableMembers.MemberInfos[0].Name;
                }
                val = new UTMemberInfo(type.FullName, propertyPath);
                fieldWrapper.Value = val;
            }
        }

        GUI.enabled = val != null && !string.IsNullOrEmpty(val.TypeName);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel(" ");
        if (GUILayout.Button(val.FieldPath, EditorStyles.popup))
        {
            var genericMenu = BuildMenu(val.Type, val.SetFieldPath);
            genericMenu.ShowAsContext();
        }
        EditorGUILayout.EndHorizontal();
        GUI.enabled = true;

        EditorGUILayout.EndVertical();
    }
    private static void BuildCache()
    {
        cache = new Dictionary <Type, UTIPropertyRenderer> ();
        var renderers = UTComponentScanner.FindComponentsAnnotatedWith <UTIPropertyRenderer, UTPropertyRendererAttribute> ();

        foreach (var entry in renderers)
        {
            var rendererAttribute = entry.Value;
            var instance          = entry.Key;
            var supportedTypes    = rendererAttribute.supportedTypes;
            foreach (var supportedType in supportedTypes)
            {
                if (cache.ContainsKey(supportedType))
                {
                    Debug.LogWarning("There already exists a property renderer for type '" + supportedType + "'");
                }
                cache [supportedType] = instance;
            }
        }
    }
    public void Render(UTFieldWrapper fieldWrapper)
    {
        Type baseType = fieldWrapper.InspectorHint.baseType;

        var compatibleTypes = UTComponentScanner.FindCompatibleTypes(baseType);

        var val          = (UTTypeInfo)fieldWrapper.Value;
        int currentIndex = -1;

        if (val != null)
        {
            currentIndex = Array.IndexOf(compatibleTypes.TypeNames, val.TypeName);
        }

        int newIndex = -1;

        if (fieldWrapper.Label != null)
        {
            newIndex = EditorGUILayout.Popup(fieldWrapper.Label, currentIndex, compatibleTypes.NicifiedTypeNames);
        }
        else
        {
            newIndex = EditorGUILayout.Popup(currentIndex, compatibleTypes.NicifiedTypeNames);
        }

        if (currentIndex != newIndex)
        {
            if (newIndex == -1)
            {
                fieldWrapper.Value = null;
            }
            else
            {
                fieldWrapper.Value = new UTTypeInfo(compatibleTypes.TypeNames[newIndex]);
            }
        }
    }
    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("");
    }