【Unity】技巧集合2

转发,请保持地址: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. 回调相关

UnityEventSystem.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
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值