最近看到項目中插件的一部分邏輯,發現問題多多,可讀性很差,並且容易出錯,於是隨手整理了下邏
輯。
Unity3D的插件邏輯,因爲要考慮到針對各平臺的移植,因此會大片的出現#if/#endif等條件編譯,當
然,爲了簡化邏輯,我們可以使用Conditional屬性,但當需要處理的邏輯規模(函數個數規模、函數邏
輯規模、針對的平臺規模等等)達到一定程度時,仍然會顯得繁瑣,這時候可能就需要尋找新的處理方法
:
可以使用partial分部類/方法的方式解決問題。我們先來看一下修改前的邏輯:
//Sample.cs
public class Sample
{
#if UNITY_ANDROID
private AndroidJavaClass _agent = null;
private AndroidJavaObject _content = null;
public AndroidJavaClass Agent
{
get { return _agent; }
}
public AndroidJavaObject Content
{
get { return _content; }
}
#elif UNITY_IPHONE
#endif
#region singleton...
private Sample()
{
#if UNITY_EDITOR
Debug.Log("Editor: Sample--------------------");
#elif UNITY_ANDROID
try
{
_agent = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
_content = _agent.GetStatic<AndroidJavaObject>("currentActivity");
}
catch (System.Exception ex)
{
Debug.LogError(ex != null ? ex.Message : "<null>");
}
#elif UNITY_IPHONE
#endif
}
#endregion
public void Func1(string _param1, string _param2)
{
#if UNITY_ANDROID
if (Content != null)
{
Content.Call(......);
}
#elif UNITY_IPHONE
......
#endif
}
public void Func2()
{
#if UNITY_ANDROID
if (Content != null)
{
Content.Call("Func2");
}
#elif UNITY_IPHONE
#endif
}
public string Func3()
{
#if UNITY_ANDROID
if (Content != null)
return Content.Call<string>("Func3");
else
{
return "12345678";
}
#elif UNITY_IOS
return "23456789";
#endif
return "34567890";
}
public int Func4()
{
#if UNITY_ANDROID
if (Content != null)
{
return Content.Call<int>("Func4");
} //此處隱藏無返回的情況
#elif UNITY_IPHONE
return 100;
#endif
return 100; //編譯時的警告:執行不到的情況等等
}
......
......
}
對比修改之後的內容:
//Sample.cs
public partial class Sample
{
partial void init(); //針對構造函數
partial void func1(string _param1, string _param2);
partial void func2();
partial void func3(ref string _param1);
partial void func4(ref int _param1);
}
public partial class Sample
{
#region singleton...
private Sample()
{
init();
}
#endregion
public void Func1(string _param1, string _param2)
{
func1(_param1, _param2);
}
public void Func2()
{
func2();
}
public string Func3()
{
string tResult = "";
func3(ref tResult);
return tResult;
}
public int Func4()
{
int tResult = "";
func4(ref tResult);
return tResult;
}
}
以下針對平臺可以分別放在不同文件:
//Sample4Android.cs
#if !UNITY_EDITOR && UNITY_ANDROID
public partial class Sample
{
private AndroidJavaClass _agent = null;
private AndroidJavaObject _content = null;
public AndroidJavaClass Agent
{
get { return _agent; }
}
public AndroidJavaObject Content
{
get { return _content; }
}
partial void init()
{
try
{
_agent = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
_content = _agent.GetStatic<AndroidJavaObject>("currentActivity");
}
catch (System.Exception ex)
{
Debug.LogError(ex != null ? ex.Message : "<null>");
}
}
partial void func1(string _param1, string _param2)
{
if (Content != null)
{
Content.Call(......);
}
}
partial void func2()
{
if (Content != null)
{
Content.Call("Func2");
}
}
partial void func3(ref string _param1)
{
_param1 = Content != null ? Content.Call<string>("Func3") : "12345678";
}
partial void func4(ref int _param1)
{
_param1 = Content != null ? Content.Call<int>("Func4") : 100;
}
}
#endif
//Sample4Editor.cs
#if UNITY_EDITOR
public partial class Sample
{
}
#endif
//Sample4IPhone.cs
#if !UNITY_EDITOR && (UNITY_IPHONE || UNITY_IOS)
public partial class Sample
{
}
#endif
我們可以看到,修改之後可讀性大大提高,而且出錯的概率也會下降很多,同時對於多平臺的同時開發移植都很友好。