cegredev
cegredev

Reputation: 1579

How to use compile-time classes in an at runtime compiled class?

I am compiling code at runtime in my Unity game and want to use premade classes in that user-generated code. Although both classes are in the same namespace, the at runtime compiled class can't find the other and gives me the following error:

InvalidOperationException: Error (CS0234): The type or namespace name 'PremadeClass' (that's the class name) does not exist in the namespace `GameLevel' (that's the namespace name). Are you missing an assembly reference?

Based of previous errors I had with this project, I am guessing that I need to reference the .dll file for the premade class in the runtime-code, but don't know where Unity stores those for each class, or if it even generates them. This could be wrong though, as both classes are, again, in the same namespace and I'm inexperienced with C#.

I wrote my compiling code using this tutorial - check it out for more information on that (it's just plain code with some explanations), but this is the most important part:

public void Compile() {
  CSharpCodeProvider provider = new CSharpCodeProvider();
  CompilerParameters parameters = new CompilerParameters();
  //...
  parameters.ReferencedAssemblies.Add("path/UnityEngine.dll");
  parameters.OutputAssembly = "path/fileName.dll";
  parameters.GenerateInMemory = false; //generates actual file
  parameters.GenerateExecutable = false; //generates .dll instead of .exe
  //...
  parameters.OutputAssembly = Application.dataPath + className + ".dll";
  CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
  //...
  Assembly assembly = results.CompiledAssembly;
  Type program = assembly.GetType("GameLevel." + className);
  MethodInfo excecuteMethod = program.GetMethod("Excecute");

  excecuteMethod.Invoke(null, null);
}

This is the basic structure of the premade class:

namespace GameLevel
{
    public class PrecompiledClass
    {
         public void Foo() {
         }
    }
}

And this is basically how the runtime code utilises it:

namespace GameLevel
{
    public class RuntimeClass
    {
         public void Foo() {
             new PrecompiledClass().Foo();
         }
    }
}

I am thankful for your answers!

Upvotes: 0

Views: 264

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

Put your premade classes in a seperate assembly (dll), then include that dll in your parameters.ReferencedAssemblies.Add("path/Premade.dll")

The reason you should use a seperate assembly is so only the classes you want the player to access will be visable to them.

Upvotes: 1

Related Questions