- Home /
C# string as type for AddComponent
Hello,
I am making a custom Editor Window where I can create quests. The tool generates a .cs file using streamwriter. But when I want to assign the script in editor to an object (questGiver) it can't use the string as a type.
using UnityEditor;
using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.Text;
[ExecuteInEditMode]
public class Quest : EditorWindow
{
public static int levelRequirement = 0;
public static string questName ="Enter Questname Here";
public static int questExp = 0;
public static string questGiver = "Quest Giver";
public static GameObject selectedObject;
public float secs = 10f;
public float startVal = 0f;
public float progress = 0f;
public class curQuest : MonoBehaviour{};
//QuestStates:
// -1 Player is too low level for the quest so the questgiver denies the request
// -2 Player activates the quest
// -3 Player has not yet finishes the quest
// -4 Player has failed the quest but he can start over
// -5 Player finishes the quest
public static string questState_1_String = "Can not begin Quest now";
public static string questState_2_String = "Here is your Quest";
public static string questState_3_String = "You're not finished yet";
public static string questState_4_String = "Please try again";
public static string questState_5_String = "Get your loot";
[MenuItem ("Window/Quests")]
static void Init () {
// Get existing open window or if none, make a new one:
Quest window = (Quest)EditorWindow.GetWindow (typeof (Quest));
window.Show();
}
void OnGUI(){
questName = EditorGUILayout.TextField ("Questname", questName);
questGiver = Selection.activeTransform ? Selection.activeTransform.name : "Select Quest Giver";
EditorGUILayout.LabelField("Quest Giver: ", questGiver);
levelRequirement = EditorGUILayout.IntSlider ("Minimum Level", levelRequirement, 0, 100);
questState_1_String = EditorGUILayout.TextField ("State 1 Text", questState_1_String);
questState_2_String = EditorGUILayout.TextField ("State 2 Text", questState_2_String);
questState_3_String = EditorGUILayout.TextField ("State 3 Text", questState_3_String);
questState_4_String = EditorGUILayout.TextField ("State 4 Text", questState_4_String);
questState_5_String = EditorGUILayout.TextField ("State 5 Text", questState_5_String);
questExp = EditorGUILayout.IntSlider ("Experience Points", questExp, 0, 1000);
if (GUILayout.Button ("Add Quest")) {
Create ();
}
EditorGUILayout.LabelField ("Compiling:", EditorApplication.isCompiling ? "YES" : "NO");
if (!EditorApplication.isCompiling) {
if (GUILayout.Button ("Add Quest to Questgiver")) {
AddScript ();
}
}
}
static void Create()
{
string copyPath = "Assets/Quests/" + questName + ".cs";
if (File.Exists (copyPath) == false) { // do not overwrite
using (StreamWriter outfile =
new StreamWriter (copyPath)) {
outfile.WriteLine ("using UnityEngine;");
outfile.WriteLine ("using System.Collections;");
outfile.WriteLine ("");
outfile.WriteLine ("public class " + questName + " : MonoBehaviour {");
outfile.WriteLine (" ");
outfile.WriteLine ("public int levelRequirement = " + levelRequirement + ";");
outfile.WriteLine (" ");
outfile.WriteLine (" // Use this for initialization");
outfile.WriteLine (" void Start () {");
outfile.WriteLine (" ");
outfile.WriteLine (" }");
outfile.WriteLine (" ");
outfile.WriteLine (" ");
outfile.WriteLine (" // Update is called once per frame");
outfile.WriteLine (" void Update () {");
outfile.WriteLine (" ");
outfile.WriteLine (" }");
outfile.WriteLine ("}");
}//File written
}
AssetDatabase.Refresh ();
}
void AddScript(){
GameObject selectedObject = Selection.activeTransform.gameObject;
selectedObject.AddComponent<questName>();
}
void OnInspectorUpdate(){
Repaint ();
}
}
The error is here in:
void AddScript(){
GameObject selectedObject = Selection.activeTransform.gameObject;
selectedObject.AddComponent<questName>();
}
This is my compiler error:
Assets/Editor/Quest.cs(97,45): error CS0118: `Quest.questName' is a `field' but a `type' was expected
It can't use questName as a Type for AddComponent. How should I add the script to the GameObject?
Greetings,
GerardM
There were alternatives given in the docs when AddComponent(String) was deprecated.
http://blogs.unity3d.com/2015/01/21/addcomponentstring-api-removal-in-unity-5-0/
And a Snippet from the Unity 5 Upgrade Guide
AddComponent(string), when called with a variable cannot be automatically updated to the generic version AddComponent<T>(). In such cases the API Updater will replace the call with a call to APIUpdaterRuntimeServices.AddComponent(). This method is meant to allow you to test your game in editor mode (they do a best effort to try to resolve the type at runtime) but it is not meant to be used in production, so it is an error to build a game with calls to such method). On platforms that support Type.GetType(string) you can try to use GetComponent(Type.GetType(typeName)) as a workaround.
Interestingly, it's still in the docs but I can't see any blog posts of it being put back in.
Answer by coolraiman · May 03, 2016 at 03:54 PM
reflection is your friend take note that reflection is not stable with webgl and if my memory is correct, IOS builds have limitation on it to
here is how to get a type from a string https://msdn.microsoft.com/en-us/library/w3f99sx1(v=vs.110).aspx
I tried to implement it in my script but I have no idea how, could you show me? Also this project is not meant for webgl or IOS so that won't be a problem. By the way, many thanks for your quick answer.
selectedObject.AddComponent<Type.GetType(questName)>();
never had to use this functionnality of reflection but this should work
if it is to be used outside of the editor, use try catch to prevent crash
If I do that I get:
Assets/Editor/Quest.cs(98,70): error CS1525: Unexpected symbol `)'
Answer by troien · May 03, 2016 at 04:59 PM
If I undestand what you intend to do, you could use the string overload of AddComponent I guess...
Like so:
selectedObject.AddComponent(questName);
Internally this most likely uses reflection, but why reinvent the wheel? :p
I tried that but the script doesn't exist yet so it won't work :(
Uhm... but how/why do you intend to add a script that doesn't exist in the first place???
I mean whichever option you choose, you can't add scripts that don't exist...
I write the script in this script and after compiling I want to add it to a gameobject
Follow this Question
Related Questions
Add Component Using String, Runtime Types? 3 Answers
C# - passing a Type var to GameObject.AddComponent 1 Answer
Multiple Cars not working 1 Answer
AddComponent with runtime type checking 0 Answers
Distribute terrain in zones 3 Answers