Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Failing to compile foreign code to add to the game

Discussion in 'Scripting' started by howaboutno000, Dec 21, 2020.

  1. howaboutno000

    howaboutno000

    Joined:
    Nov 13, 2020
    Posts:
    20
    I'm working on an addon system for my game. This means that I have an interface, and that the addon should inherit from that interface, written in a file, then the game reads the file and then I'll manage. But I fail at compilation.

    The code that I current have is following:

    The render, which is invoked by MonoBehaviour Start in a GameObject:
    Code (CSharp):
    1. using System;
    2. using System.CodeDom.Compiler;
    3. using System.IO;
    4. using System.Reflection;
    5. using Microsoft.CSharp;
    6. using UnityEngine;
    7.  
    8.  
    9. public static class test
    10. {
    11.  
    12.     public static void LLL()
    13.     {
    14.         var zax = CreateFunction("BinaryFunction");
    15.         if (zax == null) throw new Exception("Something's not right");
    16.         //var betterFunction = (Func<double, double, double>)Delegate.CreateDelegate(typeof(Func<double, double, double>), zax);
    17.         //Debug.Log($"Result: {betterFunction(10.0f, 12.0f)}");
    18.     }
    19.  
    20.     public static MethodInfo CreateFunction(string function)
    21.     {
    22.         string fromFile;
    23.         fromFile = File.ReadAllText(Path.Combine(Application.dataPath, "file.cs"));
    24.         CSharpCodeProvider provider = new CSharpCodeProvider();
    25.         var cp = new CompilerParameters();
    26.         CompilerResults results = provider.CompileAssemblyFromSource(cp, fromFile);
    27.  
    28.         foreach (object z in results.Errors)
    29.         {
    30.             Debug.Log($"Compilation Error: {z}");
    31.         }
    32.  
    33.         Type binaryFunction = results.CompiledAssembly.GetType("XXX.AAA");
    34.         return binaryFunction.GetMethod("S***");
    35.     }
    36.  
    37. }
    Then the supposed addon, its located within Asset folder to assure that there are no syntax errors:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using Yes;
    4.  
    5.  
    6. public interface IComeon
    7. {
    8.     void Test(in TestStruct testStruct);
    9.     void Test1(Transform testTransform);
    10. }
    11.  
    12.  
    13. namespace XXX
    14. {
    15.  
    16.     public class Addon : IComeon
    17.     {
    18.  
    19.         public void Test(in TestStruct testStruct)
    20.         {
    21.             throw new NotImplementedException();
    22.         }
    23.  
    24.         public void Test1(Transform testTransform)
    25.         {
    26.             throw new NotImplementedException();
    27.         }
    28.  
    29.     }
    30. }
    31.  
    32. namespace Yes
    33. {
    34.     public struct TestStruct
    35.     {
    36.         public int easily;
    37.     }
    38. }
    This is already an nth attempt so I've focused the code on two compilation errors:
    - bypmtztt.0.cs(8,11) : error CS1525: Unexpected symbol `in'
    - bypmtztt.0.cs(19,19) : error CS1525: Unexpected symbol `in'
    Which I do understand, I just don't know the solution.

    Removing both "in", throws the remaining errors:
    - pi194hlh.0.cs(9,13): The type or namespace name `UnityEngine' could not be found. Are you missing an assembly reference?
    - pi194hlh.0.cs(9,13): error CS0246: The type or namespace name `Transform' could not be found. Are you missing an assembly reference?
    I understand that I miss reference but how do I add it?
    I tried everything I could guess in
    cp.ReferencedAssemblies.Add();
    but it throws something like:
    error CS0006: Metadata file `UnityEngine' could not be found


    Which leaves me with 3 questions:
    - Can (and how do) I compile structs and interfaces into a DLL for future use for other people?
    - How can I allow addon to reference UnityEngine's structs and classes?
    - Is there a way to have an "in" parameter on the functions?

    I need to do all this from code itself, not external invocations.
     
    Last edited: Dec 21, 2020
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Usually if you want to play with precompiled DLLs you make a Visual Studio project, add references to the appropriate version of UnityEngine.dll you wish to compile against, compile the DLL with Visual Studio, then drag it into the Unity project to use.

    I'm unfamiliar with the
    in
    parameter modifier. Sounds like maybe it's from a later version of C# that Unity might not yet support. Code you compile in Unity has to fall within its C# spec.

    Honestly I've never seen someone trying to compile C# under their own script control in Unity, so I'm not even sure that's a thing.
     
  3. howaboutno000

    howaboutno000

    Joined:
    Nov 13, 2020
    Posts:
    20
    It does compile if the script is generic. So it uses primitive types from System and doesn't inherit from anything. It works, but only if its an extreme standalone with no non-vanilla references (like Unity).