如何在 Unity3D 项目中启用 c# 7 功能

Posted

技术标签:

【中文标题】如何在 Unity3D 项目中启用 c# 7 功能【英文标题】:How to enable c# 7 features on Unity3D projects 【发布时间】:2018-01-16 14:42:08 【问题描述】:

我在我的 Unity3D 项目中编写了一个新方法(使用 Visual Studio 2017),对于该方法,我需要 C# 7 或更高版本。所以我按照this guide中的说明进行操作。

现在,当我尝试打开项目的属性时,Visual Studio 会打开它,但在打开后它突然关闭。现在我什至无法打开项目的属性。

看起来是这样的:

为什么会出现第一个和第三个错误? (我在 gif 中展示的那些)

【问题讨论】:

您可以在任何文本编辑器中直接检查.csproj 及其属性并进行修复。 @maccettura:不是官方的,但由于 mono 支持它的一些功能,确实可以启用 C# 7.0 的“实验性”使用。我自己做了,它工作得很好。 C# 6 与 C# 7 在某些代码可读性特性和元组方面日夜不同。 Unity 2018.3 现在支持 Roslyn 编译器,它允许您使用最新的 C# 7 功能!见:Unity's 2018.3 beta new features 属性未打开不是错误。这是一个可以打开/关闭的设置。要启用访问 Unity 项目中的属性,请导航至:tools->options->tools for unity->general 在“杂项”标题下,有一个“访问项目属性”标志。将其设置为 true,然后重新启动 VS。 【参考方案1】:

编辑

Unity 2018.3 现在支持 Roslyn 编译器,它允许您使用最新的 C# 7 功能!

见:https://blogs.unity3d.com/2018/09/13/unity-2018-3-beta-get-early-access-now/


对于 Unity3D

我会告诉你我是如何在 Unity3D 项目中启用 C# 7.3 的(尽管它的一些功能还不能编译)。但请注意:这种方法是一种 hack!这是 Unity 中 C# 7 的早期实验性用法。

如果您按照以下说明进行操作,我相信您可以轻松找到问题,因为您的问题很难为 SO 社区提供完整的 MCVE。但我相信您实际上想要实现的是为 Unity 启用 C# 7,而不是解决项目属性窗口中的奇怪错误。

在继续之前,我建议您完全重新安装 Visual Studio 2017 和 Unity3D,以确保您没有遇到与错误安装相关的任何问题。始终直接从 Unity 网页下载 Unity,而不是使用 Viual Studio 的安装程序,这样您可以获得最新版本。

在 Unity 3D 项目中启用 C# 7(在 Unity3D v.2018.2.10f、VS 2017 v.15.8.5 上测试)

    首先新建一个新的空项目。

    转到Edit -> Project Settings -> Player,找到Other Settings 部分,然后在Configuration / Scripting Runtime Version 下选择.NET 4.x Equivalent

    我们想告诉 mcs.exe 使用 C# 7 的新“实验”功能来处理 C# 代码。为此,只需在 Assets 文件夹中创建文件 mcs.rsp。编辑它并在其中写下这一行:

    -langversion:experimental
    

    现在,在您的 Assets 文件夹中创建一个名为 Editor 的新文件夹。添加到此文件夹的任何脚本都会使 Unity 创建一个 *.Editor.csproj 项目文件,其中包含旨在修改 Unity 编辑器的脚本。

    我们需要告诉 Visual Studio,您的项目支持 C# 7.3 语言。这并不意味着 Unity 将能够编译 C# 7.3 的所有功能,但至少 Visual Studio 不会抱怨您尝试使用的功能。

    但是,如果您直接编辑 csproj 文件,Unity 会在某个时候自动覆盖它(Unity 总是自动生成项目和解决方案文件)。所以你可以做的是安装一个在项目文件自动生成时调用的钩子,这样你就可以自己打开项目文件并添加你的自定义(你的自定义不仅限于更改语言版本:你可以做更多的事情,但你必须明白你在这里做什么)。

    为此,请将以下脚本放在Editor 文件夹中:

    #if ENABLE_VSTU
    
    using SyntaxTree.VisualStudio.Unity.Bridge;
    using System;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using UnityEditor;
    using UnityEngine;
    
    [InitializeOnLoad]
    public class ProjectFilesGeneration
    
        private class Utf8StringWriter : StringWriter
        
            public override Encoding Encoding
            
                get  return Encoding.UTF8; 
            
        
    
        static ProjectFilesGeneration()
        
            ProjectFilesGenerator.ProjectFileGeneration += (string name, string content) =>
            
                // Ignore projects you do not want to edit here:
                if (name.EndsWith("Editor.csproj", StringComparison.InvariantCultureIgnoreCase)) return content;
    
                Debug.Log($"CUSTOMIZING PROJECT FILE: 'name'");
    
                // Load csproj file:
                XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
                XDocument xml = XDocument.Parse(content);
    
                // Find all PropertyGroups with Condition defining a Configuration and a Platform:
                XElement[] nodes = xml.Descendants()
                    .Where(child =>
                        child.Name.LocalName == "PropertyGroup"
                        && (child.Attributes().FirstOrDefault(attr => attr.Name.LocalName == "Condition")?.Value.Contains("'$(Configuration)|$(Platform)'") ?? false)
                    )
                    .ToArray();
    
                // Add <LangVersion>7.3</LangVersion> to these PropertyGroups:
                foreach (XElement node in nodes)
                    node.Add(new XElement(ns + "LangVersion", "7.3"));
    
                // Write to the csproj file:
                using (Utf8StringWriter str = new Utf8StringWriter())
                
                    xml.Save(str);
                    return str.ToString();
                
            ;
        
    
    
    #endif
    

