/// <summary>
	/// draws a foldout with buttons to load and save a preset
	/// </summary>
	public static bool PresetFoldout(bool foldout, vp_Component component)
	{

		foldout = EditorGUILayout.Foldout(foldout, "Preset");
		if (foldout)
		{

			GUI.enabled = true;
			EditorGUILayout.BeginHorizontal();
			if (component.DefaultState.TextAsset != null)
				GUI.enabled = false;
			if (GUILayout.Button("Load"))
				ShowLoadDialog(component);
			GUI.enabled = true;
			if (GUILayout.Button("Save"))
				ShowSaveDialog(component, false);
			if (!Application.isPlaying)
				GUI.enabled = false;
			if (GUILayout.Button("Save Tweaks"))
				ShowSaveDifferenceDialog(component);
			GUI.enabled = true;
			EditorGUILayout.EndHorizontal();

		}
		return foldout;

	}
 /// <summary>
 /// 
 /// </summary>
 public static vp_State GetState(vp_Component component, string state)
 {
     foreach (vp_State s in component.States)
     {
         if (s.Name == state)
             return s;
     }
     return null;
 }
Ejemplo n.º 3
0
    ///////////////////////////////////////////////////////////
    // allows or disallows 'state' on this object, then scans
    // the underlying hierarchy for vp_Components and does the
    // same on every object found
    ///////////////////////////////////////////////////////////
    public void AllowStateRecursively(string state, bool isAllowed)
    {
        AllowState(state, isAllowed);

        Component[] components;
        components = GetComponentsInChildren <vp_Component>();
        foreach (Component c in components)
        {
            vp_Component vc = (vp_Component)c;
            vc.AllowState(state, isAllowed);
        }
    }
Ejemplo n.º 4
0
 public void CacheChildren()
 {
     this.Children.Clear();
     vp_Component[] componentsInChildren = base.GetComponentsInChildren <vp_Component>(true);
     for (int i = 0; i < componentsInChildren.Length; i++)
     {
         vp_Component vp_Component = componentsInChildren[i];
         if (vp_Component.transform.parent == base.transform)
         {
             this.Children.Add(vp_Component);
         }
     }
 }
    /// <summary>
    /// copies a component's type and values into 'this' preset
    /// </summary>
    public void InitFromComponent(vp_Component component)
    {
        m_ComponentType = component.Type;

        m_Fields.Clear();

        List <FieldInfo> fieldInfos = GetFieldInfos(m_ComponentType);

        for (int v = 0; v < fieldInfos.Count; v++)
        {
            m_Fields.Add(new Field(fieldInfos[v].FieldHandle, fieldInfos[v].GetValue(component)));
        }
    }
Ejemplo n.º 6
0
 public void CacheFamily()
 {
     this.Family.Clear();
     vp_Component[] componentsInChildren = base.transform.root.GetComponentsInChildren <vp_Component>(true);
     for (int i = 0; i < componentsInChildren.Length; i++)
     {
         vp_Component vp_Component = componentsInChildren[i];
         if (vp_Component != this)
         {
             this.Family.Add(vp_Component);
         }
     }
 }
Ejemplo n.º 7
0
 public void CacheSiblings()
 {
     this.Siblings.Clear();
     vp_Component[] components = base.GetComponents <vp_Component>();
     for (int i = 0; i < components.Length; i++)
     {
         vp_Component vp_Component = components[i];
         if (vp_Component != this)
         {
             this.Siblings.Add(vp_Component);
         }
     }
 }
Ejemplo n.º 8
0
    static private void ShowSaveDialog(vp_Component component, bool showLoadDialogAfterwards)
    {
        string path = Application.dataPath;

        vp_FileDialog.Create(vp_FileDialog.Mode.Save, "Save Preset", path, delegate(string filename)
        {
            vp_FileDialog.Result = vp_ComponentPreset.Save(component, filename);

            if (showLoadDialogAfterwards)
            {
                ShowLoadDialog(component);
            }
        }, ".txt");
    }
