Giter VIP home page Giter VIP logo

weaver's Introduction

Weaver

A a code weaver built for use in Unity Engine. Based very heavily off of Fody. Implmented using Mono.Cecil.

What is Code Weaving?

Weaving refers to the process of injecting functionality into an existing program. This can be done conceptually at a number of levels:

  • Source code weaving would inject source code lines before the code is compiled
  • IL weaving (for .NET) adds the code as IL instructions in the assembly

A great example of this is the Unity Project Updater. It uses both versions of code weaving on your project. It uses text replacing for unsupported code in your source files and IL weaving for compiled dlls.

Weaver for now only uses IL Weaving which runs once every time an assembly is recompiled.

Features

  • Hooked into Unity callbacks to run automatically.
  • Filter only the assemblies you want to weave.
  • Validation for end user.
  • Custom logger.
  • Utility functions to write MSIL.

How To Use

Weaver is run using a single ScriptableObjects you will need to create a new instance for your project. Int Unity use the create menu to create a new instance.

Right click in the Project Window Create/Weaver/Settings

You Only Need One: Only one instance should exist in your project since every operation only needs to happen once.

Weaved Assemblies

When you create a new instance by default Weaver will not edit any assemblies. It is up to you to define which assemblies you want to be modified. Click on the + icon on the bottom right and a context menu will pop up with all the valid assemblies you can target. You can also disable the assemblies in this list by unchecking the check box beside it's name. This will stop them from being edited.

Menu Content: The assemblies in the menu are populated with reflection and will be found if they they are anywhere ein the Unity Project.

Components

Weaver is built around it's components as they are what do the weaving of the assemblies. Weaver itself is just a provider of information for the components. They get notified when they should run and on which assemblies they should run against.

To add a new component use the (+) button to open the menu and pick any option.

There Can Only Be One: You can only have one instance of each component as having more would be useless.

Adding New Componet Types: The component menu uses reflection to find all types that inherit from WeaverComponent and are not abstract and are part of the EditorAssembly. Any new classes that match thoese rules will populate inside the menu.

Logs

To make the process a bit more clear but also not spam to your console Weaver logs all it's contents to it's own console on the ScriptableObject. Errors are also logged to the Unity console because that is important.

Toggling Weaver

If you would like Weaver to not run while in your project you can uncheck Is Enabled in the settings object. You also have the option to define if Weaver will run depending on the Script Symbols defined in Unity.

You can use any flag like UNITY_EDITOR or the inverse flag !UNITY_EDITOR. Weaver will only run if all flags are active.

Current Extensions

  • Method Timer - Any method with the MethodTimerAttribute will be timed using Stopwatch and logged to the console.

  • Profile Sample - Any method with the ProfileSample attribute will be have a profile sample injected into the method. The sample name will be the name of the method.

  • Property Changed : Invoke a callback whenever a property is marked with the [OnChanged(string callback)] attribute..

Git Sub Modules

  • Capture Groups: Used to generate the screen shots because I am too lazy to do that by hand. All code is under the preproc CAPTURE_GROUPS so feel free to remove this if you copy over the code.

Meta

Handcrafted by Byron Mayne [twittergithub]

Released under the MIT License.

If you have any feedback or suggestions for Weaver feel free to contact me.

weaver's People

Contributors

byronmayne avatar byronplaytika avatar kaw0 avatar konh avatar metzsg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

weaver's Issues

Script won't update after first successful weaving

I'm using Assembly Definitions within Unity and created a custom weaving component to weave specific assemblies. For some reason, if I add a field to a type in an assembly using my component, and the type of the field is a delegate type that I've defined, scripts in the assembly don't appear to update after the first successful modification/weaving.

The following code runs correctly every time I recompile, but if I attempt to replace PropertyChangedEventHandler with a custom delegate type, the assembly compiles and weaves correctly only once, then refuses to compile/update with newer script changes. It only works again if I restart Unity. I'm not receiving any error messages:


var handlerReference = typeDefinition.Module.ImportReference(typeof(System.ComponentModel.PropertyChangedEventHandler));
 
var fieldDef = new FieldDefinition(nameof(INotifyMethodCalled.MethodCalled), FieldAttributes.Private | FieldAttributes.NotSerialized, handlerReference);

typeDefinition.Fields.Add(fieldDef);

Any help would be greatly appreciated.

NullRef

