UnityVS: Web Target with Web Security enabled will prevent opening files and communication with UnityVS.
解决方法
直接在 unity中 File-》build setting -> 更换一个平台就行,不要选择web的
just go to File->Build Settings then select something other than web player and then press Switch Platform.
======================================================================================
捕获日志
using UnityEngine;using System.Collections;public class SetupVerification : MonoBehaviour{ public string message = ""; private bool badSetup = false; void Awake () { Application.RegisterLogCallback (OnLog); } void OnLog (string message, string stacktrace, LogType type) { if (message.IndexOf ("UnityException: Input Axis") == 0 || message.IndexOf ("UnityException: Input Button") == 0 ) { //处理异常信息 } }}
===============================================================
InternalGetGameObject can only be called from the main thread.
然后socketclient对象是异步的,所以做了多线程处理,当socketclient接收到消息时,回调了主线程的函数(继承自monobehaviour),这时候就导致了报错。上面第一篇unity论坛博文解释得比较清楚,大概就是unity对于API调用主线程做了限制:
“Unity chose to limit API calls to main-thread, to make a simple and solid threading model that everyone can understand and use.”
UIScrollView的更新
void updateScroll(){ //总的高度 float allHeight = uiGrid.transform.childCount * uiGrid.cellHeight; if (allHeight > uiScrollView.gameObject.GetComponent().height) { //菜单高度 float btnHeight = buttonClickSingerClass.gameObject.GetComponent ().size.y; btnHeight = btnHeight * buttonGrid.transform.childCount; float offset = uiGrid.cellHeight * 0.66f; float curHeight = Mathf.Abs (gameObject.transform.localPosition.y) + btnHeight + offset; if (curHeight > allHeight) { uiScrollView.verticalScrollBar.value = 1.0f; } uiScrollView.UpdatePosition (); } }
旋转
using UnityEngine;public class DragRotate : MonoBehaviour{ public GameObject obj; void Start() { } void OnDrag(Vector2 v){ if (obj != null){ obj.transform.localEulerAngles -= Vector3.up * v.x; } }}
转化为00:00:00
static string timeCv(int value){ string str = ""; if (value >= 0) { if (value < 10) str = "0" + value; else str = value.ToString(); } else { str = "00"; } return str; } static string TimeFormat(int s){ int hour = s / 3600; int mm = 0; int ss = 0; if (hour > 0) { mm = (s % 3600)/60; ss = s - hour * 3600 - mm * 60; } else { mm = s / 60; ss = s - hour * 3600 - mm * 60; } return timeCv (hour) + ":" + timeCv (mm) + ":" + timeCv (ss); }
ReadPixels 需要等待一帧后才能处理.
ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame.
StartCoroutine(screenAndUpload());IEnumerator screenAndUpload(){ Texture2D tex = new Texture2D(Screen.width,Screen.height); //ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame. //这个需要你在调用这个函数之前使用yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame(); tex.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0); tex.Apply(); byte[] bytes = tex.EncodeToPNG(); Destroy(tex); WWWForm form = new WWWForm (); form.AddField ("frameCount",Time.frameCount.ToString()); form.AddBinaryData ("fileUpload", bytes, "screenShot.png", "image/png"); WWW w = new WWW ("http://127.0.0.1/cgi-bin/savelog.cgi", form); StartCoroutine (screenAndUploadCoroutine(w)); } IEnumerator screenAndUploadCoroutine(WWW w){ yield return w; if (!String.IsNullOrEmpty (w.error)){ print (w.error); }else{ print ("Finished Uploading ScreenShot!"); } }
unity3d post 二进制数据流到web 服务器
IEnumerator screenAndUpload(){ WWWForm form = new WWWForm (); form.AddField ("frameCount","("+Time.frameCount.ToString()+")"); byte[] _uploadBytes = testBytes; form.AddBinaryData ("bytes", testBytes,"");//_uploadBytes.Length.ToString() WWW w = new WWW ("http://127.0.0.1/cgi-bin/savelog.cgi", form); StartCoroutine (screenAndUploadCoroutine(w)); } byte[] testBytes{ get{ byte[] bytes = new byte[] { 65,66,97,98}; return bytes; } } IEnumerator screenAndUploadCoroutine(WWW w){ yield return w; if (!String.IsNullOrEmpty (w.error)){ //print (w.error); }else{ //print ("Finished Uploading ScreenShot!"); print(w.data); } }
--zcYvw8EWu622BRvwDuR9ZMyucYxHAapZXRlzb4Sa
Content-Type: text/plain; charset="utf-8"Content-disposition: form-data; name="frameCount"(756)
--zcYvw8EWu622BRvwDuR9ZMyucYxHAapZXRlzb4SaContent-Type: application/octet-streamContent-disposition: form-data; name="bytes"; filename=""ABab
--zcYvw8EWu622BRvwDuR9ZMyucYxHAapZXRlzb4Sa--������������UnityEngine.MonoBehaviour:print(Object)<screenAndUploadCoroutine>c__Iterator4:MoveNext() (at Assets/Script/Login.cs:81)
saveCgi.c
#include#include void main(int argc, char *argv[]){ int i, n; //fprintf( stdout, "Content-type:application/octet-stream\n\n" ); //fprintf( stdout, " post " ); if( getenv("CONTENT_LENGTH") ){ n = atoi( getenv("CONTENT_LENGTH") ); }else { n = 0; fprintf( stdout, "(NULL)" ); } for( i=0; i
print Logs message to the Unity Console (identical to Debug.Log).
在控制台输出日志,等同于Debug.Log
TweenAlpha 使用
using UnityEngine;using System.Collections;public class Init :MonoBehaviour{ public Transform cube; public GameObject alphaGo; public UIWidget button; void Awake() { //print(gameObject.name); } void Update(){ if(cube!=null) cube.transform.Rotate(new Vector3(0.1f,0.1f,0.1f)); } void Start(){ UIEventListener.Get(button.gameObject).onClick = onClickHandle; } void onClickHandle(GameObject go){ if(alphaGo!=null){ alphaGo.GetComponent().alpha = 0.0f; StopCoroutine("delScript"); TweenAlpha.Begin(alphaGo,5.0f,1.0f); StartCoroutine("delScript",alphaGo); } } IEnumerator delScript(GameObject go){ yield return new WaitForSeconds(5.0f); TweenAlpha ta = go.GetComponent (); if(ta!=null) Destroy(ta); }}
TweenPosition使用
using UnityEngine;public class TweenPostionExample :MonoBehaviour{ public UIWidget btn; public GameObject tweenObj; void Start(){ tweenObj.transform.localPosition = Vector3.zero; UIEventListener.Get(btn.gameObject).onClick = onClickHandle; } void onClickHandle(GameObject go){ Debug.Log(go.name); ResetExecute(); EventDelegate eventDelegate = new EventDelegate(this,"onTpFinish"); TweenPosition tp = TweenPosition.Begin(tweenObj,0.2f,new Vector3(200,-100,0)); tp.onFinished.Clear(); tp.onFinished.Add(eventDelegate); } void onTpFinish(){ Debug.Log("end.."); } [ContextMenu("ResetExecute")] public void ResetExecute (){ tweenObj.transform.localPosition = Vector3.zero; }}
如何动态的给EventDelegate添加参数
using UnityEngine;using System.Collections;public class SZEventDelegateParams : MonoBehaviour { public int param = 2; void Start(){ // 创建新的delegate,最后调用此(this)脚本的Finished函数。当然this可以换成别的脚本,这里为了方便 EventDelegate eventDelegate = new EventDelegate(this, "Finished"); // 把第一个参数设置为此(this)脚本的param变量。当然this可以换成别的脚本,这里为了方便 eventDelegate.parameters[0] = new EventDelegate.Parameter(this, "param"); UIPlayTween uipt = this.GetComponent(); uipt.onFinished.Add(eventDelegate); uipt.Play(true); } // PlayTween 结束后,会调用到这里,打印相应的值 void Finished(int p){ Debug.Log(p.ToString()); }}
随机数(防止ie缓存)
string url = "http://127.0.0.1/cgi-bin/savelog.cgi" + "?" + UnityEngine.Random.Range (0.0f, 1.0f);http://127.0.0.1/cgi-bin/savelog.cgi?0.4753303
MonoDevelop几个常用的快捷键
Tools/Options/Key bindings
CTRL+K 删除光标所在行的该行后面的代码
CTRL + ALT +C 注释/不注释该行
CTRL+ DOWN 像鼠标滚轮一样向下拖
CTRL + UP 像鼠标滚轮一样向上拖
CTRL + F 查找该脚本
CTRL + SHIFT + F 查找全部脚本
CTRL + H 替换代码
CTRL + SHIFT +W 关掉所有脚本
CTRL + G 跳转到指定的行
C#回调
public delegate void Callback();
加载texture
using UnityEngine;using System;using System.Collections;using System.Collections.Generic;public class AssetBunder :MonoBehaviour{ void Start () { WWW www = new WWW("http://192.168.1.10/AssetBundle/PC/role_1001hs.unity3d"); StartCoroutine (downLoad(www)); } IEnumerator downLoad (WWW w) { yield return w; UnityEngine.Object obj = w.assetBundle.mainAsset; Texture2D tex = obj as Texture2D; UITexture texture = GetComponent(); texture.mainTexture = tex; yield return new WaitForSeconds(3.0f); DestroyImmediate(texture); }}
C#List排序
class ComparerDynamicByTime:IComparer{ public int Compare(MeetDynamicItemVO x,MeetDynamicItemVO y){ if (x.time < y.time) { return 1; } return -1; } }List _dynList = new List ();_dynList.Sort (new ComparerDynamicByTime ());
UIDrag Object
/// Allows dragging of the specified target object by mouse or touch, optionally limiting it to be within the UIPanel's clipped rectangle.
使用鼠标或者是触碰来拖拽UIPanel剪切矩形区域范围内的窗口
HudText飘血特效实现
using UnityEngine;using System.Collections;public class HUDTextTest :MonoBehaviour{ public HUDText hudText; void Start () { //hudText.Add("hello",Color.red,0.0f); UIEventListener.Get (gameObject).onClick = onClickHandle; } void onClickHandle (GameObject go) { if (hudText != null) { hudText.Add (UnityEngine.Random.Range (0.0f, 1.0f).ToString (), Color.red, 0.0f); } StartCoroutine (EnableDragScrollView ()); } protected IEnumerator EnableDragScrollView () { yield return new WaitForSeconds (1.0f); GameObject obj = GameObject.Find ("GameObject"); while (obj!=null && obj.transform.childCount > 0) { DestroyImmediate (obj.transform.GetChild (0).gameObject); } } void Update () { }}
射线拾取模型
void Update() { if (rootCreat.activeSelf && creatState == false && Input.GetMouseButtonDown(0)) { if (!UICamera.Raycast(Input.mousePosition))//没有碰到NGUI { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线 RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { GameObject gameObj = hitInfo.collider.gameObject; int num = 0; if (int.TryParse(gameObj.name, out num)) { ButtonCreatChoose(gameObj.name); } } } } }
Camera.main = null的问题 设置一个Camera的tar= MainCamera
设置RenderQ,设置材质渲染队列,改变前后层关系,RenderQ越大 就越在前面,就越先看到
using UnityEngine;using System.Collections;[AddComponentMenu("Tool/Change RenderQueue")]public class ChangeRenderQueue : MonoBehaviour { public int queue = 0; void Awake() { renderer.material.renderQueue = queue; Destroy(this); }}
翻牌
using UnityEngine;using System.Collections;public class TweenFlipCARDS : MonoBehaviour{ public GameObject positive; /// 牌正面 public GameObject reverse; /// 牌背面 public float durationTime = 0.5f; /// 半圈时间 [HideInInspector] public EventDelegate.Callback endCallBack; void Start () { reset(); } [ContextMenu("Play")] public void play() { StartCoroutine(IPlay()); } IEnumerator IPlay(){ yield return new WaitForEndOfFrame(); positive.SetActive(true); reverse.SetActive(false); TweenRotation mPositiveTween = TweenRotation.Begin(positive,durationTime,Quaternion.Euler(Vector3.zero)); mPositiveTween.from = Vector3.zero; mPositiveTween.to = new Vector3 (0, 90, 0); EventDelegate.Add (mPositiveTween.onFinished, positiveEnd); mPositiveTween.Play(); } [ContextMenu("Reset")] public void reset() { positive.SetActive(true); reverse.SetActive(false); positive.transform.localRotation = Quaternion.Euler(Vector3.zero); reverse.transform.localRotation = Quaternion.Euler(new Vector3(0,90,0)); } void positiveEnd () { positive.SetActive(false); reverse.SetActive(true); TweenRotation mReverseTween = TweenRotation.Begin(reverse,durationTime,Quaternion.Euler(Vector3.zero)); mReverseTween.enabled = true; mReverseTween.from = new Vector3 (0, -90, 0); mReverseTween.to = Vector3.zero; EventDelegate.Add (mReverseTween.onFinished, reverseEnd); mReverseTween.Play(); } void reverseEnd() {// Debug.Log("ReverseEnd..."); if(endCallBack != null) endCallBack(); }}
抖屏
iTween.ShakePosition(GameObject.Find("Camera").gameObject,new Vector3(0.1f,0.1f,0.1f),1.0f);
using UnityEngine;using System.Collections;using System.Collections.Generic;public class Card : MonoBehaviour{ public static Card instance; const float useTime = 0.5f; void Start() { } Listlist = new List (); void Awake() { instance =this; GameObject child = gameObject.transform.GetChild(0).gameObject; for(int i = 0;i < child.transform.childCount;i++) { list.Add(child.transform.GetChild(i).gameObject); }// Debug.Log(list.Count); } public void onHover(GameObject go) { int index = int.Parse(go.name.Substring(go.name.Length - 1,1)); GameObject cur = list[index]; TweenRotation tr = TweenRotation.Begin(go,useTime,Quaternion.Euler(Vector3.zero)); tr.Play(); for(int i = 0;i < list.Count;i++){ if(i < index) { rotateTarget(list[i],true); } else if(i > index) { rotateTarget(list[i],false); } } } void rotateTarget(GameObject go,bool isReverse) {// Debug.Log("rotate:" + go.name); TweenRotation tr = TweenRotation.Begin(go,useTime,Quaternion.Euler(new Vector3())); tr.to = new Vector3(0,(isReverse == true ? 45 : 135),0); tr.Play(); }}/*using UnityEngine;using System.Collections;using System.Collections.Generic;public class CardItem :MonoBehaviour{ public CardItem () { } void Start () { UIEventListener.Get (gameObject).onClick = onClickHandle; UIEventListener.Get (gameObject).onHover = onHoverHandle; } void onClickHandle (GameObject go) { } void onHoverHandle (GameObject go, bool state) { if (state) { TweenRotation.Begin (go, 0.5f, Quaternion.Euler (new Vector3 (0, 45, 0))); Card.instance.onHover(go); }// Debug.Log (go.name + "," + state.ToString ()); }}*/
==========================================
Resources:此文件夹内的文件可以使用Rescources.Load加载,thus all assets in the "Resources" folders will be included in a build.所有在Resources文件下的资源将被编译在一起,在android编译的时候 会压缩成一个zip文件.如果资源不需要了使用 Resources.UnloadUnusedAssets.释放内存
==========================================
Building Setting 中添加关卡:
Application.LoadLevel(sn);(同步加载会删除掉当前场景),异步测试会附加关卡数据
==========================================
unity3d中类static常驻,即使是loadLevel切换关卡的时候.这样脚本即使卸载了,那么static存储的数据还在.
using UnityEngine;using System.Collections;public class Test :MonoBehaviour{ public static int count = 0; [HideInInspector] public int tempCount = 0; public GameObject btn; void Start() { count++; tempCount++; Debug.Log("count: "+count + " tempCount: " + tempCount);//count会自增变化,tempCount不会自增变化 if(btn!=null) { UIEventListener.Get(btn).onClick = onClickHandle; } } void onClickHandle(GameObject obj) { StartCoroutine(SceneFadeOut()); } IEnumerator SceneFadeOut() { yield return new WaitForEndOfFrame(); if(Application.loadedLevelName == "Test") { Application.LoadLevel("load"); } else { Application.LoadLevel("Test"); } }}
关于unity3d中单例的问题,基类中绑定到一个全局GameObject上
using UnityEngine;using System.Collections;using System.Collections.Generic;public class ManagerBase: EventDispatcher where T : MonoBehaviour { private static T _instance; public static T instance { get { if(_instance == null && GameControl.instance != null) { _instance = GameControl.instance.gameObject.AddComponent (); GameControl.managerList.Add(_instance as ManagerInterface); } return _instance; } } void OnDestroy() { _instance = null; }}
OnDestroy()的使用
在对象销毁灭的时候调用,销魂场景里的数据.
void OnDestroy() { MeetManager.instance.RemoveEvent(MeetManager.EVENT_CREATE_MEET); }
UITable:表格布局管理器
播放一个fbx动画
using UnityEngine;public class Test : MonoBehaviour{ [ContextMenu("Play")] public void Play() { Animator anim = gameObject.GetComponent(); if (anim!=null) { anim.Play("attack"); } else { Debug.Log("there is no anim!"); } }}
war3 下拉菜单动画
/* war3下拉菜单动画 */ IEnumerator StartPlay() { GameObject go = BottomWindow.gameObject; go.transform.localPosition = new Vector3(21, 134f, 0.0f); TweenPosition tp = TweenPosition.Begin(go, 0.5f, new Vector3()); tp.from = new Vector3(21, 134f, 0.0f); tp.to = new Vector3(21, -235f, 0.0f); tp.Play(); yield return new WaitForSeconds(0.5f); tp = TweenPosition.Begin(go, 0.3f, new Vector3()); tp.from = new Vector3(21, -235f, 0.0f); tp.to = new Vector3(21, -175f, 0.0f); tp.Play(); yield return new WaitForSeconds(0.3f); tp = TweenPosition.Begin(go, 0.3f, new Vector3()); tp.from = new Vector3(21, -175f, 0.0f); tp.to = new Vector3(21, -202f, 0.0f); tp.Play(); yield return new WaitForSeconds(0.3f); PlayEnd(); }
/* * 传入毫秒,返回误差值 * 返回值 > 0 则服务器时间比本地时间快 * 返回值 < 0 则服务器时间比本地时间慢 */ static void TimeSub(long ms) { DateTime d = new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(ms).ToLocalTime(); DateTime nowdatetime = DateTime.Now; DateTime enddatetime = Convert.ToDateTime(d); TimeSpan nowtimespan = new TimeSpan(nowdatetime.Ticks); TimeSpan endtimespan = new TimeSpan(enddatetime.Ticks); TimeSpan timespan = nowtimespan.Subtract(endtimespan).Duration(); //TimeCountLbl.Text = "距离" + textBox1.Text + "还有" + timespan.TotalSeconds.ToString() + "秒"; Console.WriteLine(">>"+timespan.TotalSeconds + " s"); }
================================================
cmd命里行编译输出web
/**/Applications/Unity/Unity.app/Contents/MacOS/Unity \ -batchmode \ -quit \ -projectPath $PROJECT_PATH \ -executeMethod CommandBuild.BuildAndroid*/// Assets/Editor/CommandBuile.csusing UnityEngine;using UnityEditor;public class BuildWeb{ public static void build() { string[] levels = { "Assets/Scence/Test.unity"}; BuildPipeline.BuildPlayer(levels, "SampleWeb", BuildTarget.WebPlayer, BuildOptions.None); }}//批处理//文件生成在项目根目录下//"C:\Program Files (x86)\Unity\Editor\Unity.exe" -quit -batchmode -executeMethod BuildWeb.build//pause
Cmd 输出Android
/**/Applications/Unity/Unity.app/Contents/MacOS/Unity \ -batchmode \ -quit \ -projectPath $PROJECT_PATH \ -executeMethod CommandBuild.BuildAndroid*/// Assets/Editor/CommandBuile.csusing UnityEngine;using UnityEditor;public class CommandBuild{ public static void BuildAndroid() { string[] levels = { "Assets/Scence/S0.unity"}; BuildPipeline.BuildPlayer(levels, "Sample.apk", BuildTarget.Android, BuildOptions.None); }}//批处理//"C:\Program Files (x86)\Unity\Editor\Unity.exe" -quit -batchmode -executeMethod CommandBuild.BuildAndroid//文件生成在项目根目录下
CMD输出时间格式
@echo offcall:systime"C:\Program Files (x86)\Unity\Editor\Unity.exe" -quit -batchmode -executeMethod BuildWeb.buildcall:systimeecho.&goto:eof ::--------------------------------------------------------::-- 函数部分开始::---------------------------------------:systime ::获取日期 将格式设置为:20110820 set datevar=%date:~0,4%.%date:~5,2%.%date:~8,2% ::获取时间中的小时 将格式设置为:24小时制 set timevar=%time:~0,2% if /i %timevar% LSS 10 ( set timevar=0%time:~1,1% ) ::获取时间中的分、秒 将格式设置为:3220 ,表示 32分20秒 set timevar=%timevar%:%time:~3,2%:%time:~6,2% @echo %datevar%-%timevar%goto:eof::测试函数:printf echo .this is CMD function!goto:eof
添加一个unity3D运行的环境变量:
我的电脑/属性/高级/环境变量-->系统变量-->编辑系统变量 Path (D:\software\unity3D\Editor)
bat 中的(Unity.exe -quit -batchmode -executeMethod BuildWindowExe.build)