public void RelaxBlockingList(vp_State blocker)
 {
     foreach (int current in blocker.StatesToBlock)
     {
         this.m_States[current].RemoveBlocker(blocker);
     }
 }
    /// <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 + ".");
            }
        }
    }
Example #3
0
 /// <summary>
 /// removes a state from the list of states that blocks this one
 /// </summary>
 public void RemoveBlocker(vp_State blocker)
 {
     if (CurrentlyBlockedBy.Contains(blocker))
     {
         CurrentlyBlockedBy.Remove(blocker);
     }
 }
Example #4
0
 /// <summary>
 /// adds a state to the list of states that blocks this one
 /// </summary>
 public void AddBlocker(vp_State blocker)
 {
     if (!CurrentlyBlockedBy.Contains(blocker))
     {
         CurrentlyBlockedBy.Add(blocker);
     }
 }
Example #5
0
    /// <summary>
    /// copies component values into the default state's preset.
    /// if needed, creates & adds default state to the state list.
    /// to be called on app startup and statemanager recombine
    /// </summary>
#if UNITY_EDITOR
    public void RefreshInitialState()
    {
        m_InitialState        = null;
        m_InitialState        = new vp_State(GetType().Name, "Internal_Initial", null);
        m_InitialState.Preset = new vp_ComponentPreset();
        m_InitialState.Preset.InitFromComponent(this);
    }
    /// <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;
        }
    }
 public void ImposeBlockingList(vp_State blocker)
 {
     foreach (int current in blocker.StatesToBlock)
     {
         this.m_States[current].AddBlocker(blocker);
     }
 }
    /// <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();
    }
Example #9
0
    /// <summary>
    /// this is a utility function for cleaning out state type names created
    /// on v1.3.3, updating internally to the 1.4.x type names. it will
    /// likely be removed in an upcoming version
    /// </summary>
    private static void UpdateOldStateTypeNames(List <vp_State> stateList)
    {
        for (int v = 0; v < stateList.Count; v++)
        {
            vp_State s = stateList[v];

            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 + ".");
            }
        }
    }
