转发,请保持地址:http://blog.csdn.net/stalendp/article/details/46707079
相关的文章:【Unity】技巧集合
1. 调试相关
Debug.DrawRay(transform.position, newDir, Color.red);
void OnDrawGizmos() {
UnityEditor.Handles.Label(transform.position, string.Format("ID: {0}, Status: {1}", Role.Data.ID, Role.RoleST.ToString()));
}
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-wrapper
Coroutine的实现参考:https://github.com/rozgo/Unity.Coroutine/blob/master/Coroutine.cs
另外关于自定义协同:
1)http://docs.unity3d.com/ScriptReference/CustomYieldInstruction.html
2)http://blogs.unity3d.com/2015/12/01/custom-coroutines/
5. 回调相关
UnityEvent和System.Action和System.Func,还有C#中支持的event; 都是delegate,相当于函数指针;前者没有返回值,后者有返回值。其中UnityEvent和System.Action基本相同,但是UnityEvent可以被序列化,最显著的优点是可以在Inspector上被编辑(比如新UI控件ScrollRect中的OnValueChanged属性),两者差异性参考这里的讨论,用法:UnityEvent和C# event的性能对比(性能是c# event更加优越):https://www.reddit.com/r/Unity3D/comments/35sa5h/unityevent_vs_delegate_event_benchmark_for_those/
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;
}
});
5b)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());
});
5c) 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
其中NullableTypes,参考: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 UnityEn