【Unity】テクニック集合2
21990 ワード
転送、アドレスを保持してください:http://blog.csdn.net/stalendp/article/details/46707079
関連記事:【Unity】テクニック集合
1.デバッグ関連
2.uGuiのレベルの問題.(CanvasのDraw Order of Elements参照)
UGUIの要素のレンダリング順序はHierarchyの順序と一致し、上から下へレンダリングされます(前のものを上書きします).スクリプトではtransformのSetAsFirstSibling,SetAsLastSibling,and SetSiblingIndex.関数で順序を設定できます.たとえば、次の世代コードでは、現在選択されているオブジェクトを上に置きます.
3.カメラ移動コード
4.協同的な使い方(IEnumerator)
Coroutinesについては、1)Coroutines–More than you want to know:http://twistedoakstudios.com/blog/Post83_coroutines-more-than-you-want-to-know 2)Unity coroutine (Coroutine) principle deeply again:http://www.programering.com/a/MTOzgjNwATI.html 3)Wrapping Unity C# Coroutines for Exception Handling, Value Retrieval, and Locking:http://www.zingweb.com/blog/2013/02/05/unity-coroutine-wrapperCoroutineの実装リファレンス:https://github.com/rozgo/Unity.Coroutine/blob/master/Coroutine.cs
5.コールバック関連:UnityEventとSystem.ActionとSystem.Func、そしてC#でサポートされているevent;いずれもdelegateで、関数ポインタに相当します.前者には戻り値がなく、後者には戻り値があります.その中でUnityEventとSystem.Actionは基本的に同じですが、UnityEventはシーケンス化できます.最も顕著な利点は、Inspectorで編集できることです(例えば、新しいUIコントロールScrollRectのOnValueChangedプロパティなど).両者の違いは、ここでの議論を参照してください.
5a) System.Funcの使い方:
以下のように簡単に書くこともできます.
5 c)C#システムのeventの使い方:Events Tutorial
6.Raycastでtrigger Collidersを無視する方法:
Edit > Project Settings > Physics > Uncheck "Raycasts Hit Triggers"
7.パーティクルシステムの動作:
8.C#の特殊なオペレータ:https://msdn.microsoft.com/en-us/library/6a71f45d.aspx
ここでNullableType,参考:https://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
8-1)Boxing nullable types: int? float? double? 基本タイプをobjectタイプに変更する.その値はnullであってもよいし、関連する変換操作であってもよい.
8-2) Null-conditional Operators: ?. ?[]オブジェクトにアクセスする前にnullを判断すると、コードを簡略化できます.C#6の新しい特性は、Unityでは使えないようです
8-3) Null-coalescing Operator: x ?? y
9.Unityにおける「一例」の一般的な実現方案:
10.変数を初期化する簡単な方法
11.Unityにおける新しいUIのメッセージ処理方式(EventSystemにおけるRaycastにより現在のUIを取得し、メッセージを送信する)
詳細については、次の文書を参照してください.http://gregandaduck.blogspot.com/2015/02/using-unitys-c-message-system-unity-46.html
メッセージ受信者は、次のように実装されます.
メッセージ送信者は、以下のように実装される.
12.C#でJavaの匿名クラスの書き方をシミュレートする(Javascriptの味がする):
13.仕事中に常にある単位の初期化に遭遇した場合、他の単位に依存してまだ初期化されていないため、Null ReferenceExceptionが発生します.これはすべての初期化がStartメソッドに書かれているため,コード初期化の前後順序により上記の問題が発生する.解決策は初期化を段階的に行うことである.NullReferenceExceptionを引き起こすことができるのは、GetCompent、Findなどの操作で、AwakeやOnEnableメソッドなどに書かれています.論理初期化はStartの中程度に書きます.以下はScript Lifecycleの概略図です.公式ドキュメントは次のとおりです.http://docs.unity3d.com/Manual/ExecutionOrder.html
14.文字の書式設定
How to format a number 1234567 into 1,234,567 in C#?
より多くの文字列をフォーマットする操作:
a) https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx
b) http://www.dotnetperls.com/string-format
15.RenderTextureをファイルとして保存する(参考:http://answers.unity3d.com/questions/27968/getpixels-of-rendertexture.html)
16.2つのベクトルを乗算:
17.C#でのDictionaryの初期化:
18.MonoBehaviourサブクラスで親クラスのOnEnableメソッドを非表示にします.原則として、文法的な面ではサブクラスHideの親のメソッドを制限することはできませんが、そうすれば、コンパイラは108番の異常を提示します.私の解決策は、この異常をエラーに変換することです.これはコンパイラパラメータを設定する必要があります.Unityにおけるコンパイラパラメータの設定方法は、Assetsルートディレクトリの下にsmcsを追加することである.rspファイル:http://docs.unity3d.com/Manual/PlatformDependentCompilation.html
a)Assetsルートノードの下にsmcsを作成する.rspファイル、/warnaserror+:108
コンパイラパラメータの詳細については、以下を参照してください.https://msdn.microsoft.com/en-us/library/406xhdz3.aspx
b)親クラスで上書きする関数を記述し、アクセス権はprotectedである.例えば:
c)サブクラスにOnEnableメソッドがある場合,コンパイラはエラーを報告する.
19.Unity 3 dでデバイスを間違えた方法、参考:Any tips for debuging Android?19-1)androidのLogcatメソッド、コマンドライン:adb logcat-s Unity、もちろんログが多い場合は出力をファイルにインポートできます.19-2)MonoDeveloperのRemote Debugを使用:Attaching MonoDevelop Debugger To an Android device 19-3)いくつかのプラグインを使用
20.マスタースレッドでコードを実行する方法.Unityコードでネットワーク層を自分でカプセル化し、データが戻ってきたらコールバックで通知すると、「StartCoroutine_Auto can only be called from the main thread.」などのエラーは、ネットワークが別のスレッドで実行されているためです.次の記事では、Main thread coroutine using Queueの簡単なコードについて説明します.
21.UnityのAssertにバグがあるようです.次のコードがあります.
このうちstyle 1は、PCでは問題なく、携帯電話ではいつもunitが空になっています(携帯電話のメモリが緊張しているはずで、すぐにゴミ回収されていると思います);style 2の両方がOKです.
22.Windowsでprotobufを使用している場合、protobufのバイナリファイルをTortoiseSVNで更新した場合、svnで変更される可能性があります.主にsvnツールでは、バイナリ・ファイルがテキスト・モードであると判断してeolモード(end-of-line)をオンにした場合、改行文字が変更されることがあります.ソリューションは師eol-styleがfalseで、バイナリ・フォーマットに設定されています.tortoiseSVNでは、変更するファイルを右クリックしてpropertiesメニューを選択し、ポップアップ・ダイアログ・ボックスで次のように変更します.
23.不規則ボタンのカスタマイズ(関連11条参照)
一般的なゲームでは地図の中のある領域をクリック領域に変え、これらの領域は一般的に不規則である(下図参照).UnityではPhysic 2 DとPolygonCollider 2 Dを組み合わせて要求を達成することができ、Physics 2 Dをメッセージソースとし、PolygonCollider 2 Dが存在するオブジェクトをメッセージ受信者とする.関連コードは以下の通りである.
メッセージソース:
次の操作を行います.
24.C#正規表現の例:
25.エディタでAnimatorControllerのすべてのStateを取得します.
26.Unityで特定のジオメトリを描画する
27.カスタムuGUIコントロール(具体例は、『【Unity】新しいUIシステムテクニック』の第2点を参照)
注意:Unity 5.3以降、上記の関数を「void OnPopulateMesh(VertexHelper vh)」で置き換えることをお勧めします(パラメータの変化に注意し、Meshの操作をVertexHelperにカプセル化しました)
28.iosパッケージの注意点:
unity 4を使っています.6発iosパッケージの時、導出したxcode工程の間違いを発見した.実はxcodeがあまりにも新しいため、7.2で、unityはまだ7.1しかサポートしていませんが、両者の互換性が悪く、多くのerrorの出現を招きました.だから、iosパッケージを出すときはxcodeのバージョンとunityが合っているかどうかに注意してください.そうしないと、上に時間がかかりすぎます.覚えておいてください.
関連記事:【Unity】テクニック集合
関連記事:【Unity】テクニック集合
1.デバッグ関連
Debug.DrawRay(transform.position, newDir, Color.red);
2.uGuiのレベルの問題.(CanvasのDraw Order of Elements参照)
UGUIの要素のレンダリング順序はHierarchyの順序と一致し、上から下へレンダリングされます(前のものを上書きします).スクリプトではtransformのSetAsFirstSibling,SetAsLastSibling,and SetSiblingIndex.関数で順序を設定できます.たとえば、次の世代コードでは、現在選択されているオブジェクトを上に置きます.
curSelected.transform.SetAsLastSibling();
3.カメラ移動コード
public class DragMap : MonoBehaviour {
public Vector3 speed = Vector3.zero;
public bool isFlying = false;
public float threshold = 0.2f;
Camera mainCam;
Vector3 startPos;
int groundLayer;
Vector3[] speedCache ;
int idx = 0;
bool isDragging = false;
// Use this for initialization
void Start () {
groundLayer = 1 << LayerMask.NameToLayer ("ground");
mainCam = Camera.main;
speedCache = new Vector3[5];
isFlying = false;
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown (0)) {
RaycastHit hit;
if (Physics.Raycast (mainCam.ScreenPointToRay (Input.mousePosition), out hit, Mathf.Infinity, groundLayer)) {
startPos = hit.point;
speed = Vector3.zero;
idx = 0;
for(int i=0; i<speedCache.Length; i++) {
speedCache[i] = Vector3.zero;
}
isDragging = true;
}
} else if(Input.GetMouseButtonUp(0)) {
speed = Vector3.zero;
foreach(Vector3 s in speedCache) {
speed += s;
}
speed /= 5;
isFlying = speed.magnitude > threshold;
isDragging = false;
}
if (isDragging) {
RaycastHit hit;
if (Physics.Raycast (mainCam.ScreenPointToRay (Input.mousePosition), out hit, Mathf.Infinity, groundLayer)) {
Vector3 offset = hit.point - startPos;
mainCam.transform.position -= offset;
speedCache [idx++ % 5] = offset;
}
} else if (isFlying) {
speed *= 0.9f;
isFlying = speed.magnitude > threshold;
mainCam.transform.position -= speed;
}
}
}
4.協同的な使い方(IEnumerator)
IEnumerator Start() {
Debug.Log ("zero: " + Time.time);
yield return StartCoroutine (mywait (3f));
Debug.Log ("one: " + Time.time);
yield return StartCoroutine (mywait (2f));
Debug.Log ("two: " + Time.time);
}
Coroutinesについては、1)Coroutines–More than you want to know:http://twistedoakstudios.com/blog/Post83_coroutines-more-than-you-want-to-know 2)Unity coroutine (Coroutine) principle deeply again:http://www.programering.com/a/MTOzgjNwATI.html 3)Wrapping Unity C# Coroutines for Exception Handling, Value Retrieval, and Locking:http://www.zingweb.com/blog/2013/02/05/unity-coroutine-wrapperCoroutineの実装リファレンス:https://github.com/rozgo/Unity.Coroutine/blob/master/Coroutine.cs
5.コールバック関連:UnityEventとSystem.ActionとSystem.Func、そしてC#でサポートされているevent;いずれもdelegateで、関数ポインタに相当します.前者には戻り値がなく、後者には戻り値があります.その中でUnityEventとSystem.Actionは基本的に同じですが、UnityEventはシーケンス化できます.最も顕著な利点は、Inspectorで編集できることです(例えば、新しいUIコントロールScrollRectのOnValueChangedプロパティなど).両者の違いは、ここでの議論を参照してください.
5a) System.Funcの使い方:
public struct AstarWorkItem {
//....
public System.Func<bool, bool> update;
//....
public AstarWorkItem (System.Func<bool, bool> update) {
this.update = update;
}
}
//...
AddWorkItem (new AstarWorkItem (delegate (bool force) {
InternalOnPostScan ();
return true;
}));
以下のように簡単に書くこともできます.
public struct AstarWorkItem {
public System.Func<bool, bool> update;
}
// ...
AddWorkItem (new AstarWorkItem () {
update = (force) => {
InternalOnPostScan ();
return true;
}
});
5 b)UnityEventの使い方[Serializable]
public class ScrollRectEvent : UnityEvent<Vector2> {}
// class members
[SerializeField]
private ScrollRectEvent m_OnValueChanged = new ScrollRectEvent();
public ScrollRectEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } }
// invoke ...
onValueChanged.AddListener (offset => {
Debug.Log("ScrollRect is changed, offset is : " + offset.ToString());
});
5 c)C#システムのeventの使い方:Events Tutorial
//
public event global::System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
if(PropertyChanged != null)
PropertyChanged(this, new global::System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
//
xx.OnPropertyChanged(@"name");
//
PropertyChanged += (sender, e) => {
Debug.Log(e.PropertyName + " is changed!!");
};
6.Raycastでtrigger Collidersを無視する方法:
Edit > Project Settings > Physics > Uncheck "Raycasts Hit Triggers"
7.パーティクルシステムの動作:
// stop particalSystem
waterEffect.Stop();
// restart particalSystem
waterEffect.Simulate(0);
waterEffect.Play();
8.C#の特殊なオペレータ:https://msdn.microsoft.com/en-us/library/6a71f45d.aspx
ここでNullableType,参考:https://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
8-1)Boxing nullable types: int? float? double? 基本タイプをobjectタイプに変更する.その値はnullであってもよいし、関連する変換操作であってもよい.
//## Example 1: Nullable objects and their boxed counterpart can be tested for null:
bool? b = null;
object boxedB = b;
if (b == null) {
// True.
}
if (boxedB == null) {
// Also true.
}
//## Example 2: Boxed nullable types fully support the functionality of the underlying type:
double? d = 44.4;
object iBoxed = d;
// Access IConvertible interface implemented by double.
IConvertible ic = (IConvertible)iBoxed;
int i = ic.ToInt32(null);
string str = ic.ToString();
8-2) Null-conditional Operators: ?. ?[]オブジェクトにアクセスする前にnullを判断すると、コードを簡略化できます.C#6の新しい特性は、Unityでは使えないようです
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
int? count = customers?[0]?.Orders?.Count();
// null if customers, the first customer, or Orders is null
var handler = this.PropertyChanged;
if (handler != null)
handler(…)
=== ==》
PropertyChanged?.Invoke(e)
8-3) Null-coalescing Operator: x ?? y
class NullCoalesce
{
static int? GetNullableInt()
{
return null;
}
static string GetStringValue()
{
return null;
}
static void Main()
{
int? x = null;
// Set y to the value of x if x is NOT null; otherwise,
// if x = null, set y to -1.
int y = x ?? -1;
// Assign i to return value of the method if the method's result
// is NOT null; otherwise, if the result is null, set i to the
// default value of int.
int i = GetNullableInt() ?? default(int);
string s = GetStringValue();
// Display the value of s if s is NOT null; otherwise,
// display the string "Unspecified".
Console.WriteLine(s ?? "Unspecified");
}
}
8-4) How to: Safely Cast from bool? to bool bool? b = null;
if (b) // Error CS0266.
{
}
=== ==>>
bool? test = null;
// Other code that may or may not
// give a value to test.
if(!test.HasValue) //check for a value
{
// Assume that IsInitialized
// returns either true or false.
test = IsInitialized();
}
if((bool)test) //now this cast is safe
{
// Do something.
}
9.Unityにおける「一例」の一般的な実現方案:
public static EventSystem current { get; private set; }
...
protected void OnEnable()
{
if (EventSystem.current == null)
EventSystem.current = this;
#if UNITY_EDITOR
else
{
Debug.LogWarning("Multiple EventSystems in scene... this is not supported");
}
#endif
}
10.変数を初期化する簡単な方法
PointerEventData ped = new PointerEventData (EventSystem.current);
ped.position = Input.mousePosition;
EventSystem.current.RaycastAll (ped, hits);
=== ==>
EventSystem.current.RaycastAll (new PointerEventData (EventSystem.current) {
position = Input.mousePosition
}, hits);
11.Unityにおける新しいUIのメッセージ処理方式(EventSystemにおけるRaycastにより現在のUIを取得し、メッセージを送信する)
詳細については、次の文書を参照してください.http://gregandaduck.blogspot.com/2015/02/using-unitys-c-message-system-unity-46.html
メッセージ受信者は、次のように実装されます.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
// refer to http://gregandaduck.blogspot.com/2015/02/using-unitys-c-message-system-unity-46.html
public interface IMyMouseOver : IEventSystemHandler {
void mouseOver(string str);
void mouseLeaving();
}
public class MyDisplayText : MonoBehaviour, IMyMouseOver {
public Text text;
public void mouseOver(string str) {
if (!text.enabled) {
text.text = str;
text.enabled = true;
}
}
public void mouseLeaving() {
if (text.enabled) {
text.enabled = false;
}
}
}
メッセージ送信者は、以下のように実装される.
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
public class MyMouseOver : MonoBehaviour {
GameObject prevObject;
void Update () {
GameObject target = getMouseOver ();
if (target) {
prevObject = target;
ExecuteEvents.Execute<IMyMouseOver> (target, null, (handle, data) => {
handle.mouseOver ("Mouse Over Active, frame: " + Time.frameCount);
});
} else {
if(prevObject) {
ExecuteEvents.Execute<IMyMouseOver>(prevObject, null, (handle, data) =>{
handle.mouseLeaving();
});
prevObject = null;
}
}
}
private GameObject getMouseOver() {
List<RaycastResult> hits = new List<RaycastResult>();
EventSystem.current.RaycastAll (new PointerEventData (EventSystem.current) {
position = Input.mousePosition
}, hits);
foreach (RaycastResult rr in hits) {
GameObject go = rr.gameObject;
if(go)
return go;
}
return null;
}
}
12.C#でJavaの匿名クラスの書き方をシミュレートする(Javascriptの味がする):
public class HpBarHandler { // struct delegate
public System.Action<float> changeHp;
public System.Action hidde;
public System.Action show;
public System.Action destory;
}
public void registerHPBarEvent(HpBarHandler _hphandler) {
hphandler = _hphandler;
}
fightUnit.registerHPBarEvent (new HpBarHandler () {
changeHp = hp => {
size.x = 200 * hp;
if(rectTrans) {
rectTrans.sizeDelta = size;
if(hp<=0) {
GameObject.Destroy (gameObject);
}
}
},
hidde = delegate{
gameObject.SetActive(false);
},
show = delegate {
gameObject.SetActive(true);
},
destory = delegate {
GameObject.Destroy (gameObject);
}
});
13.仕事中に常にある単位の初期化に遭遇した場合、他の単位に依存してまだ初期化されていないため、Null ReferenceExceptionが発生します.これはすべての初期化がStartメソッドに書かれているため,コード初期化の前後順序により上記の問題が発生する.解決策は初期化を段階的に行うことである.NullReferenceExceptionを引き起こすことができるのは、GetCompent、Findなどの操作で、AwakeやOnEnableメソッドなどに書かれています.論理初期化はStartの中程度に書きます.以下はScript Lifecycleの概略図です.公式ドキュメントは次のとおりです.http://docs.unity3d.com/Manual/ExecutionOrder.html
14.文字の書式設定
//List<Vector3> uvList = ...;
Debug.Log (string.Format("frame: {0:0.00}, uvs: {1}, {2}, {3}, {4}",
0.125f,
uvList[0].ToString("0.000"),
uvList[1].ToString("0.000"),
uvList[2].ToString("0.000"),
uvList[3].ToString("0.000")
));
How to format a number 1234567 into 1,234,567 in C#?
int number = 123456;
number.ToString ("N0"); //123,456
//
number.ToString ("#,##0");
より多くの文字列をフォーマットする操作:
a) https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx
b) http://www.dotnetperls.com/string-format
15.RenderTextureをファイルとして保存する(参考:http://answers.unity3d.com/questions/27968/getpixels-of-rendertexture.html)
// RenderTexture
public void saveRT2File(RenderTexture srcRenderTex) {
RenderTexture.active = srcRenderTex;
Texture2D outputTex = new Texture2D (srcRenderTex.width, srcRenderTex.height, TextureFormat.RGB24, false);
outputTex.ReadPixels(new Rect(0, 0, srcRenderTex.width, srcRenderTex.height), 0, 0);
outputTex.Apply ();
string path = Application.persistentDataPath + "/savedTex.png";
System.IO.File.WriteAllBytes( path, outputTex.EncodeToPNG() );
RenderTexture.active = null;
}
16.2つのベクトルを乗算:
Vector result = Vector3.Scale(new Vector3(1, 2, 3), new Vector3(2, 3, 4)); // (2,6,12)
17.C#でのDictionaryの初期化:
Dictionary<string, UnityAction> dict = new Dictionary<string, UnityAction> () {
{"btnExpedition", delegate{ Debug.Log("btnExpedition");} },
{"btnFormation", delegate{ Debug.Log("btnFormation");} }
};
18.MonoBehaviourサブクラスで親クラスのOnEnableメソッドを非表示にします.原則として、文法的な面ではサブクラスHideの親のメソッドを制限することはできませんが、そうすれば、コンパイラは108番の異常を提示します.私の解決策は、この異常をエラーに変換することです.これはコンパイラパラメータを設定する必要があります.Unityにおけるコンパイラパラメータの設定方法は、Assetsルートディレクトリの下にsmcsを追加することである.rspファイル:http://docs.unity3d.com/Manual/PlatformDependentCompilation.html
a)Assetsルートノードの下にsmcsを作成する.rspファイル、/warnaserror+:108
コンパイラパラメータの詳細については、以下を参照してください.https://msdn.microsoft.com/en-us/library/406xhdz3.aspx
b)親クラスで上書きする関数を記述し、アクセス権はprotectedである.例えば:
public abstract class AMView : MonoBehaviour {
protected void OnEnable() {
this.bind ();
InitBeforeStart ();
}
protected virtual void InitBeforeStart() {}
}
c)サブクラスにOnEnableメソッドがある場合,コンパイラはエラーを報告する.
19.Unity 3 dでデバイスを間違えた方法、参考:Any tips for debuging Android?19-1)androidのLogcatメソッド、コマンドライン:adb logcat-s Unity、もちろんログが多い場合は出力をファイルにインポートできます.19-2)MonoDeveloperのRemote Debugを使用:Attaching MonoDevelop Debugger To an Android device 19-3)いくつかのプラグインを使用
20.マスタースレッドでコードを実行する方法.Unityコードでネットワーク層を自分でカプセル化し、データが戻ってきたらコールバックで通知すると、「StartCoroutine_Auto can only be called from the main thread.」などのエラーは、ネットワークが別のスレッドで実行されているためです.次の記事では、Main thread coroutine using Queue
private readonly Queue<System.Action> _ExecuteOnMainThread = new Queue<System.Action>();
protected void Update() {
lock (((ICollection)_ExecuteOnMainThread).SyncRoot) {
while (_ExecuteOnMainThread.Count > 0) {
_ExecuteOnMainThread.Dequeue().Invoke();
}
}
}
public static void ExecuteOnMainThread(System.Action action) {
if (current != null) {
lock (((ICollection)current._ExecuteOnMainThread).SyncRoot) {
current._ExecuteOnMainThread.Enqueue (action);
}
} else {
throw new System.Exception ("The System is not inited!");
}
}
public new Coroutine StartCoroutine (IEnumerator routine) {
ExecuteOnMainThread (delegate {
base.StartCoroutine (routine);
});
return null;
}
21.UnityのAssertにバグがあるようです.次のコードがあります.
Unit unit = null;
// style 1
Assert.IsTrue (unitTable.TryGetValue (id, out unit), "Cannot get value from Unit sheet with id: " + id);
return unit;
// style 2
if (unitTable.TryGetValue (id, out unit)) {
return unit;
}
throw new System.Exception (string.Format("Unit with id '{0}' is not found in cache!", id));
このうちstyle 1は、PCでは問題なく、携帯電話ではいつもunitが空になっています(携帯電話のメモリが緊張しているはずで、すぐにゴミ回収されていると思います);style 2の両方がOKです.
22.Windowsでprotobufを使用している場合、protobufのバイナリファイルをTortoiseSVNで更新した場合、svnで変更される可能性があります.主にsvnツールでは、バイナリ・ファイルがテキスト・モードであると判断してeolモード(end-of-line)をオンにした場合、改行文字が変更されることがあります.ソリューションは師eol-styleがfalseで、バイナリ・フォーマットに設定されています.tortoiseSVNでは、変更するファイルを右クリックしてpropertiesメニューを選択し、ポップアップ・ダイアログ・ボックスで次のように変更します.
23.不規則ボタンのカスタマイズ(関連11条参照)
一般的なゲームでは地図の中のある領域をクリック領域に変え、これらの領域は一般的に不規則である(下図参照).UnityではPhysic 2 DとPolygonCollider 2 Dを組み合わせて要求を達成することができ、Physics 2 Dをメッセージソースとし、PolygonCollider 2 Dが存在するオブジェクトをメッセージ受信者とする.関連コードは以下の通りである.
メッセージソース:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class AmMapRaycaster : MonoBehaviour {
private GameObject selectObj = null;
void Update () {
if (Input.GetMouseButtonDown (0)) {
selectObj = getMapButton ();
} else if (Input.GetMouseButtonUp (0)) {
if(selectObj==getMapButton() && selectObj!=null) {
ExecuteEvents.Execute<IPointerClickHandler>(selectObj, null, (handler, eventData) => {
handler.OnPointerClick(null);
});
}
selectObj = null;
}
}
private GameObject getMapButton() {
Collider2D h = Physics2D.OverlapPoint(Input.mousePosition);
if(h) {
return h.gameObject;
}
return null;
}
}
メッセージ受信者(buttonと同様):using System;
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
[RequireComponent(typeof(Collider2D))]
public class MapButton : MonoBehaviour, IPointerClickHandler {
[Serializable]
public class ButtonClickedEvent : UnityEvent {}
[SerializeField]
private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();
public ButtonClickedEvent onClick
{
get { return m_OnClick; }
set { m_OnClick = value; }
}
public void OnPointerClick (PointerEventData eventData) {
m_OnClick.Invoke();
}
}
次の操作を行います.
MapButton mapButton = GetComponent<MapButton>();
mapButton.onClick.AddListener (delegate {
Debug.Log("you click the map area!");
});
24.C#正規表現の例:
using System.Text.RegularExpressions;
string longStr = "xxx";
Regex regex = new Regex (@"(Assets/A2Game/.*?([^\./]+)\.unity)", RegexOptions.IgnoreCase);
Match m = regex.Match(longStr);
if(m.Success) {
Debug.LogFormat("group1: {0}, group2: {1}", m.Groups[1].ToString(), m.Groups[2].ToString());
}
25.エディタでAnimatorControllerのすべてのStateを取得します.
public static void addAllAnimators() {
UnityEditor.Animations.AnimatorController ac = AssetDatabase.LoadAssetAtPath<UnityEditor.Animations.AnimatorController> ("Assets/OriginalResources/character/1036/1036.controller");
List<AnimatorState> states = new List<AnimatorState> ();
getAllAnimClips (ac.layers [0].stateMachine, states);
Debug.Log (">>>" + ac.name);
foreach (var s in states) {
Debug.LogFormat("name: {0}, motion: {1}", s.name, s.motion.ToString());
}
}
private static void getAllAnimClips(AnimatorStateMachine sm, List<AnimatorState> states) {
System.Array.ForEach(sm.states, s=>states.Add(s.state));
System.Array.ForEach(sm.stateMachines, v=>getAllAnimClips(v.stateMachine, states));
}
26.Unityで特定のジオメトリを描画する
public void Update() {
draw ();
}
void draw() {
var verticies = new Vector3[6] {
new Vector3(0f, 0f, 0f), // 0
new Vector3(0f, 1f, 0f), // 1
new Vector3(1f, 0f, 0f), // 2
new Vector3(0.5f, -0.5f, 0f), // 3
new Vector3(-0.5f, -0.5f, 0f), // 4
new Vector3(-1f, 0f, 0f) // 5
};
var triangles = new int[15] { //
2, 0, 1,
3, 0, 2,
4, 0, 3,
5, 0, 4,
1, 0, 5,
};
var m = new Mesh();
m.vertices = verticies;
m.triangles = triangles;
m.RecalculateNormals();
Matrix4x4 mtx = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, Vector3.one * 1.9f);
Graphics.DrawMesh (m, mtx, mat, 2);
}
27.カスタムuGUIコントロール(具体例は、『【Unity】新しいUIシステムテクニック』の第2点を参照)
public class GuideMask : Graphic {
/// <summary>
/// Fill the vertex buffer data.
/// </summary>
protected override void OnPopulateMesh(Mesh m)
{
var r = GetPixelAdjustedRect();
var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height);
Color32 color32 = color;
using (var vh = new VertexHelper())
{
vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(0f, 0f));
vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(0f, 1f));
vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(1f, 1f));
vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(1f, 0f));
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(2, 3, 0);
vh.FillMesh(m);
}
}
}
注意:Unity 5.3以降、上記の関数を「void OnPopulateMesh(VertexHelper vh)」で置き換えることをお勧めします(パラメータの変化に注意し、Meshの操作をVertexHelperにカプセル化しました)
28.iosパッケージの注意点:
unity 4を使っています.6発iosパッケージの時、導出したxcode工程の間違いを発見した.実はxcodeがあまりにも新しいため、7.2で、unityはまだ7.1しかサポートしていませんが、両者の互換性が悪く、多くのerrorの出現を招きました.だから、iosパッケージを出すときはxcodeのバージョンとunityが合っているかどうかに注意してください.そうしないと、上に時間がかかりすぎます.覚えておいてください.
関連記事:【Unity】テクニック集合