1.生成问题(泛型脚本导致的)
接刚刚的Hololens开发(10),因为给每个返回消息都写Update脚本麻烦,打算写一个通用的脚本。
写好了,重新打包。打包好后,生成hololens发布,突然不能生成了。
Severity Code Description Project File Line Suppression State
Error The command ""D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\Unity\Tools\AssemblyConverter.exe" -platform=uap -lock="D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\project.lock.json" -bits=32 -configuration=Release -removeDebuggableAttribute=False -uwpsdk=10.0.10586.0 -path="." -path="C:\Program Files\Unity5.6\Editor\Data\PlaybackEngines\MetroSupport\Players\UAP\dotnet\x86\Release" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\Assembly-CSharp.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\Assembly-CSharp-firstpass.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\Assembly-UnityScript.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\UnityEngine.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\nunit.framework.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\UnityEngine.UI.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\UnityEngine.HoloLens.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\UnityEngine.Networking.dll" "D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\UnityEngine.VR.dll"" exited with code 1. NoToolkit D:\SoftwareProjects\Hololens\UnityProjects\NoToolkit\NoToolkit\bin\NoToolkit\NoToolkit.csproj 358
这个提示和在以前刚刚开始时,用VS2017打开的问题一样。但是,其他项目都好好的,
刚刚(虽然中间去开了个很久的会)也是能正常打包的。
原因是出在我刚刚写的脚本上?
将相关脚本注释掉,也不行。
和其他项目比较一下,多了个Assembly-UnityScript.dll相关的东西。
查了一下Assembly-UnityScript.dll是UnityScript(脚本语言)的相关dll,把他删除看看。
先把启动项目中的dll删除了, 引用删了,然后把项目文件中的AssemblyConverter.exe那里的也删了
生成,出了个问题
把obj文件夹删除,也没用,生成还是有。
在Unity项目中把“可疑的”文件删除,多了个Editor文件夹,似乎是点击Test Runner时产生的,把WSATestCertificate也删除,把JavaScript脚本文件删除。重新生成一个新的位置。
可以生成了。
但是,后来再加上这些可以的文件,还是可以的。
奇怪了。
结论是,是某个文件导致的,但是哪个?什么原因不知道。总之下次再碰到,再找一找。
===============================================
后来发现是泛型脚本不行
using System;
using UnityEngine;
public class TaskManager : MonoBehaviour {
public static TaskManager Instance;
void Awake()
{
Instance = this;
}
public void Add<T>(Action<T> action, T arg)
{
TaskScript<T> task = gameObject.AddComponent<TaskScript<T>>();
task.Action = action;
task.Arg = arg;
}
}
public class TaskScript<T> : MonoBehaviour
{
public Action<T> Action;
public T Arg;
void Start()
{
if (Action != null)
{
Action.Invoke(Arg);
}
}
}
这里的TaskScript<T>不能用,仅仅是定义不会有影响,
TaskScript<T> task = gameObject.AddComponent<TaskScript<T>>();
这句话加上就会有问题,不能生成。
语法上没问题,生成时就报错了。
关键是错误里面根本就没说清楚。
AssemblyConverter.exe .....什么的
另外这说明AssemblyConverter.exe的问题,是Unity自身运行脚本时会出的任何问题导致的。
在Unity中测试了一下泛型脚本
using UnityEngine;
public class GenericScript<T> : MonoBehaviour {
public T Data;
// Use this for initialization
void Start () {
Debug.Log("GenericScript:" + typeof(T));
}
}
using UnityEngine;
public class GenericScriptUse : MonoBehaviour {
// Use this for initialization
void Start () {
GenericScript<int> script = gameObject.AddComponent<GenericScript<int>>();
script.Data = 10;
}
}
结果是:
那不用泛型就好了,说白了把需要用到的类型具体指定就好了。
using System;
using UnityEngine;
public class TaskManager : MonoBehaviour {
public static TaskManager Instance;
void Awake()
{
Instance = this;
}
public void AddActionString(Action<string> action, string arg)
{
TaskScriptString task = gameObject.AddComponent<TaskScriptString>();
task.Action = action;
task.Arg = arg;
}
public void AddActionInt(Action<int> action, int arg)
{
TaskScriptInt task = gameObject.AddComponent<TaskScriptInt>();
task.Action = action;
task.Arg = arg;
}
}
public class TaskScriptString : MonoBehaviour
{
public Action<string> Action;
public string Arg;
void Start()
{
if (Action != null)
{
Action.Invoke(Arg);
}
}
}
public class TaskScriptInt : MonoBehaviour
{
public Action<int> Action;
public int Arg;
void Start()
{
if (Action != null)
{
Action.Invoke(Arg);
}
}
}
public void ReceiveString(int count, Action<string> callback)
{
if (Client != null)
{
Client.ReceiveString(count, msg=> {
TaskManager.Instance.AddActionString(callback, msg);
});
}
else
{
Debug.Log("WCFClientFactory.RecevieString");
if (callback != null)
{
callback("");
}
}
}
但是!实际上这样虽然能生成,
运行时也是不行的,因为回调函数函数中用了gameObject
结果是抛出异常:
UnityEngine.UnityException: get_gameObject can only be called from the main thread.
改成
using System;
using System.Collections.Generic;
using UnityEngine;
public class TaskManager : MonoBehaviour {
public static TaskManager Instance;
public List<Action> Tasks=new List<Action>();
public bool IsDirty;
void Awake()
{
Instance = this;
}
void Update()
{
if (IsDirty)
{
foreach (Action action in Tasks)
{
if (action != null)
{
action.Invoke();
}
}
Tasks.Clear();
IsDirty = false;
}
}
public void AddTask<T>(Action<T> action, T arg)
{
IsDirty = true;
Tasks.Add(() =>
{
if (action != null)
{
action(arg);
}
});
}
}
这里的Tasks是无法直接添加action的,要通过一个匿名函数再封装一下。
调用的地方:
public void ReceiveString(int count, Action<string> callback)
{
if (Client != null)
{
//Client.ReceiveString(count, callback);
Client.ReceiveString(count, msg =>
{
TaskManager.Instance.AddTask(callback, msg);
});
}
else
{
Debug.Log("WCFClientFactory.RecevieString");
if (callback != null)
{
callback("");
}
}
}
这样以后在Client中处理回调函数用TaskManager调用一下就好了,不用每种回调处理都写一个脚本在Update中调用了。
然后打包测试,Hololens中启动,界面闪一下,就退出了。
App.cs的代码运行没问题,就是无法进入Unity。
怎么修改脚本都没用。
Unity重新生成一下Hololens项目,可以了。