unity3d questions!

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<UIPanel> ().height) {
            //菜单高度
            float btnHeight = buttonClickSingerClass.gameObject.GetComponent<BoxCollider> ().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)
--zcYvw8EWu622BRvwDuR9ZMyucYxHAapZXRlzb4Sa
Content-Type: application/octet-stream
Content-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 <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[]){    
    int i, n;
        //fprintf( stdout, "Content-type:application/octet-stream\n\n" );
       //fprintf( stdout, "<html><title>post</title>" );
        if( getenv("CONTENT_LENGTH") ){
            n = atoi( getenv("CONTENT_LENGTH") );
        }else {
            n = 0;
            fprintf( stdout, "(NULL)" );
        }
        for( i=0; i<n; i++ ){
             fputc( getc(stdin), stdout );
        }
        fprintf( stdout, "" );
        
}

 

print

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<UIWidget>().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<TweenAlpha>();
        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变量。<span style="font-family: Arial; ">当然this可以换成别的脚本,这里为了方便</span>
        eventDelegate.parameters[0] = new EventDelegate.Parameter(this, "param");
 
        UIPlayTween uipt = this.GetComponent<UIPlayTween>();
        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<UITexture>();
        texture.mainTexture = tex;
        yield return new WaitForSeconds(3.0f);
        DestroyImmediate(texture);
    }
}

 C#List排序

class ComparerDynamicByTime:IComparer<MeetDynamicItemVO>{
        public int Compare(MeetDynamicItemVO x,MeetDynamicItemVO y){
            if (x.time < y.time) {
                return 1;
            }
            return -1;
        }
    }

List<MeetDynamicItemVO> _dynList = new List<MeetDynamicItemVO> ();
_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()
    {

    }
    List<GameObject> list = new List<GameObject>();

    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<T> : EventDispatcher  where T : MonoBehaviour 
{
    private static T _instance;

    public static T instance
    {
        get
        {
            if(_instance == null && GameControl.instance != null)
            {
                _instance =  GameControl.instance.gameObject.AddComponent<T>();
                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<Animator>();
        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.cs
using 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.cs
using 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 off
call:systime

"C:\Program Files (x86)\Unity\Editor\Unity.exe" -quit -batchmode -executeMethod BuildWeb.build
call:systime

echo.&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)

posted @ 2015-05-13 16:35  泥潭里的金鱼  阅读(1927)  评论(0编辑  收藏  举报