unity_2017-11-28_22-58-25

On opening the project with Unity 2017.2.0f3

Disable BuildDetails Generation

Would be nice to be able to disable the build details that gets generated each time we do test builds. Work around for right now is to delete the BuildDetailsScriptBuilder.cs file. Didn't see a clear way to easily add a toggle to turn it off myself

Which type of license does this project use?

I need to use this on a paid asset and I would like to know if I'm allowed to include this on my project. Thanks!

EDIT: I just realized that in the bottom of the README the MIT License is advertised, but could you include a LICENSE file. Just to clarify.

Just checking something

Image of Weaver Settings

Just wanted to know if the default settings upon cloning the repository is right, as it seems to have one blank assembly?

NotSupportedException on weaving in an empty 2019.1.0 project

In a completely new and otherwise empty 2019.1.0 project, I get this error after setting it up with these simple settings:

Components:

  • Weaver.PropertyChangedComponent

Weaved Assemblies:

  • Library\ScriptAssemblies\Assembly-CSharp.dll
Exception was thrown while weaving assemblies. System.NotSupportedException: The invoked member is not supported in a dynamic module.
  at Weaver.WeaverSettings.WeaveAssemblies (System.Collections.Generic.IList`1[T] assemblies) [0x002cf] in C:\Dev\Unity Projects\Weaver Test\Assets\Weaver\Editor\Settings\WeaverSettings.cs:273 
  at Weaver.WeaverSettings.CheckForAssemblyModifications () [0x00169] in C:\Dev\Unity Projects\Weaver Test\Assets\Weaver\Editor\Settings\WeaverSettings.cs:192 
UnityEngine.Debug:LogError(Object)
Weaver.Log:Error(String, String, Boolean, Int32) (at Assets/Weaver/Editor/Utility Types/Logging/Log.cs:95)
Weaver.WeaverSettings:CheckForAssemblyModifications() (at Assets/Weaver/Editor/Settings/WeaverSettings.cs:208)
UnityEditor.AssemblyReloadEvents:OnBeforeAssemblyReload()

Weaver Test.zip

Does this work with IL2CPP?

If the scripting backend for a Unity project is IL2CPP, does your Weaver still work?

Thanks - and super interesting project!

[Feature Request] adding a weaver attribute for logging methods

I think it will be good to add a weaver like that :

The attribute

 public class MethodLogger : Attribute
    {
        void OnMethodWillExecute(parameters, method) 
        {
           Debug.Log("entered in method " + method + " with parameters " + parameters);
        }
       
        void OnMethodExecuted(returnValue, method)
       {
           Debug.Log("finished in method " + method + " with return value " + returnValue);
       }
    }

The use case:

using UnityEngine;
using Arch.Internal.Advices;

public class SceneEventManager : MonoBehaviour
{
   [MethodLogger]
   public void Test()
   {
      Debug.Log("Invoked Test");
   }

   private void Update()
   {
       if (Input.anyKeyDown)
       {
                Test();
       }
   }
}

[Weaver Component] Expose Scripting Symbols

Right now components have a scripting symbols field that is hidden along with the is active flag. It would be nice to allow users to use this fields.

Right now I can't expose them as I need to recompile all assemblies when they change.

NotSupportedException occurs

I am very glad to find Weaver for my project.
But, I had so many same exceptions.

NotSupportedException: The invoked member is not supported in a dynamic module.
System.Reflection.Emit.AssemblyBuilder.get_Location () (at <567df3e0919241ba98db88bec4c6696f>:0)
Weaver.WeaverAssemblyResolver..ctor () (at Assets/AssetStore/Weaver/Editor/Resolver/WeaverAssemblyResolver.cs:39)
Weaver.WeaverSettings.GetReaderParameters () (at Assets/AssetStore/Weaver/Editor/Settings/WeaverSettings.cs:193)
Weaver.WeaverSettings.WeaveAssembly (System.String assemblyPath) (at Assets/AssetStore/Weaver/Editor/Settings/WeaverSettings.cs:250)

When resolving location of dynamic modules, for example,

Assembly: Microsoft.GeneratedCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

I modified the line below at WeaverAssemblyResolver() constructor to solve the problem temporally.

if (assembly.ReflectionOnly)
if (assembly.ReflectionOnly || assembly.IsDynamic)

Missing references to Mono.Cecil

Seems Unity changed once again how it includes the Mono.Cecil stuff. We cannot reference the dlls anymore by asmdef.
Because you updated the API to the newer version of cecil we cannot use the dlls from this repository's history.

So I just grabbed them from the Unity folder (Editor\Data\il2cpp\build\deploy\net471 in this case) and put them into the Lib folder where you had them before, works fine.

This is an issue at least with 2019.4 (and i guess 2019.3).

Working on mac?

Hi

Great job on this!
Have you tried it on mac? I'm asking because I'm seeing some strange behaviors.
Somehow it seems to prevent Unity from reloading assemblies at all. I can see that the package processes the scrips properly and it does write correct assemblies to disk, but once I enable this package Unity will no longer load new changes to the scripts after the initial one.
So if I make a change to a script, I see Unity compiling it and everything, but when I press play I still get the same result as after the first time the package was enabled. Restarting Unity does make it load the latest changes however.
I also cannot seem to get it to work for standalone builds (tested x64 mac standalone). The PostProcessScene callback runs as it is supposed to, but the standalone player does not have the modified assemblies.

PrecompiledAssemblyException at importing library into my project

Hi!

The following error occurs when importing the library into my project:

PrecompiledAssemblyException: Multiple precompiled assemblies with the same name Mono.Cecil.dll included for the current platform. Only one assembly with the same name is allowed per platform. Assembly path: {0}
UnityEditor.Scripting.ScriptCompilation.EditorBuildRules.CreateTargetAssemblies (System.Collections.Generic.IEnumerable`1[T] customScriptAssemblies, System.Collections.Generic.IEnumerable`1[T] precompiledAssemblies) (at C:/buildslave/unity/build/Editor/Mono/Scripting/ScriptCompilation/EditorBuildRules.cs:221)
UnityEditor.Scripting.ScriptCompilation.EditorCompilation.UpdateCustomTargetAssemblies () (at C:/buildslave/unity/build/Editor/Mono/Scripting/ScriptCompilation/EditorCompilation.cs:672)
UnityEditor.Scripting.ScriptCompilation.EditorCompilation.SetAllCustomScriptAssemblyJsonContents (System.String[] paths, System.String[] contents, System.String[] guids) (at C:/buildslave/unity/build/Editor/Mono/Scripting/ScriptCompilation/EditorCompilation.cs:892)
UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface.SetAllCustomScriptAssemblyJsonContents (System.String[] allAssemblyJsonPaths, System.String[] allAssemblyJsonContents, System.String[] guids) (at C:/buildslave/unity/build/Editor/Mono/Scripting/ScriptCompilation/EditorCompilationInterface.cs:241)

What could I do? I don't know exactly what I'm doing, so I can't check if the problem is caused by this or because I didn't done this on the right way.

I don't know exactly how to hook my new created Component (PLEASE, could you add more documentation about how to create new components? I would be very appreciated)

using Mono.Cecil;
using Mono.Cecil.Cil;
using System;
using UnityEditor;
using Weaver;
using Weaver.Extensions;

namespace UnityEngine.Core.Editor
{
    public class RadioMenuComponent : WeaverComponent
    {
        public override string addinName => "Radio Menu";

        private TypeReference m_InvokerTypeReference;
        private MethodReference m_PerfomActionMethodRef;

        public override void VisitModule(ModuleDefinition moduleDefinition)
        {
            // Get 'Radio Menu Invoker' type
            Type invokerType = typeof(RadioMenuInvoker);
            // Import the 'Radio Menu Invoker' type
            m_InvokerTypeReference = moduleDefinition.Import(invokerType);
            // Get the type def by resolving
            TypeDefinition invokerTypeDef = m_InvokerTypeReference.Resolve();
            // Get our start sample
            m_PerfomActionMethodRef = invokerTypeDef.GetMethod("PerformAction", 1);

            // Import everything
            moduleDefinition.Import(typeof(RadioMenuAttribute));
            moduleDefinition.Import(m_PerfomActionMethodRef);
        }

        public override void VisitMethod(MethodDefinition methodDefinition)
        {
            // This isn't executing... When it's supposed to be executed?
            Debug.Log(methodDefinition.FullName);

            // Check if we have our attribute
            CustomAttribute customAttribute = methodDefinition.GetCustomAttribute<RadioMenuAttribute>();
            if (customAttribute == null)
                return;

            // Remove the attribute
            methodDefinition.CustomAttributes.Remove(customAttribute);

            MethodBody body = methodDefinition.Body;
            ILProcessor bodyProcessor = body.GetILProcessor();

            // Start of method
            {
                Instruction _02 = Instruction.Create(OpCodes.Call, methodDefinition.Module.Import(m_PerfomActionMethodRef));
                bodyProcessor.InsertBefore(body.Instructions[0], _02);
             }
        }

        public class RadioMenuInvoker
        {
            public static void PerformAction(RadioMenuAttribute radioMenu)
            {
                bool enabled = radioMenu.Enabled;

                // Set checkmark on menu item
                Menu.SetChecked(radioMenu.Path, enabled);

                // Saving editor state
                EditorPrefs.SetBool(radioMenu.Path, enabled);

                radioMenu.Enabled = enabled;

                // Perform your logic here...
            }
        }
    }

}
using System;
using System.Collections.Generic;

namespace UnityEngine.Core.Editor
{
    using Extensions;

    // [InitializeOnLoad]
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class RadioMenuAttribute : Attribute
    {
        private static Dictionary<string, HashSet<RadioMenuAttribute>> m_menus = new Dictionary<string, HashSet<RadioMenuAttribute>>();

        public string Path { get; private set; }
        public bool Enabled { get; set; }

        private RadioMenuAttribute()
        {
        }

        public RadioMenuAttribute(string name, string path)
        {
            Path = path;

            m_menus.AddOnce(name, new HashSet<RadioMenuAttribute>());
            m_menus[name].Add(this);
        }

        static RadioMenuAttribute()
        {
            // Find here all methods with 'RadioMenuAttribute'

            // Test 1 (Debug Length)
            //var attrs = typeof(UnityEditor.Editor).Assembly.GetCustomAttributes<RadioMenuAttribute>();

            //foreach (var attr in attrs)
            //{
            //    attr.Enabled = EditorPrefs.GetBool(attr.Path, false);

            //    // Delaying until first editor tick so that the menu
            //    // will be populated before setting check state, and
            //    // re-apply correct action
            //}

            //EditorApplication.delayCall += () =>
            //{
            //    foreach (var attr in attrs)
            //        PerformAction(attr);
            //};

            // Test 2 (Inject this code to all methods that contains 'RadioMenuAttribute')

            /*

                 // Toggling action
                 PerformAction( !CheckmarkMenuItem.enabled_);

             */
        }

    }
}
using UnityEditor;
using UnityEngine.Core.Editor;

namespace UnitedTeamworkAssociation.UST_SDK.Utilities.SWW.Editor
{
    using Wins;

    public static class MenuItems
    {
        [MenuItem("Source Tools/Open Steam Workshop Wrapper Window...")]
        public static void StartVectorEditor()
        {
            EditorWindow.GetWindow<SteamWorkshopWrapperEditorWindow>("Steam Workshop Wrapper", false, typeof(SceneView));
        }

        #region "Settings"

        public const string BrowseSettings = "BROWSE_SETTINGS",
                    BrowseSettings_Opt1 = "Source Tools/Settings/Browse items in Editor browser...",
                    BrowseSettings_Opt2 = "Source Tools/Settings/Browse items in Default browser...";

        [RadioMenu(BrowseSettings, BrowseSettings_Opt1)]
        [MenuItem(BrowseSettings_Opt1)]
        public static void Setting_BrowseInEditor()
        {
        }

        [RadioMenu(BrowseSettings, BrowseSettings_Opt2)]
        [MenuItem(BrowseSettings_Opt2)]
        public static void Setting_BrowseInApp()
        {
        }

        #endregion "Settings"
    }
}

My main question comes here. How could I inject the following code:

RadioMenuInvoker.PerformAction(xxx);

To:

        [RadioMenu(BrowseSettings, BrowseSettings_Opt1)]
        [MenuItem(BrowseSettings_Opt1)]
        public static void Setting_BrowseInEditor()
        {
               // Logic here...
        }

To output the following:

        [MenuItem(BrowseSettings_Opt1)]
        public static void Setting_BrowseInEditor()
        {
                RadioMenuInvoker.PerformAction(xxx);
                // Where xxx is a direct reference to the attibute?
               // Logic here...
        }

What I'm trying to do is to implement a checkmark system for MenuItems (like Radio button does) (example)...

But, as you can see, I'm a newbie with IL and Mono.Cecil... So, I can't figure this out without help.

Thanks in advance!

Does not work with Mono.Cecil version 1.11.4

Works fine with Mono.Cecil 1.10.2. Trying to use with Mono.Cecil version 1.11.4 gives this error:
AssemblyResolutionException: Failed to resolve assembly: 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.DefaultAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.MetadataResolver.Resolve (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ModuleDefinition.Resolve (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ExportedType.Resolve () (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.MetadataResolver.GetType (Mono.Cecil.ModuleDefinition module, Mono.Cecil.TypeReference reference) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.MetadataResolver.Resolve (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ModuleDefinition.Resolve (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.TypeReference.Resolve () (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.Mixin.CheckedResolve (Mono.Cecil.TypeReference self) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.SignatureReader.ReadCustomAttributeEnum (Mono.Cecil.TypeReference enum_type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.SignatureReader.ReadCustomAttributeElementValue (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.SignatureReader.ReadCustomAttributeElement (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.SignatureReader.ReadCustomAttributeFixedArgument (Mono.Cecil.TypeReference type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.SignatureReader.ReadCustomAttributeConstructorArguments (Mono.Cecil.CustomAttribute attribute, Mono.Collections.Generic.Collection1[T] parameters) (at :0)
Mono.Cecil.MetadataReader.ReadCustomAttributeSignature (Mono.Cecil.CustomAttribute attribute) (at :0)
Mono.Cecil.CustomAttribute.b__35_0 (Mono.Cecil.CustomAttribute attribute, Mono.Cecil.MetadataReader reader) (at :0)
Mono.Cecil.ModuleDefinition.Read[TItem] (TItem item, System.Action2[T1,T2] read) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.CustomAttribute.Resolve () (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.CustomAttribute.get_ConstructorArguments () (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ImmediateModuleReader.ReadCustomAttributes (Mono.Cecil.ICustomAttributeProvider provider) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ImmediateModuleReader.ReadType (Mono.Cecil.TypeDefinition type) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ImmediateModuleReader.ReadTypes (Mono.Collections.Generic.Collection1[T] types) (at :0)
Mono.Cecil.ImmediateModuleReader.ReadModule (Mono.Cecil.ModuleDefinition module, System.Boolean resolve_attributes) (at :0)
Mono.Cecil.ImmediateModuleReader.b__2_0 (Mono.Cecil.ModuleDefinition module, Mono.Cecil.MetadataReader reader) (at :0)
Mono.Cecil.ModuleDefinition.Read[TItem] (TItem item, System.Action2[T1,T2] read) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ImmediateModuleReader.ReadModule () (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ModuleReader.CreateModule (Mono.Cecil.PE.Image image, Mono.Cecil.ReaderParameters parameters) (at <ee112d265aad4e098cf6cf7bf2806b0e>:0) Mono.Cecil.ModuleDefinition.ReadModule (Mono.Disposable1[T] stream, System.String fileName, Mono.Cecil.ReaderParameters parameters) (at :0)
Mono.Cecil.ModuleDefinition.ReadModule (System.IO.Stream stream, Mono.Cecil.ReaderParameters parameters) (at :0)
Weaver.WeaverSettings.WeaveAssembly (System.String assemblyPath) (at ./Library/PackageCache/com.byronmayne.weaver@37945741a9/Editor/Settings/WeaverSettings.cs:250)
Weaver.WeaverSettings.ComplicationComplete (System.String assemblyPath, UnityEditor.Compilation.CompilerMessage[] compilerMessages) (at ./Library/PackageCache/com.byronmayne.weaver@37945741a9/Editor/Settings/WeaverSettings.cs:164)
UnityEditor.Compilation.CompilationPipeline+<>c.b__26_3 (UnityEditor.Scripting.ScriptCompilation.ScriptAssembly scriptAssembly, UnityEditor.Compilation.CompilerMessage[] messages) (at :0)
UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget, Int32, String[], Boolean)
`

Behaviour is missing

Hello Byron. Do you still support Weaver? Here is the project attached in which I use Weaver to inject logging into TestScript. When first pushing "Play" everything looks fine. But the second time Unity reports "Behaviour missing" on every script in weaved assembly.
And after that every assembly rebuild produces error "Copying the file failed"

TestCecil.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.