如果您想完全了解您的项目文件中发生了什么变化,只需使用任何 diff 工具,比较 csproj 文件的旧版本和新版本即可。上面的 hack 基本上与您在更改语言版本时发布的链接类似,除了每次 Unity 自动生成项目文件时都会这样做。 Microsoft 还提供了大量关于 csproj 文件中定义的文档。

【讨论】:

按照您所说的,我收到此错误:Microsoft (R) Visual C# Compiler version 2.9.1.65535 (9d34608e) 版权所有 (C) Microsoft Corporation。版权所有。错误 CS1617:/langversion 的“实验性”选项无效。使用'/langversion:?'列出支持的值。 你运行的是哪个版本的 Unity? 我正在运行 Unity 2018.3.9f1 在这种情况下,您正在运行已经支持 Roslyn 编译器的 Unity 版本。如果您仔细阅读答案,您必须采取的措施是针对 Unity -UNDER- 2018.3 的版本,这不是您的情况。请确保您在 Unity 中正确设置了以下设置:编辑->项目设置->播放器->其他设置->配置,您必须在此处设置:Scripting Runtime Version = .NET 4.xScripting Backend = MonoApi Compatibility Level = .NET 4.x。附带说明一下,我的机器上也安装了 Visual Studio 2017 Community Edition,用于脚本编辑。【参考方案2】:

看起来您正在使用 Unity(您在帖子中提到了它)。我无法从你的 gif 中分辨出来,因为它大概有 4 个像素宽。

如果您确实在使用 Unity,您将无法使用 C# 7 功能。他们只允许对 C# 6 进行实验性支持(请参阅 here)。

不幸的是,如果您想在 Unity 中使用 C# 7,那么您现在很不走运

【讨论】:

感谢遮阳篷,是的,我不知道为什么 gif 看起来这么小。方法不是经常使用和需要的东西吗?没有它我怎么做游戏?他是如何在这里使用它的? unity3d.com/learn/tutorials/topics/scripting/…(转至视频末尾)【参考方案3】:

属性窗口未打开听起来像是您安装 Visual Studio 时出现的问题(对此我无法给出太多建议)

对于编码错误,您似乎正试图在另一个方法中声明一个方法(这很奇怪):

void Update() 
    ...
    public void Method1();

想象这不是你的意图。抱怨是因为您正在编译的 C# 版本不支持该版本(并且 C#7 中的本地方法在任何情况下都不能标记为 public)。它也在抱怨,因为您的方法不是抽象的(或外部的)但没有主体,这是 C# 不允许的。这是你的意思吗?

void Update() 
    if (Input.GetKeyDown(KeyCode.R)) // Note no ; here!
    
        GetComponent<Renderer>().material.color = Color.red;
    


public void Method1() 
    // Some code

您在第 15 行的 if () 语句之后还有一个错误的 ;。这将导致 GetComponent&lt;Renderer&gt; 行(第 17 行)始终运行,而不仅仅是条件是真的。再说一次,这可能不是我想象的你想要的。

【讨论】:

感谢 awnser,我只是一个初学者,所以我不知道我所有的错误或我在做什么,这对我来说很奇怪,因为我正在学习 c# unity和sololearn同时和unity做了我所做的差不多,但我并不是要在另一个方法中创建一个方法,如何将它们分开? 您需要将Update() 方法的花括号 () 的 public void Method1() 声明 移动到外部 - 类似于我在我的代码示例。 我刚刚更新了我的答案以显示您需要使用的确切代码。

以上是关于如何在 Unity3D 项目中启用 c# 7 功能的主要内容,如果未能解决你的问题,请参考以下文章

如何为整个项目启用 C# 8.0 的 Nullable Reference Types 功能

如何在 Visual Studio 2013 中启用 C# 6.0 功能?

如何在现有的 ios 测试项目中启用 xcode 7 UI 测试

Unity3D学习:C#和C++的相互调用

Unity3d C# 实现AA包(Addressables)资源热更新的多个包异步加载并显示加载实时进度功能(含源码)

unity3d中c#如何修改物体局部的颜色