Ejemplo n.º 9
0
    ///////////////////////////////////////////////////////////
    // draws a button showing if a state is on or off, allowing
    // the user to toggle states at runtime. will also show
    // a text saying if the state is currently disallowed
    ///////////////////////////////////////////////////////////
    public static void RunTimeStateField(vp_Component component, vp_StateInfo state, List <vp_StateInfo> stateList)
    {
        EditorGUILayout.BeginHorizontal();

        GUI.color = m_ColorTransparentWhite;
        if (!state.Enabled)
        {
            GUILayout.Space(20);
            GUI.enabled = true;
            GUILayout.Label((stateList.Count - stateList.IndexOf(state) - 1).ToString() + ":", vp_EditorGUIUtility.RightAlignedPathStyle, GUILayout.MinWidth(20), GUILayout.MaxWidth(20));
            GUILayout.BeginHorizontal();
            if (GUILayout.Button(state.Name, vp_EditorGUIUtility.CenteredBoxStyle, GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
            {
                vp_Component[] compos = component.gameObject.GetComponentsInChildren <vp_Component>();
                foreach (vp_Component c in compos)
                {
                    c.StateManager.SetState(state.Name, true);
                    c.Refresh();
                }
            }
            if (!state.Allowed)
            {
                GUILayout.Label("(Disallowed)");
            }
            GUILayout.EndHorizontal();
            GUI.color = m_ColorTransparentWhite;
        }
        else
        {
            GUILayout.Space(20);
            GUILayout.Label((stateList.Count - stateList.IndexOf(state) - 1).ToString() + ":", vp_EditorGUIUtility.RightAlignedPathStyle, GUILayout.MinWidth(20), GUILayout.MaxWidth(20));
            if (GUILayout.Button(state.Name, vp_EditorGUIUtility.CenteredBoxStyleBold, GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
            {
                vp_Component[] compos = component.gameObject.GetComponentsInChildren <vp_Component>();
                foreach (vp_Component c in compos)
                {
                    c.StateManager.SetState(state.Name, false);
                    c.Refresh();
                }
            }
        }

        if (state.Name != "Default" && state.TextAsset == null)
        {
            GUILayout.TextField("<- Warning: No preset!", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(100));
        }

        EditorGUILayout.EndHorizontal();
    }
    private int m_TargetId  = 0;        // id of the last modified state (for triggering enable / disable callbacks)


    /// <summary>
    /// manages a list of states and corresponding presets for a
    /// component. loads the presets into memory on startup, and
    /// allows applying them from memory to the component.
    /// states are enabled in a layered manner, that is: the
    /// default state is always alive, and any enabled states are
    /// applied on top of it in the order of which they were enabled.
    ///
    /// this class doesn't store any preset data between sessions.
    /// it is merely used to manipulate the component using a list
    /// of states that is sent along at startup. it is very silent
    /// and forgiving; it won't complain if a state isn't found
    /// (since providing a certain state should not be considered
    /// mandatory for a component, and states can be set recursively).
    /// it will also ignore empty presets
    /// </summary>
    public vp_StateManager(vp_Component component, List <vp_State> states)
    {
        m_States    = states;
        m_Component = component;

        // create default state and add it to the list
        m_Component.RefreshDefaultState();

        // refresh the initial state, needed for being able to save
        // partial presets in the editor
#if UNITY_EDITOR
        m_Component.RefreshInitialState();
#endif

        // load states and initialize the state id dictionary
        m_StateIds = new Dictionary <string, int>(System.StringComparer.CurrentCulture);
        foreach (vp_State s in m_States)
        {
            s.StateManager = this;

            // store the name and list index of each state in a dictionary for
            // fast lookup. IMPORTANT: the state list (m_States) must never be
            // modified at runtime (i.e. have states reordered, added, renamed
            // or removed) or the dictionary (m_StateIds) will be out of date
            if (!m_StateIds.ContainsKey(s.Name))
            {
                m_StateIds.Add(s.Name, m_States.IndexOf(s));
            }
            else
            {
                Debug.LogWarning("Warning: " + m_Component.GetType() + " on '" + m_Component.name + "' has more than one state named: '" + s.Name + "'. Only the topmost one will be used.");
                m_States[m_DefaultId].StatesToBlock.Add(m_States.IndexOf(s));
            }

            // load up the preset of each user assigned state and
            if (s.Preset == null)
            {
                s.Preset = new vp_ComponentPreset();
            }
            if (s.TextAsset != null)
            {
                s.Preset.LoadFromTextAsset(s.TextAsset);
            }
        }

        // the default state of a component is always the last one in the list
        m_DefaultId = m_States.Count - 1;
    }
Ejemplo n.º 11
0
    /// <summary>
    /// opens a dialog for loading presets
    /// </summary>
    static private void ShowLoadDialog(vp_Component component)
    {
        string path = Application.dataPath.Replace("\\", "/");

        vp_FileDialog.Create(vp_FileDialog.Mode.Open, "Load Preset", path, delegate(string filename)
        {
            if (!vp_ComponentPreset.Load(component, filename))
            {
                vp_FileDialog.Result = "Failed to load preset '" + vp_FileDialog.ExtractFilenameFromPath(filename) + "'.\n\nIs it the correct component type? (" + component.GetType().ToString() + ")";
            }
            else
            {
                EditorUtility.SetDirty(component);
            }
        }, ".txt");
    }
Ejemplo n.º 12
0
	private int m_TargetId = 0;		// id of the last modified state (for triggering enable / disable callbacks)


	/// <summary>
	/// manages a list of states and corresponding presets for a
	/// component. loads the presets into memory on startup, and
	/// allows applying them from memory to the component.
	/// states are enabled in a layered manner, that is: the
	/// default state is always alive, and any enabled states are
	/// applied on top of it in the order of which they were enabled.
	/// 
	/// this class doesn't store any preset data between sessions.
	/// it is merely used to manipulate the component using a list
	/// of states that is sent along at startup. it is very silent
	/// and forgiving; it won't complain if a state isn't found
	/// (since providing a certain state should not be considered
	/// mandatory for a component, and states can be set recursively).
	/// it will also ignore empty presets
	/// </summary>
	public vp_StateManager(vp_Component component, List<vp_State> states)
	{

		m_States = states;
		m_Component = component;

		// create default state and add it to the list
		m_Component.RefreshDefaultState();

		// refresh the initial state, needed for being able to save
		// partial presets in the editor
#if UNITY_EDITOR
			m_Component.RefreshInitialState();
#endif

		// load states and initialize the state id dictionary
		m_StateIds = new Dictionary<string, int>(System.StringComparer.CurrentCulture);
		foreach (vp_State s in m_States)
		{

			s.StateManager = this;

			// store the name and list index of each state in a dictionary for
			// fast lookup. IMPORTANT: the state list (m_States) must never be
			// modified at runtime (i.e. have states reordered, added, renamed
			// or removed) or the dictionary (m_StateIds) will be out of date
			if (!m_StateIds.ContainsKey(s.Name))
				m_StateIds.Add(s.Name, m_States.IndexOf(s));
			else
			{
				Debug.LogWarning("Warning: " + m_Component.GetType() + " on '" + m_Component.name + "' has more than one state named: '" + s.Name + "'. Only the topmost one will be used.");
				m_States[m_DefaultId].StatesToBlock.Add(m_States.IndexOf(s));
			}

			// load up the preset of each user assigned state and
			if (s.Preset == null)
				s.Preset = new vp_ComponentPreset();
			if (s.TextAsset != null)
				s.Preset.LoadFromTextAsset(s.TextAsset);

		}

		// the default state of a component is always the last one in the list
		m_DefaultId = m_States.Count - 1;

	}
Ejemplo n.º 13
0
    /// <summary>
    /// this method applies a preset onto the passed component,
    /// returning true on success
    /// </summary>
    public static bool Apply(vp_Component component, vp_ComponentPreset preset)
    {
        if (preset == null)
        {
            Error("Tried to apply a preset that was null in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        if (preset.m_ComponentType == null)
        {
            Error("Preset ComponentType was null in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        if (component == null)
        {
            UnityEngine.Debug.LogWarning("Warning: Component was null when attempting to apply preset in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        if (component.Type != preset.m_ComponentType)
        {
            string type = "a '" + preset.m_ComponentType + "' preset";
            if (preset.m_ComponentType == null)
            {
                type = "an unknown preset type";
            }
            Error("Applied " + type + " to a '" + component.Type.ToString() + "' component in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        // component and preset both seem ok, so set the preset fields
        // onto the component
        foreach (Field f in preset.m_Fields)
        {
            foreach (FieldInfo destField in component.Fields)
            {
                if (destField.FieldHandle == f.FieldHandle)
                {
                    destField.SetValue(component, f.Args);
                }
            }
        }

        return(true);
    }
Ejemplo n.º 14
0
    /// <summary>
    /// fills a dictionary with all the states as string keys
    /// (instead of objects) and their block lists as string-list
    /// (instead of int-list) values
    /// </summary>
    static void BackupBlockLists(vp_Component component)
    {
        m_BlockListBackups = new Dictionary <string, List <string> >();
        foreach (vp_State blocker in component.States)
        {
            List <string> blockees = new List <string>();
            foreach (int i in blocker.StatesToBlock)
            {
                string blockee = GetStateName(component, i);
                if (blockee != null)
                {
                    blockees.Add(blockee);
                }
            }

            if (!m_BlockListBackups.ContainsKey(blocker.Name))
            {
                m_BlockListBackups.Add(blocker.Name, blockees);
            }
        }
    }
Ejemplo n.º 15
0
 public vp_StateManager(vp_Component component, List <vp_State> states)
 {
     this.m_States    = states;
     this.m_Component = component;
     this.m_Component.RefreshDefaultState();
     this.m_StateIds = new Dictionary <string, int>(StringComparer.CurrentCulture);
     foreach (vp_State current in this.m_States)
     {
         current.StateManager = this;
         if (!this.m_StateIds.ContainsKey(current.Name))
         {
             this.m_StateIds.Add(current.Name, this.m_States.IndexOf(current));
         }
         else
         {
             Debug.LogWarning(string.Concat(new object[]
             {
                 "Warning: ",
                 this.m_Component.GetType(),
                 " on '",
                 this.m_Component.name,
                 "' has more than one state named: '",
                 current.Name,
                 "'. Only the topmost one will be used."
             }));
             this.m_States[this.m_DefaultId].StatesToBlock.Add(this.m_States.IndexOf(current));
         }
         if (current.Preset == null)
         {
             current.Preset = new vp_ComponentPreset();
         }
         if (current.TextAsset != null)
         {
             current.Preset.LoadFromTextAsset(current.TextAsset);
         }
     }
     this.m_DefaultId = this.m_States.Count - 1;
 }
Ejemplo n.º 16
0
    private List<vp_StateInfo> m_States = null; // list sent from the component at startup

    #endregion Fields

    #region Constructors

    ///////////////////////////////////////////////////////////
    // constructor. creates a default state using the values
    // currently set on the component, then loads the presets
    // referenced in the passed list of states.
    ///////////////////////////////////////////////////////////
    public vp_StateManager(vp_Component component, List<vp_StateInfo> states)
    {
        m_States = states;
        m_Component = component;

        // create default state and add it to the list
        m_Component.RefreshDefaultState();

        // refresh the initial state, needed for being able to save
        // partial presets in the editor
        #if UNITY_EDITOR
        m_Component.RefreshInitialState();
        #endif

        // load up the preset of each user assigned state
        foreach (vp_StateInfo s in m_States)
        {
            if(s.Preset == null)
                s.Preset = new vp_ComponentPreset();
            if (s.TextAsset != null)
                s.Preset.LoadFromTextAsset(s.TextAsset);
        }
    }
Ejemplo n.º 17
0
    /// <summary>
    /// creates an empty preset in memory, copies a component's
    /// type and values into it and returns the preset
    /// </summary>
    public static vp_ComponentPreset CreateFromComponent(vp_Component component)
    {
        // TODO: used?

        vp_ComponentPreset preset = new vp_ComponentPreset();

        preset.m_ComponentType = component.Type;

        foreach (FieldInfo f in preset.m_ComponentType.GetFields())
        {
            if (f.IsPublic)
            {
                if (f.FieldType == typeof(float) ||
                    f.FieldType == typeof(Vector4) ||
                    f.FieldType == typeof(Vector3) ||
                    f.FieldType == typeof(Vector2) ||
                    f.FieldType == typeof(int) ||
                    f.FieldType == typeof(bool) ||
                    f.FieldType == typeof(string)
#if ANTICHEAT
                    || f.FieldType == typeof(ObscuredFloat) ||
                    f.FieldType == typeof(ObscuredVector3) ||
                    f.FieldType == typeof(ObscuredVector2) ||
                    f.FieldType == typeof(ObscuredInt) ||
                    f.FieldType == typeof(ObscuredBool) ||
                    f.FieldType == typeof(ObscuredString)
#endif
                    )
                {
                    preset.m_Fields.Add(new Field(f.FieldHandle, f.GetValue(component)));
                }
            }
        }

        return(preset);
    }
	/// <summary>
	/// static overload: creates and loads a preset and sets all
	/// the values on 'component'
	/// </summary>
	public static bool Load(vp_Component component, string fullPath)
	{

		vp_ComponentPreset preset = new vp_ComponentPreset();
		preset.LoadTextStream(fullPath);
		return Apply(component, preset);

	}
	/// <summary>
	/// restores the int block list onto all states by name, by
	/// fetching block lists in string-list format from the
	/// backup dictionary and converting them back to int-lists
	/// to be set on the components
	/// </summary>
	static void RestoreBlockLists(vp_Component component)
	{

		foreach (string s in m_BlockListBackups.Keys)
		{
			vp_State blocker = GetState(component, s);
			if (blocker == null)
				continue;

			List<string> stringBlockList;
			if (!m_BlockListBackups.TryGetValue(s, out stringBlockList))
				continue;

			List<int> intBlockList = new List<int>();
			foreach (string b in stringBlockList)
			{
				int blockee = GetStateId(component, b);
				if (blockee != -1)
					intBlockList.Add(GetStateId(component, b));
			}

			blocker.StatesToBlock = intBlockList;

		}

	}
	/// <summary>
	/// 
	/// </summary>
	public static string GetStateName(vp_Component component, int id)
	{
		if (id == -1)
			return null;
		return component.States[id].Name;
	}
	/// <summary>
	/// draws a button showing if a state is on or off, allowing
	/// the user to toggle states at runtime. will also show
	/// a text saying if the state is currently disallowed
	/// </summary>
	public static void RunTimeStateField(vp_Component component, vp_State state, List<vp_State> stateList)
	{

		EditorGUILayout.BeginHorizontal();

		GUI.color = m_ColorTransparentWhite;
		if (!state.Enabled)
		{
			GUILayout.Space(20);
			GUI.enabled = true;
			GUILayout.Label((stateList.Count - stateList.IndexOf(state) - 1).ToString() + ":", vp_EditorGUIUtility.RightAlignedPathStyle, GUILayout.MinWidth(20), GUILayout.MaxWidth(20));
			GUILayout.BeginHorizontal();
			if (GUILayout.Button(state.Name, vp_EditorGUIUtility.CenteredBoxStyle, GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
			{
				RunTimeStateButtonTarget = component;
				vp_Component[] compos = component.gameObject.GetComponentsInChildren<vp_Component>();
				foreach (vp_Component c in compos)
				{
					c.StateManager.SetState(state.Name, true);
					c.Refresh();
				}
			}
			GUILayout.EndHorizontal();
			GUI.color = m_ColorTransparentWhite;
		}
		else
		{
			

			GUILayout.Space(20);
			GUILayout.Label((stateList.Count - stateList.IndexOf(state) - 1).ToString() + ":", vp_EditorGUIUtility.RightAlignedPathStyle, GUILayout.MinWidth(20), GUILayout.MaxWidth(20));
			if (GUILayout.Button(state.Name,
				((!state.Blocked) ? vp_EditorGUIUtility.CenteredBoxStyleBold : vp_EditorGUIUtility.CenteredStyleBold)
				, GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
			{
				RunTimeStateButtonTarget = component;
				vp_Component[] compos = component.gameObject.GetComponentsInChildren<vp_Component>();
				foreach (vp_Component c in compos)
				{
					c.StateManager.SetState(state.Name, false);
					c.Refresh();
				}
			}
		}
		if (state.Name != "Default")
		{
			if (state.Blocked)
				GUILayout.TextField("(Blocked on " + component.GetType().ToString() + "(" + state.BlockCount + "))", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(100));

			if ((state.TextAsset == null) && (!state.Blocked))
				GUILayout.TextField("(No preset)", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(100));
		}

		EditorGUILayout.EndHorizontal();

	}
	/// <summary>
	/// this is a utility function for forcing state type names to
	/// that of the component. these names may potentially contain
	/// out-of-date type names serialized on earlier versions of UFPS,
	/// or may be a result of copying fields from one type to a related
	/// but different type
	/// </summary>
	public static void UpdateOldStateTypeNames(vp_Component component)
	{

		System.Type componentType = component.Type;

		// update state type names created on v1.3.3, to the 1.4.x type names
		for (int v = 0; v < component.States.Count; v++)
		{
			vp_State s = component.States[v];

			// force states to have the type names of the component 
			if (s.TypeName != componentType.Name)
				s.TypeName = componentType.Name;

			// TODO: remove ?
			if (s.TypeName == "vp_FPSController" ||
				s.TypeName == "vp_FPSCamera" ||
				s.TypeName == "vp_FPSSHooter" ||
				s.TypeName == "vp_FPSWeapon")
			{
				s.TypeName = s.TypeName.Replace("vp_FPS", "vp_FP");
				Debug.Log("Corrected " + s.Name + " state type name to:" + s.TypeName + ".");
			}


		}

	}
	/// <summary>
	/// opens a dialog for saving presets
	/// </summary>
	static private void ShowSaveDifferenceDialog(vp_Component component)
	{

		string path = Application.dataPath;

		// LORE: in order not to overwrite existing values in a disk
		// preset, we'll load the disk preset before saving over it.
		// since the file dialog system will execute its callback
		// twice in case of an already existing file (and delete the
		// target file in the process) we need to store the preset
		// in memory outside of the callback and skip loading it on
		// the second iteration
		vp_ComponentPreset diskPreset = null;

		vp_FileDialog.Create(vp_FileDialog.Mode.Save, "Save Tweaks", path, delegate(string filename)
		{

			// only attempt to load the disk preset the first time
			// the callback is executed
			if (diskPreset == null)
			{
				diskPreset = new vp_ComponentPreset();
				// attempt to load target preset into memory, ignoring
				// load errors in the process
				bool logErrorState = vp_ComponentPreset.LogErrors;
				vp_ComponentPreset.LogErrors = false;
				diskPreset.LoadTextStream(filename);
				vp_ComponentPreset.LogErrors = logErrorState;
			}

			vp_FileDialog.Result = vp_ComponentPreset.SaveDifference(component.InitialState.Preset, component, filename, diskPreset);

		}, ".txt");

	}
Ejemplo n.º 24
0
    ///////////////////////////////////////////////////////////
    // draws a field allowing the user to create, reorganize,
    // name, assign presets to and delete states on a component
    ///////////////////////////////////////////////////////////
    public static bool StateFoldout(bool foldout, vp_Component component, List <vp_StateInfo> stateList, vp_ComponentPersister persister = null)
    {
        bool before = foldout;

        foldout = EditorGUILayout.Foldout(foldout,
                                          (foldout && !Application.isPlaying) ? "State             Preset" : "States"
                                          );

        if (foldout != before)
        {
            component.RefreshDefaultState();
        }

        if (foldout)
        {
            for (int v = 0; v < stateList.Count; v++)
            {
                int s = v;
                if (!Application.isPlaying)
                {
                    vp_PresetEditorGUIUtility.StateField(stateList[s], stateList);
                }
                else
                {
                    vp_PresetEditorGUIUtility.RunTimeStateField(component, stateList[s], stateList);
                }
            }

            GUILayout.BeginHorizontal();
            if (!Application.isPlaying)
            {
                if (GUILayout.Button("Add State", GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
                {
                    stateList.Add(new vp_StateInfo(component.GetType().Name, "New State", ""));
                    component.RefreshDefaultState();
                }
            }
            else
            {
                GUI.color = Color.clear;
                GUILayout.Button("", GUILayout.MinWidth(36), GUILayout.MaxWidth(36));
                GUI.color = Color.white;
            }
            if (!Application.isPlaying)
            {
                GUILayout.EndHorizontal();
            }
            if (persister != null)
            {
                vp_PresetEditorGUIUtility.PersistToggle(persister);
            }
            if (Application.isPlaying)
            {
                GUILayout.EndHorizontal();
            }

            vp_EditorGUIUtility.Separator();
        }

        return(foldout);
    }
Ejemplo n.º 25
0
 /// <summary>
 /// opens a dialog for saving presets
 /// </summary>
 static private void ShowSaveDialog(vp_Component component)
 {
     ShowSaveDialog(component, false);
 }
	/// <summary>
	/// this method applies a preset onto the passed component,
	/// returning true on success 
	/// </summary>
	public static bool Apply(vp_Component component, vp_ComponentPreset preset)
	{

		if (preset == null)
		{
			Error("Tried to apply a preset that was null in '" + vp_Utility.GetErrorLocation() + "'");
			return false;
		}

		if (preset.m_ComponentType == null)
		{
			Error("Preset ComponentType was null in '" + vp_Utility.GetErrorLocation() + "'");
			return false;
		}

		if (component == null)
		{
			UnityEngine.Debug.LogWarning("Warning: Component was null when attempting to apply preset in '" + vp_Utility.GetErrorLocation() + "'");
			return false;
		}
		
		if (component.Type != preset.m_ComponentType)
		{
			string type = "a '" + preset.m_ComponentType + "' preset";
			if (preset.m_ComponentType == null)
				type = "an unknown preset type";
			Error("Applied " + type + " to a '" + component.Type.ToString() + "' component in '" + vp_Utility.GetErrorLocation() + "'");
			return false;
		}

		// component and preset both seem ok, so set the preset fields
		// onto the component
		foreach (Field f in preset.m_Fields)
		{
			foreach (FieldInfo destField in component.Fields)
			{
				if (destField.FieldHandle == f.FieldHandle)
					destField.SetValue(component, f.Args);
			}
		}

		return true;

	}
	/// <summary>
	/// static overload: creates and loads a preset and sets all
	/// the values on 'component', then returns the preset
	/// </summary>
	public static vp_ComponentPreset LoadFromTextAsset(vp_Component component, TextAsset file)
	{

		vp_ComponentPreset preset = new vp_ComponentPreset();
		preset.LoadFromTextAsset(file);
		Apply(component, preset);
		return preset;

	}
	/// <summary>
	/// static overload: creates and loads a preset and sets all
	/// the values on 'component', then returns the preset
	/// </summary>
	public static vp_ComponentPreset LoadFromResources(vp_Component component, string resourcePath)
	{

		vp_ComponentPreset preset = new vp_ComponentPreset();
		preset.LoadFromResources(resourcePath);
		Apply(component, preset);
		return preset;

	}
	/// <summary>
	/// opens a dialog for saving presets
	/// </summary>
	static private void ShowSaveDialog(vp_Component component)
	{
		ShowSaveDialog(component, false);
	}
Ejemplo n.º 30
0
    /// <summary>
    /// draws a field allowing the user to create, reorganize,
    /// name, assign presets to and delete states on a component
    /// </summary>
    public static bool StateFoldout(bool foldout, vp_Component component, List <vp_State> stateList, vp_ComponentPersister persister = null)
    {
        bool before = foldout;

        foldout = EditorGUILayout.Foldout(foldout,
                                          (foldout && !Application.isPlaying) ? "State             Preset" : "States"
                                          );

        if (foldout != before)
        {
            m_ShowBlockListFor = null;
            component.RefreshDefaultState();
        }

        if (foldout)
        {
            if (m_ShowBlockListFor != null)
            {
                if (!stateList.Contains(m_ShowBlockListFor))
                {
                    foldout = false;
                }
            }
        }

        if (foldout)
        {
            for (int v = 0; v < stateList.Count; v++)
            {
                vp_State s = stateList[v];
                if (!Application.isPlaying)
                {
                    vp_PresetEditorGUIUtility.StateField(s, stateList, component);
                    if ((m_ShowBlockListFor != null) && m_ShowBlockListFor == s)
                    {
                        StateBlockList(component, s);
                    }
                }
                else
                {
                    vp_PresetEditorGUIUtility.RunTimeStateField(component, s, stateList);
                }
            }

            GUILayout.BeginHorizontal();
            if (!Application.isPlaying)
            {
                if (GUILayout.Button("Add State", GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
                {
                    m_ShowBlockListFor = null;
                    string newStateName = "Untitled";
                    int    n            = 1;
                    while (GetStateId(component, newStateName) != -1)
                    {
                        n++;
                        newStateName = newStateName.Substring(0, 8) + (n < 10?"0":"") + n.ToString();
                    }

                    stateList.Add(new vp_State(component.GetType().Name, newStateName, ""));
                    component.RefreshDefaultState();
                    EditorUtility.SetDirty(component);
                }
            }
            else
            {
                GUI.color = Color.clear;
                GUILayout.Button("", GUILayout.MinWidth(36), GUILayout.MaxWidth(36));
                GUI.color = Color.white;
            }
            if (!Application.isPlaying)
            {
                GUILayout.EndHorizontal();
            }
            if (persister != null)
            {
                vp_PresetEditorGUIUtility.PersistToggle(persister);
            }
            if (Application.isPlaying)
            {
                GUILayout.EndHorizontal();
            }

            vp_EditorGUIUtility.Separator();
        }

        return(foldout);
    }
	static private void ShowSaveDialog(vp_Component component, bool showLoadDialogAfterwards)
	{
		string path = Application.dataPath;

		vp_FileDialog.Create(vp_FileDialog.Mode.Save, "Save Preset", path, delegate(string filename)
		{
			vp_FileDialog.Result = vp_ComponentPreset.Save(component, filename);

			if (showLoadDialogAfterwards)
				ShowLoadDialog(component);

		}, ".txt");


	}
Ejemplo n.º 32
0
    /// <summary>
    ///
    /// </summary>
    static void StateBlockList(vp_Component component, vp_State blocker)
    {
        GUILayout.BeginHorizontal();
        GUILayout.Space(20);
        GUILayout.BeginVertical();

        string componentName = component.GetType().ToString();

        if (componentName.Contains("vp_"))
        {
            componentName = componentName.Substring(3);
        }

        EditorGUILayout.HelpBox("'" + blocker.Name + "' blocks " + ((blocker.StatesToBlock.Count > 0) ? blocker.StatesToBlock.Count.ToString() : "no") + " state" + ((blocker.StatesToBlock.Count == 1) ? "" : "s") + " on this " + componentName + ".", MessageType.None);

        GUILayout.BeginVertical();
        int e = 0;

        foreach (vp_State blockee in component.States)
        {
            if (blockee == blocker)
            {
                continue;
            }

            if (blockee.Name == "Default")
            {
                continue;
            }

            int i = component.States.IndexOf(blockee);

            if (component.States[i].StatesToBlock.Contains(component.States.IndexOf(blocker)))
            {
                GUI.enabled = false;
            }

            if (e % 2 == 0)
            {
                GUILayout.BeginHorizontal();
            }
            GUILayout.Space(20);
            bool before = blocker.StatesToBlock.Contains(i);
            bool after  = before;

            after = GUILayout.Toggle(after, blockee.Name);

            if (before != after)
            {
                if (!before)
                {
                    blocker.StatesToBlock.Add(i);
                }
                else
                {
                    blocker.StatesToBlock.Remove(i);
                }

                EditorUtility.SetDirty(component);
            }
            if (e % 2 == 1)
            {
                GUILayout.Space(10);
                GUILayout.EndHorizontal();
            }

            e++;
            GUI.enabled = true;
        }
        if (e % 2 == 1)
        {
            GUILayout.EndHorizontal();
        }

        GUILayout.EndVertical();

        GUILayout.BeginHorizontal();
        EditorGUILayout.HelpBox("Select states to be disallowed on this " + componentName + " while the '" + blocker.Name + "' state is enabled. A state can not block itself, a state that blocks it or the Default state.", MessageType.Info);
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        if (GUILayout.Button("Close", GUILayout.MinWidth(100), GUILayout.MaxWidth(50)))
        {
            m_ShowBlockListFor = null;
            EditorUtility.SetDirty(component);
        }

        GUILayout.EndVertical();
        GUILayout.EndHorizontal();
        GUILayout.Space(10);
        GUILayout.EndHorizontal();
        GUILayout.Space(10);
    }
	/// <summary>
	/// draws a field allowing the user to create, reorganize,
	/// name, assign presets to and delete states on a component
	/// </summary>
	public static bool StateFoldout(bool foldout, vp_Component component, List<vp_State> stateList, vp_ComponentPersister persister = null)
	{

		RunTimeStateButtonTarget = null;

		bool before = foldout;
		foldout = EditorGUILayout.Foldout(foldout,
			(foldout && !Application.isPlaying) ? "State             Preset" : "States"
			);

		if (foldout != before)
		{
			m_ShowBlockListFor = null;
			component.RefreshDefaultState();

			if (!Application.isPlaying)
				UpdateOldStateTypeNames(component);

		}

		if (foldout)
		{
			if (m_ShowBlockListFor != null)
			{
				if (!stateList.Contains(m_ShowBlockListFor))
					foldout = false;
			}
		}

		if (foldout)
		{

			for (int v = 0; v < stateList.Count; v++)
			{
				vp_State s = stateList[v];
				if (!Application.isPlaying)
				{
					vp_PresetEditorGUIUtility.StateField(s, stateList, component);
					if ((m_ShowBlockListFor != null) && m_ShowBlockListFor == s)
					{
						StateBlockList(component, s);
					}
				}
				else
				{
					vp_PresetEditorGUIUtility.RunTimeStateField(component, s, stateList);
				}
			}

			GUILayout.BeginHorizontal();
			if (!Application.isPlaying)
			{
				if (GUILayout.Button("Add State", GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
				{
					m_ShowBlockListFor = null;
					string newStateName = "Untitled";
					int n = 1;
					while (GetStateId(component, newStateName) != -1)
					{
						n++;
						newStateName = newStateName.Substring(0, 8) + (n<10?"0":"") + n.ToString();
					}
					
					stateList.Add(new vp_State(component.GetType().Name, newStateName, ""));
					component.RefreshDefaultState();
					EditorUtility.SetDirty(component);
				}
			}
			else
			{
				GUI.color = Color.clear;
				GUILayout.Button("", GUILayout.MinWidth(36), GUILayout.MaxWidth(36));
				GUI.color = Color.white;
			}
			if (!Application.isPlaying)
				GUILayout.EndHorizontal();
			if (persister != null)
				vp_PresetEditorGUIUtility.PersistToggle(persister);
			if (Application.isPlaying)
				GUILayout.EndHorizontal();

			vp_EditorGUIUtility.Separator();

		}

		return foldout;

	}
Ejemplo n.º 34
0
    /// <summary>
    /// draws a row displaying a preset state name, a path and
    /// buttons for browsing the path + deleting the state
    /// </summary>
    public static void StateField(vp_State state, List <vp_State> stateList, vp_Component component)
    {
        GUI.enabled = !Application.isPlaying;           // only allow preset field interaction in 'stopped' mode

        EditorGUILayout.BeginHorizontal();

        string orig = state.Name;

        if (state.Name == "Default")
        {
            GUI.enabled = false;
            EditorGUILayout.TextField(state.Name, GUILayout.MinWidth(90), GUILayout.MaxWidth(90));
            GUI.enabled = true;
        }
        else
        {
            if (m_ShowBlockListFor != null)
            {
                if (!component.States.Contains(m_ShowBlockListFor))
                {
                    m_ShowBlockListFor = null;
                }
                else if (m_ShowBlockListFor.StatesToBlock.Contains(component.States.IndexOf(state)))
                {
                    GUI.color = m_ColorGrayYellow;
                }
            }
            state.Name = EditorGUILayout.TextField(state.Name, GUILayout.MinWidth(90), GUILayout.MaxWidth(90));
            GUI.color  = Color.white;
        }

        if (orig != state.Name)
        {
            int collisions = -1;
            foreach (vp_State s in stateList)
            {
                if (s.Name == state.Name)
                {
                    collisions++;
                }
            }

            if (state.Name == "Default")
            {
                vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "'Default' is a reserved state name.");
                state.Name = orig;
            }
            else if (state.Name.Length == 0)
            {
                vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "State name can't be empty.");
                state.Name = orig;
            }
            else if (collisions > 0)
            {
                vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "There is already a state named '" + state.Name + "'.\nTIP: If you need a similar state name, begin by adding numbers at the end.");
                state.Name = orig;
            }
            else
            {
                EditorUtility.SetDirty(component);
            }
        }

        PresetField(state);

        if (state.Name == "Default")
        {
            if (state.TextAsset == null)
            {
                GUI.enabled = false;
                GUILayout.TextField("(Inspector)", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(60));
            }
            else
            {
                GUI.enabled = true;
                if (GUILayout.Button("Unlock", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(30), GUILayout.MinHeight(15)))
                {
                    state.TextAsset = null;
                    EditorUtility.SetDirty(component);
                }
            }
        }
        else
        {
            if (stateList.IndexOf(state) == 0)
            {
                GUI.enabled = false;
            }

            GUI.SetNextControlName("state");
            if (GUILayout.Button("^", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(15), GUILayout.MaxWidth(15), GUILayout.MinHeight(15)))
            {
                BackupBlockLists(component);
                int i = stateList.IndexOf(state);
                if (i != 0)
                {
                    stateList.Remove(state);
                    stateList.Insert(i - 1, state);
                }
                RestoreBlockLists(component);

                // focus this button to get rid of possible textfield focus,
                // or the textfields won't update properly when moving state
                GUI.FocusControl("state");
                EditorUtility.SetDirty(component);
            }

            GUI.enabled = true;

            if (state.StatesToBlock != null)
            {
                if ((state.StatesToBlock.Count > 0) && ((m_ShowBlockListFor == null) || (!component.States.Contains(m_ShowBlockListFor)) || m_ShowBlockListFor == state))
                {
                    GUI.color = m_ColorGrayYellow;
                }
            }

            GUI.enabled = (component.States.Count > 2);
            if (GUILayout.Button("B", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(15), GUILayout.MaxWidth(15), GUILayout.MinHeight(15)))
            {
                if (m_ShowBlockListFor == state)
                {
                    m_ShowBlockListFor = null;
                }
                else
                {
                    m_ShowBlockListFor = state;
                }
                EditorUtility.SetDirty(component);
            }
            GUI.enabled = true;
            GUI.color   = Color.white;

            if (GUILayout.Button("X", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(15), GUILayout.MaxWidth(15), GUILayout.MinHeight(15)))
            {
                vp_MessageBox.Create(vp_MessageBox.Mode.YesNo, "Confirm", "Are you sure you want to delete the state '" + state.Name + "'?", delegate(vp_MessageBox.Answer answer)
                {
                    if (answer == vp_MessageBox.Answer.Yes)
                    {
                        BackupBlockLists(component);
                        stateList.Remove(state);
                        RestoreBlockLists(component);
                        EditorUtility.SetDirty(component);
                    }
                });

                EditorUtility.SetDirty(component);
            }
        }

        GUI.enabled = true;

        EditorGUILayout.EndHorizontal();
    }
	/// <summary>
	/// 
	/// </summary>
	static void StateBlockList(vp_Component component, vp_State blocker)
	{

		GUILayout.BeginHorizontal();
		GUILayout.Space(20);
		GUILayout.BeginVertical();

		string componentName = component.GetType().ToString();
		if (componentName.Contains("vp_"))
			componentName = componentName.Substring(3);

		if (blocker.StatesToBlock == null)
			blocker.StatesToBlock = new List<int>();

		EditorGUILayout.HelpBox("'" + blocker.Name + "' blocks " + ((blocker.StatesToBlock.Count > 0) ? blocker.StatesToBlock.Count.ToString() : "no") + " state" + ((blocker.StatesToBlock.Count == 1) ? "" : "s") + " on this " + componentName + ".", MessageType.None);

		GUILayout.BeginVertical();
		int e = 0;
		foreach (vp_State blockee in component.States)
		{

			if (blockee == blocker)
				continue;

			if (blockee.Name == "Default")
				continue;

			int i = component.States.IndexOf(blockee);

			if (component.States[i].StatesToBlock == null)
				component.States[i].StatesToBlock = new List<int>();

			if (component.States[i].StatesToBlock.Contains(component.States.IndexOf(blocker)))
				GUI.enabled = false;

			if (e % 2 == 0)
			GUILayout.BeginHorizontal();
			GUILayout.Space(20);
			bool before = blocker.StatesToBlock.Contains(i);
			bool after = before;

			after = GUILayout.Toggle(after, blockee.Name);

			if(before != after)
			{
				if(!before)
					blocker.StatesToBlock.Add(i);
				else
					blocker.StatesToBlock.Remove(i);

				EditorUtility.SetDirty(component);
			}
			if (e % 2 == 1)
			{
				GUILayout.Space(10);
				GUILayout.EndHorizontal();
			}

			e++;
			GUI.enabled = true;

		}
		if (e % 2 == 1)
			GUILayout.EndHorizontal();

		GUILayout.EndVertical();
	
		GUILayout.BeginHorizontal();
		EditorGUILayout.HelpBox("Select states to be disallowed on this " + componentName + " while the '" + blocker.Name + "' state is enabled. A state can not block itself, a state that blocks it or the Default state.", MessageType.Info);
		GUILayout.EndHorizontal();

		GUILayout.BeginHorizontal();
		GUILayout.FlexibleSpace();
		if (GUILayout.Button("Close", GUILayout.MinWidth(100), GUILayout.MaxWidth(50)))
		{
			m_ShowBlockListFor = null;
			EditorUtility.SetDirty(component);
		}

		GUILayout.EndVertical();
		GUILayout.EndHorizontal();
		GUILayout.Space(10);
		GUILayout.EndHorizontal();
		GUILayout.Space(10);

	}
Ejemplo n.º 36
0
    /// <summary>
    /// this method applies a preset onto the passed component,
    /// returning true on success
    /// </summary>
    public static bool Apply(vp_Component component, vp_ComponentPreset preset)
    {
        if (preset == null)
        {
            Error("Tried to apply a preset that was null in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        if (preset.m_ComponentType == null)
        {
            Error("Preset ComponentType was null in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        if (component == null)
        {
            UnityEngine.Debug.LogWarning("Warning: Component was null when attempting to apply preset in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        if (component.Type != preset.m_ComponentType)
        {
            string type = "a '" + preset.m_ComponentType + "' preset";
            if (preset.m_ComponentType == null)
            {
                type = "an unknown preset type";
            }
            Error("Applied " + type + " to a '" + component.Type.ToString() + "' component in '" + vp_Utility.GetErrorLocation() + "'");
            return(false);
        }

        // component and preset both seem ok, so set the preset fields
        // onto the component
        for (int p = 0; p < preset.m_Fields.Count; p++)
        {
            FieldInfo destField = FieldInfo.GetFieldFromHandle(preset.m_Fields[p].FieldHandle);
#if ANTICHEAT
            if ((destField.FieldType == typeof(ObscuredFloat)) && (preset.m_Fields[p].Args.GetType() == typeof(float)))
            {
                ObscuredFloat o = (float)preset.m_Fields[p].Args;
                destField.SetValue(component, o);
            }
            else if ((destField.FieldType == typeof(ObscuredVector3)) && (preset.m_Fields[p].Args.GetType() == typeof(Vector3)))
            {
                ObscuredVector3 o = (Vector3)preset.m_Fields[p].Args;
                destField.SetValue(component, o);
            }
            else if ((destField.FieldType == typeof(ObscuredVector2)) && (preset.m_Fields[p].Args.GetType() == typeof(Vector2)))
            {
                ObscuredVector2 o = (Vector2)preset.m_Fields[p].Args;
                destField.SetValue(component, o);
            }
            else if ((destField.FieldType == typeof(ObscuredInt)) && (preset.m_Fields[p].Args.GetType() == typeof(int)))
            {
                ObscuredInt o = (int)preset.m_Fields[p].Args;
                destField.SetValue(component, o);
            }
            else if ((destField.FieldType == typeof(ObscuredBool)) && (preset.m_Fields[p].Args.GetType() == typeof(bool)))
            {
                ObscuredBool o = (bool)preset.m_Fields[p].Args;
                destField.SetValue(component, o);
            }
            else if ((destField.FieldType == typeof(ObscuredString)) && (preset.m_Fields[p].Args.GetType() == typeof(string)))
            {
                ObscuredString o = (string)preset.m_Fields[p].Args;
                destField.SetValue(component, o);
            }
            else
#endif
            destField.SetValue(component, preset.m_Fields[p].Args);
        }

        return(true);
    }
	/// <summary>
	/// draws a row displaying a preset state name, a path and
	/// buttons for browsing the path + deleting the state
	/// </summary>
	public static void StateField(vp_State state, List<vp_State> stateList, vp_Component component)
	{

		GUI.enabled = !Application.isPlaying;	// only allow preset field interaction in 'stopped' mode

		EditorGUILayout.BeginHorizontal();

		string orig = state.Name;
		if (state.Name == "Default")
		{
			GUI.enabled = false;
			EditorGUILayout.TextField(state.Name, GUILayout.MinWidth(90), GUILayout.MaxWidth(90));
			GUI.enabled = true;
		}
		else
		{
			if (m_ShowBlockListFor != null)
			{
				if (!component.States.Contains(m_ShowBlockListFor))
					m_ShowBlockListFor = null;
				else
				{
					if (m_ShowBlockListFor.StatesToBlock == null)
						m_ShowBlockListFor.StatesToBlock = new List<int>();
					if (m_ShowBlockListFor.StatesToBlock.Contains(component.States.IndexOf(state)))
						GUI.color = m_ColorGrayYellow;
				}
			}
			state.Name = EditorGUILayout.TextField(state.Name, GUILayout.MinWidth(90), GUILayout.MaxWidth(90));
			GUI.color = Color.white;
		}

		if (orig != state.Name)
		{

			int collisions = -1;
			foreach (vp_State s in stateList)
			{
				if (s.Name == state.Name)
					collisions++;
			}

			if (state.Name == "Default")
			{
				vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "'Default' is a reserved state name.");
				state.Name = orig;
			}
			else if (state.Name.Length == 0)
			{
				vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "State name can't be empty.");
				state.Name = orig;
			}
			else if (collisions > 0)
			{
				vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "There is already a state named '" + state.Name +"'.\nTIP: If you need a similar state name, begin by adding numbers at the end." );
				state.Name = orig;
			}
			else
				EditorUtility.SetDirty(component);
		}

		PresetField(state);

		if (state.Name == "Default")
		{
			if (state.TextAsset == null)
			{
				GUI.enabled = false;
				GUILayout.TextField("(Inspector)", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(60));
			}
			else
			{
				GUI.enabled = true;
				if (GUILayout.Button("Unlock", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(30), GUILayout.MinHeight(15)))
				{
					state.TextAsset = null;
					EditorUtility.SetDirty(component);
				}
			}
		}
		else
		{
			if (stateList.IndexOf(state) == 0)
				GUI.enabled = false;

			GUI.SetNextControlName("state");
			if (GUILayout.Button("^", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(15), GUILayout.MaxWidth(15), GUILayout.MinHeight(15)))
			{
				BackupBlockLists(component);
				int i = stateList.IndexOf(state);
				if (i != 0)
				{
					stateList.Remove(state);
					stateList.Insert(i - 1, state);
				}
				RestoreBlockLists(component);

				// focus this button to get rid of possible textfield focus,
				// or the textfields won't update properly when moving state
				GUI.FocusControl("state");
				EditorUtility.SetDirty(component);
			}

			GUI.enabled = true;

			if (state.StatesToBlock == null)
				state.StatesToBlock = new List<int>();

			if ((state.StatesToBlock.Count > 0) && ((m_ShowBlockListFor == null) || (!component.States.Contains(m_ShowBlockListFor)) || m_ShowBlockListFor == state))
				GUI.color = m_ColorGrayYellow;

			GUI.enabled = (component.States.Count > 2);
			if (GUILayout.Button("B", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(15), GUILayout.MaxWidth(15), GUILayout.MinHeight(15)))
			{
				if (m_ShowBlockListFor == state)
					m_ShowBlockListFor = null;
				else
					m_ShowBlockListFor = state;
				EditorUtility.SetDirty(component);
			}
			GUI.enabled = true;
			GUI.color = Color.white;

			if (GUILayout.Button("X", vp_EditorGUIUtility.SmallButtonStyle, GUILayout.MinWidth(15), GUILayout.MaxWidth(15), GUILayout.MinHeight(15)))
			{
				vp_MessageBox.Create(vp_MessageBox.Mode.YesNo, "Confirm", "Are you sure you want to delete the state '" + state.Name + "'?", delegate(vp_MessageBox.Answer answer)
				{
					if (answer == vp_MessageBox.Answer.Yes)
					{
						BackupBlockLists(component);
						stateList.Remove(state);
						RestoreBlockLists(component);
						EditorUtility.SetDirty(component);
					}
				});

				EditorUtility.SetDirty(component);
			}

		}

		GUI.enabled = true;

		EditorGUILayout.EndHorizontal();

	}
    ///////////////////////////////////////////////////////////
    // draws a button showing if a state is on or off, allowing
    // the user to toggle states at runtime. will also show
    // a text saying if the state is currently disallowed
    ///////////////////////////////////////////////////////////
    public static void RunTimeStateField(vp_Component component, vp_StateInfo state, List<vp_StateInfo> stateList)
    {
        EditorGUILayout.BeginHorizontal();

        GUI.color = m_ColorTransparentWhite;
        if (!state.Enabled)
        {
            GUILayout.Space(20);
            GUI.enabled = true;
            GUILayout.Label((stateList.Count - stateList.IndexOf(state) - 1).ToString() + ":", vp_EditorGUIUtility.RightAlignedPathStyle, GUILayout.MinWidth(20), GUILayout.MaxWidth(20));
            GUILayout.BeginHorizontal();
            if(GUILayout.Button(state.Name, vp_EditorGUIUtility.CenteredBoxStyle, GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
            {
                vp_Component[] compos = component.gameObject.GetComponentsInChildren<vp_Component>();
                foreach (vp_Component c in compos)
                {
                    c.StateManager.SetState(state.Name, true);
                    c.Refresh();
                }
            }
            if (!state.Allowed)
                GUILayout.Label("(Disallowed)");
            GUILayout.EndHorizontal();
            GUI.color = m_ColorTransparentWhite;
        }
        else
        {
            GUILayout.Space(20);
            GUILayout.Label((stateList.Count - stateList.IndexOf(state) - 1).ToString() + ":", vp_EditorGUIUtility.RightAlignedPathStyle, GUILayout.MinWidth(20), GUILayout.MaxWidth(20));
            if (GUILayout.Button(state.Name, vp_EditorGUIUtility.CenteredBoxStyleBold, GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
            {
                vp_Component[] compos = component.gameObject.GetComponentsInChildren<vp_Component>();
                foreach (vp_Component c in compos)
                {
                    c.StateManager.SetState(state.Name, false);
                    c.Refresh();
                }
            }
        }

        if (state.Name != "Default" && state.TextAsset == null)
            GUILayout.TextField("<- Warning: No preset!", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(100));

        EditorGUILayout.EndHorizontal();
    }
	/// <summary>
	/// fills a dictionary with all the states as string keys
	/// (instead of objects) and their block lists as string-list
	/// (instead of int-list) values
	/// </summary>
	static void BackupBlockLists(vp_Component component)
	{

		m_BlockListBackups = new Dictionary<string, List<string>>();
		foreach (vp_State blocker in component.States)
		{
			List<string> blockees = new List<string>();

			if (blocker.StatesToBlock == null)
				blocker.StatesToBlock = new List<int>();

			foreach (int i in blocker.StatesToBlock)
			{
				string blockee = GetStateName(component, i);
				if(blockee != null)
					blockees.Add(blockee);
			}

			if (!m_BlockListBackups.ContainsKey(blocker.Name))
				m_BlockListBackups.Add(blocker.Name, blockees);

		}

	}
    ///////////////////////////////////////////////////////////
    // draws a field allowing the user to create, reorganize,
    // name, assign presets to and delete states on a component
    ///////////////////////////////////////////////////////////
    public static bool StateFoldout(bool foldout, vp_Component component, List<vp_StateInfo> stateList, vp_ComponentPersister persister = null)
    {
        bool before = foldout;
        foldout = EditorGUILayout.Foldout(foldout,
            (foldout && !Application.isPlaying) ? "State             Preset" : "States"
            );

        if (foldout != before)
            component.RefreshDefaultState();

        if (foldout)
        {

            for (int v = 0; v < stateList.Count; v++)
            {
                int s = v;
                if (!Application.isPlaying)
                {
                    vp_PresetEditorGUIUtility.StateField(stateList[s], stateList);
                }
                else
                {
                    vp_PresetEditorGUIUtility.RunTimeStateField(component, stateList[s], stateList);
                }
            }

            GUILayout.BeginHorizontal();
            if (!Application.isPlaying)
            {
                if (GUILayout.Button("Add State", GUILayout.MinWidth(90), GUILayout.MaxWidth(90)))
                {
                    stateList.Add(new vp_StateInfo(component.GetType().Name, "New State", ""));
                    component.RefreshDefaultState();
                }
            }
            else
            {
                GUI.color = Color.clear;
                GUILayout.Button("", GUILayout.MinWidth(36), GUILayout.MaxWidth(36));
                GUI.color = Color.white;
            }
            if(!Application.isPlaying)
                GUILayout.EndHorizontal();
            if (persister != null)
                vp_PresetEditorGUIUtility.PersistToggle(persister);
            if (Application.isPlaying)
                GUILayout.EndHorizontal();

            vp_EditorGUIUtility.Separator();

        }

        return foldout;
    }
	/// <summary>
	/// 
	/// </summary>
	public static int GetStateId(vp_Component component, string state)
	{

		for (int v = 0; v < component.States.Count; v++)
		{
			if (component.States[v].Name == state)
				return v;
		}
		return -1;

	}
Ejemplo n.º 42
0
    /// <summary>
    ///
    /// </summary>
    public static void GenerateStatesAndPresetsFromDerivedComponent(Component derivedComponent, Component baseComponent, string path)
    {
        //System.Type derivedType = derivedComponent.GetType();	// TEST (see below)
        System.Type baseType = baseComponent.GetType();

        // TEST: disabled to allow converting from vp_FPController to
        // vp_CapsuleController. evaluate this down the line
        //if (!vp_EditorUtility.IsSameOrSubclass(baseType, derivedType))
        //	return;

        vp_Component vpDerived = derivedComponent as vp_Component;
        vp_Component vpBase    = baseComponent as vp_Component;

        if (vpDerived == null)
        {
            return;
        }

        if (vpBase == null)
        {
            return;
        }

        for (int v = 0; v < vpDerived.States.Count; v++)
        {
            // abort if old state has no text asset
            vp_State oldState = vpDerived.States[v];
            if (oldState.TextAsset == null)
            {
                continue;
            }

            // abort if we fail to load old text asset into a preset
            vp_ComponentPreset preset = new vp_ComponentPreset();
            if (!preset.LoadFromTextAsset(oldState.TextAsset))
            {
                continue;
            }

            // try to make the preset compatible with the base component. this
            // will fail if it has no compatible fields, in which case we abort
            if (preset.TryMakeCompatibleWithComponent(vpBase) < 1)
            {
                continue;
            }

            // we have a new preset that is compatible with the base component.
            // save it at a temporary, auto-generated path
            string typeName = oldState.TypeName.Replace("vp_FP", "");
            typeName = typeName.Replace("vp_", "");
            string filePath = path + "/" + typeName + "_" + vpBase.gameObject.name + "_" + oldState.Name + ".txt";
            vp_ComponentPreset.Save(preset, filePath);
            AssetDatabase.Refresh();

            // add a corresponding state, into which we load the new preset
            vp_State newState = new vp_State(baseType.Name, vpDerived.States[v].Name, null, null);
            vpBase.States.Add(newState);
            // System.Threading.Thread.Sleep(100);	// might come in handy on slow disk (?)
            newState.TextAsset = AssetDatabase.LoadAssetAtPath(filePath, typeof(TextAsset)) as TextAsset;
        }
    }
	/// <summary>
	/// opens a dialog for loading presets
	/// </summary>
	static private void ShowLoadDialog(vp_Component component)
	{

		string path = Application.dataPath.Replace("\\", "/");
		vp_FileDialog.Create(vp_FileDialog.Mode.Open, "Load Preset", path, delegate(string filename)
		{
			if (!vp_ComponentPreset.Load(component, filename))
				vp_FileDialog.Result = "Failed to load preset '" + vp_FileDialog.ExtractFilenameFromPath(filename) + "'.\n\nIs it the correct component type? (" + component.GetType().ToString() + ")";
			else
				EditorUtility.SetDirty(component);
		}, ".txt");

	}
	/// <summary>
	/// 
	/// </summary>
	public int TryMakeCompatibleWithComponent(vp_Component component)
	{

		m_ComponentType = component.GetType();


		List<FieldInfo> availableFields = new List<FieldInfo>(m_ComponentType.GetFields());

		for (int v = m_Fields.Count - 1; v > -1; v--)
		{
			foreach (FieldInfo field in availableFields)
			{

				// TEMP: special case since these values are not relevant in 3rd person
				if (field.Name.Contains("PositionOffset") ||
				field.Name.Contains("RotationOffset"))
					goto kill;

				if (m_Fields[v].FieldHandle == field.FieldHandle)
					goto keep;
			}

			kill:

			m_Fields.Remove(m_Fields[v]);

			keep:{ }
		}

		return m_Fields.Count;

	}