Example #10
0
    /// <summary>
    /// sees if the component has a default state. if so, makes
    /// sure it's in index zero of the list, if not, creates it.
    /// </summary>
    public void RefreshDefaultState()
    {
        vp_State defaultState = null;

        if (States.Count == 0)
        {
            // there are no states, so create default state
            defaultState = new vp_State(GetType().Name, "Default", null);
            States.Add(defaultState);
        }
        else
        {
            for (int v = States.Count - 1; v > -1; v--)
            {
                if (States[v].Name == "Default")
                {
                    // found default state, make sure it's in the back
                    defaultState = States[v];
                    States.Remove(defaultState);
                    States.Add(defaultState);
                }
            }
            if (defaultState == null)
            {
                // there are states, but no default state so create it
                defaultState = new vp_State(GetType().Name, "Default", null);
                States.Add(defaultState);
            }
        }

        if (defaultState.Preset == null || defaultState.Preset.ComponentType == null)
        {
            defaultState.Preset = new vp_ComponentPreset();
        }

        if (defaultState.TextAsset == null)
        {
            defaultState.Preset.InitFromComponent(this);
        }

        defaultState.Enabled = true;            // default state is always enabled

        m_DefaultState = defaultState;
    }
    /// <summary>
    /// draws a slot to which the user can drag a preset TextAsset
    /// </summary>
    private static void PresetField(vp_State state)
    {
        TextAsset orig = state.TextAsset;

        state.TextAsset = (TextAsset)EditorGUILayout.ObjectField(state.TextAsset, typeof(TextAsset), false);
        if (state.TextAsset != orig)
        {
            if (state.TextAsset != null)
            {
                if ((vp_ComponentPreset.GetFileTypeFromAsset(state.TextAsset) == null ||
                     vp_ComponentPreset.GetFileTypeFromAsset(state.TextAsset).Name != state.TypeName))
                {
                    vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "Error: The file '" + state.TextAsset.name + " ' does not contain a preset of type '" + state.TypeName + "'.");
                    state.TextAsset = orig;
                    return;
                }
            }
        }
    }
    /// <summary>
    /// draws a disabled preset field for the built-in default
    /// state, making the user aware of the state
    /// </summary>
    public static void DefaultStateField(vp_State state)
    {
        EditorGUILayout.BeginHorizontal();

        GUI.enabled = false;
        GUILayout.Label("Default", "Textfield", GUILayout.MinWidth(90), GUILayout.MaxWidth(90));

        PresetField(state);

        GUILayout.TextField("(editor)", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(100));

        EditorGUILayout.Space();
        GUI.color = Color.clear;
        GUILayout.Button("...", GUILayout.MinWidth(24), GUILayout.MaxWidth(24));
        GUILayout.Button("X", GUILayout.MinWidth(24), GUILayout.MaxWidth(24));
        GUI.color   = Color.white;
        GUI.enabled = true;

        EditorGUILayout.EndHorizontal();
    }
    /// <summary>
    /// draws a disabled preset field for the built-in default
    /// state, making the user aware of the state
    /// </summary>
    public static void DefaultStateField(vp_State state)
    {
        EditorGUILayout.BeginHorizontal();

        GUI.enabled = false;
        GUILayout.Label("Default", "Textfield", GUILayout.MinWidth(90), GUILayout.MaxWidth(90));

        PresetField(state);

        GUILayout.TextField("(editor)", vp_EditorGUIUtility.NoteStyle, GUILayout.MinWidth(100));

        EditorGUILayout.Space();
        GUI.color = Color.clear;
        GUILayout.Button("...", GUILayout.MinWidth(24), GUILayout.MaxWidth(24));
        GUILayout.Button("X", GUILayout.MinWidth(24), GUILayout.MaxWidth(24));
        GUI.color = Color.white;
        GUI.enabled = true;

        EditorGUILayout.EndHorizontal();
    }
    /// <summary>
    /// removes this state from the 'CurrentlyBlockedBy' list of
    /// all states in this state's 'StatesToBlock' list
    /// </summary>
    public void RelaxBlockingList(vp_State blocker)
    {
        if (blocker == null)
        {
            return;
        }

        if (blocker.StatesToBlock == null)
        {
            return;
        }

        if (m_States == null)
        {
            return;
        }

        foreach (int blockee in blocker.StatesToBlock)
        {
            m_States[blockee].RemoveBlocker(blocker);
        }
    }
Example #15
0
    /// <summary>
    /// adds this state to the 'CurrentlyBlockedBy' list of all
    /// states in this state's 'StatesToBlock' list
    /// </summary>
    public void ImposeBlockingList(vp_State blocker)
    {
        if (blocker == null)
        {
            return;
        }

        if (blocker.StatesToBlock == null)
        {
            return;
        }

        if (m_States == null)
        {
            return;
        }

        for (int v = 0; v < blocker.StatesToBlock.Count; v++)
        {
            m_States[blocker.StatesToBlock[v]].AddBlocker(blocker);
        }
    }
Example #16
0
    public void RefreshDefaultState()
    {
        vp_State vp_State = null;

        if (this.States.Count == 0)
        {
            vp_State = new vp_State(base.GetType().Name, "Default", null, null);
            this.States.Add(vp_State);
        }
        else
        {
            for (int i = this.States.Count - 1; i > -1; i--)
            {
                if (this.States[i].Name == "Default")
                {
                    vp_State = this.States[i];
                    this.States.Remove(vp_State);
                    this.States.Add(vp_State);
                }
            }
            if (vp_State == null)
            {
                vp_State = new vp_State(base.GetType().Name, "Default", null, null);
                this.States.Add(vp_State);
            }
        }
        if (vp_State.Preset == null || vp_State.Preset.ComponentType == null)
        {
            vp_State.Preset = new vp_ComponentPreset();
        }
        if (vp_State.TextAsset == null)
        {
            vp_State.Preset.InitFromComponent(this);
        }
        vp_State.Enabled    = true;
        this.m_DefaultState = vp_State;
    }
	/// <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>
	/// 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;

	}
	/// <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);

	}
Example #20
0
	/// <summary>
	/// copies component values into the default state's preset.
	/// if needed, creates & adds default state to the state list.
	/// to be called on app startup and statemanager recombine
	/// </summary>
#if UNITY_EDITOR
	public void RefreshInitialState()
	{

		m_InitialState = null;
		m_InitialState = new vp_State(Type.Name, "Internal_Initial", null);
		m_InitialState.Preset = new vp_ComponentPreset();
		m_InitialState.Preset.InitFromComponent(this);

	}
Example #21
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;
        }
    }
Example #22
0
	/// <summary>
	/// removes a state from the list of states that blocks this one
	/// </summary>
	public void RemoveBlocker(vp_State blocker)
	{

		if (CurrentlyBlockedBy.Contains(blocker))
			CurrentlyBlockedBy.Remove(blocker);

	}
Example #23
0
	/// <summary>
	/// sees if the component has a default state. if so, makes
	/// sure it's in index zero of the list, if not, creates it.
	/// </summary>
	public void RefreshDefaultState()
	{

		vp_State defaultState = null;

		if (States.Count == 0)
		{
			// there are no states, so create default state
			defaultState = new vp_State(Type.Name, "Default", null);
			States.Add(defaultState);
		}
		else
		{
			for (int v = States.Count - 1; v > -1; v--)
			{
				if (States[v].Name == "Default")
				{
					// found default state, make sure it's in the back
					defaultState = States[v];
					States.Remove(defaultState);
					States.Add(defaultState);
				}
			}
			if (defaultState == null)
			{
				// there are states, but no default state so create it
				defaultState = new vp_State(Type.Name, "Default", null);
				States.Add(defaultState);
			}
		}

		if (defaultState.Preset == null || defaultState.Preset.ComponentType == null)
			defaultState.Preset = new vp_ComponentPreset();

		if(defaultState.TextAsset == null)
			defaultState.Preset.InitFromComponent(this);

		defaultState.Enabled = true;	// default state is always enabled

		m_DefaultState = defaultState;

	}
    /// <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);
    }
Example #25
0
	/// <summary>
	/// adds a state to the list of states that blocks this one
	/// </summary>
	public void AddBlocker(vp_State blocker)
	{

		if (!CurrentlyBlockedBy.Contains(blocker))
			CurrentlyBlockedBy.Add(blocker);

	}
	/// <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();

	}
    /// <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>
	/// 
	/// </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>
    /// 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();
    }
Example #30
0
    /// <summary>
    /// adds this state to the 'CurrentlyBlockedBy' list of all
    /// states in this state's 'StatesToBlock' list
    /// </summary>
    public void ImposeBlockingList(vp_State blocker)
    {
        if (blocker == null)
            return;

        if (blocker.StatesToBlock == null)
            return;

        if (m_States == null)
            return;

        foreach (int blockee in blocker.StatesToBlock)
        {
            m_States[blockee].AddBlocker(blocker);
        }
    }
	/// <summary>
	/// draws a slot to which the user can drag a preset TextAsset
	/// </summary>
	private static void PresetField(vp_State state)
	{

		TextAsset orig = state.TextAsset;
		state.TextAsset = (TextAsset)EditorGUILayout.ObjectField(state.TextAsset, typeof(TextAsset), false);
		if (state.TextAsset != orig)
		{
			if (state.TextAsset != null)
			{
				if ((vp_ComponentPreset.GetFileTypeFromAsset(state.TextAsset) == null ||
				vp_ComponentPreset.GetFileTypeFromAsset(state.TextAsset).Name != state.TypeName))
				{
					vp_MessageBox.Create(vp_MessageBox.Mode.OK, "Error", "Error: The file '" + state.TextAsset.name + " ' does not contain a preset of type '" + state.TypeName + "'.");
					state.TextAsset = orig;
					return;
				}
				//else
				//	Debug.Log(state.TypeName);

			}
		}

	}
Example #32
0
    /// <summary>
    /// removes this state from the 'CurrentlyBlockedBy' list of
    /// all states in this state's 'StatesToBlock' list
    /// </summary>
    public void RelaxBlockingList(vp_State blocker)
    {
        if (blocker == null)
            return;

        if (blocker.StatesToBlock == null)
            return;

        if (m_States == null)
            return;

        foreach (int blockee in blocker.StatesToBlock)
        {
            m_States[blockee].RemoveBlocker(blocker);
        }
    }