查看: 3942|回复: 0
打印 上一主题 下一主题

Unity3d场景运行及脚本需要注意的一些问题

[复制链接]

5552

主题

2

听众

8万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
11

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-4-7 10:30:24 |只看该作者 |倒序浏览
1.GUI内容相关



一切关于GUI内容的代码,必须通过OnGUI方法来显示



代码#1



Rect a = new Rect(100,100,100,20);

//相关定义内容可以写在OnGUI方法块外面



void OnGUI()



{



if(GUI01){



//GUI.Box(newRect(drawPos.x + 10, drawPos.y + 10, 100, 50), "It's " +gameObject.name);

//相关显示代码



GUI.Box(a, "It's" + gameObject.name);

//显示相关的代码必须在此OnGUI方法块中



}



}

本帖隐藏的内容需要回复才可以浏览

―――――――――――――――――――――――――――――――

代码#2



///可以随鼠标拖动而移动的窗体



// Use this forinitialization



public Rect window01 = new Rect(20, 20, 150, 100);

//定义窗体初始状态:X、Y位置及长宽



voidStart()



{



}



voidUpdate()



{



}



//控制界面显示的“头方法”,一要关于GUI的内容都要通过这个OnGUI来实现显示。



voidOnGUI()



{



//将window01GUI矩形设置为后面的DoMyWindow窗体的实例并显示之,标题设置为"My Windows"



window01 = GUI.Window(0,window01, DoMyWindow, "My Windows");



}



//定义一个窗体原型DoMyWindow



voidDoMyWindow(int windowID)



{



GUI.Button(new Rect(20, 80, 50,20), "ok!");

//为窗体中添加一个按钮



///使用DragWindow设置window窗体为可被鼠标拖动移动,



///并设置window窗体的鼠标响应范围,四个值分别是窗体中响应区的开始X、Y位置(窗体中的局部坐标),响应区的长宽。



GUI.DragWindow(new Rect(0, 0, 150,20));



}



GUI.changed的说明



当GUI窗体中发生了修改事件(如点击按钮、滑动条被拖动等),GUI.changed将会返回true。



usingUnityEngine;



usingSystem.Collections;



public class GUI_Toolbar_try01: MonoBehaviour



{



GameObject Text03, Text04;

//定义对信息显示内容的引用



int a = 0;

//记录改变次数的变量



int selectedToolbar = 0;



string[] toolbarStrings ={ "One", "Two"};

//定义toolbar上面的按钮数量及显示内容:共两个,分别显示One和Two



// Use this for initialization



void Start () {



Text03 = GameObject.Find("text03");



Text04 = GameObject.Find("text04");



}



// Update is called once per frame



void Update () {



}



void OnGUI()



{



selectedToolbar = GUI.Toolbar(new Rect(50,10,Screen.width-100,30),selectedToolbar,toolbarStrings);



if(GUI.changed)//如果发生过改变



{



Text03.guiText.text = "This Toolbar was clicked "+a.ToString();//在信息显示上显示出此次修改



if(selectedToolbar == 0)//如果点击的按钮是第一个



{



Text04.guiText.text = "First button was clicked";



}



else//否则



{



Text04.guiText.text = "Second button was clicked";



}



a++;//记录一次



}



}



}



GUI多窗体显示的问题

同一个场景内,每个显示的窗体的ID都不能重复



usingUnityEngine;



usingSystem.Collections;



public class GUI_MultiWindows_try01: MonoBehaviour



{



// Use this for initialization



public Rectwindow01 = new Rect(50,50, 200, 200);



public Rectwindow02 = new Rect(50,100, 200, 200);



void Start () {



}



// Update is called once per frame



void Update () {



}



void OnGUI()



{



///多窗体显示的话,每个窗体的ID不能重复



window01 = GUI.Window(0, window01,IsWindows01, "windows01");

//第一个实参为此窗体的ID



window02 = GUI.Window(1, window02,IsWindows02, "windows02");

//第一个实参为此窗体的ID



}



void IsWindows01(int WindowID)



{



GUI.Label(newRect(50,50,100,20),"hahaha...");



GUI.DragWindow();



}



void IsWindows02(int WindowID)



{



GUI.Button(newRect(100,50,50,50),"button01");



GUI.DragWindow();



}



}



GUI窗体显示中文的问题



void OnGUI()



{



GUI.skin = Resources.Load("ChineseFontSkin") as GUISkin;

//设置GUI窗体上的文字为中文字体,场景的Resources目录中必须有相关的中文字体和ChineseFontSkin.GUISkin文件



window01 = GUI.Window(0,window01,MyWindow01,"功能面板");



window01.x = Mathf.Clamp(window01.x,0.0f,Screen.width-window01.width);



window01.y = Mathf.Clamp(window01.y,0.0f,Screen.height-window01.height);



}



2. Camera.main.WorldToScreenPoint(transform.position)只能在与场景运行相关的代码块中使用



//错误

Vector3 drawPos = Camera.main.WorldToScreenPoint(transform.position);

//正确



Vector3drawPos ;



// 先在外面定义



// 然后要在Update()方法块中进行定义,否定会系统会报错



void Update () {



drawPos= Camera.main.WorldToScreenPoint(transform.position);



drawPos.y = Camera.main.pixelHeight -drawPos.y;



}



3.制作unity3d场景,必须在英文目录中。



U饭_叫你自由(14097502)16:41:19

这个真的不是bug

六必居的老中医(6872084) 16:41:42

主要是因为双字节的不支持

U饭_叫你自由(14097502)16:41:52

你只要把字体放在一个非中文路径下的目录,再拖到unity里就可以了

U饭_叫你自由(14097502)16:41:57

支持。。

U饭_叫你自由(14097502)16:42:04

你按我的说法做一次就知道了



4.在场景中创建游戏对象时



5.unity场景创建时的几个重要目录:

Assets

editor

Plugins

脚本运行时需要引用的自定义的类及对象所在的目录

Resources

场景运行时需要动态调用的资料目录,也就是说只要存在于这个目录中的文件,在编译时都会被打入场景包中。



6.Plugins目录的用途:



在制作场景时,很时候需要一些可以被所有的脚本读取使用的自定义类,所以unity3d提供了Plugins目录,只要将包含自定义类的文件置入其中,在场景运行时相关的脚本就可以找到需要的自定义类。

下面是一个Plugins目录中的例文件:



usingUnityEngine;



usingSystem.Collections;



usingSystem.Text;



///

文件名:sy01.cs



///

这种用途的文件,就不像一般的脚本文件一样需要“public class 类名称: MonoBehaviour”,而是直接在文件内添加类的定义即可



public class display01

//定义的第一个类



{



public inta=20;



public stringc="";



public display01(int a_in , string c_in)



{



this.a = a_in;



this.c = c_in;



}



public stringdisplayAll()



{



StringBuilder sb = new StringBuilder();



sb.Append("a: ");



sb.AppendLine(this.a.ToString());



sb.Append("c: ");



sb.Append(this.c.ToString());



return sb.ToString();



}



}



public class display02

//定义的第二个类



{



public intb;



public stringname ="";



public display02(int b_in, string name_in)



{



this.b = b_in;



this.name = name_in;



}



public stringdisplayAll()



{



StringBuilder sb = new StringBuilder();



sb.Append("b: ");



sb.AppendLine(this.b.ToString());



sb.Append("Name: ");



sb.AppendFormat(this.name.ToString());



return sb.ToString();



}



}



脚本中对上面文件中类的调用:



usingUnityEngine;



usingSystem.Collections;



public class UsePlugins_try01: MonoBehaviour



{



GameObject Text03;



GameObject Text04;



void Start () {



Text03 = GameObject.Find("text03");

//定义对场景中GuiText文字显示对象text03的引用



Text03.guiText.font = Resources.Load("xiyuanjian") asFont;

//设置其字体为细圆简



Text04 = GameObject.Find("text04");

//定义对场景中GuiText文字显示对象text04的引用



Text04.guiText.font = Resources.Load("xiyuanjian") asFont;

//设置其字体为细圆简



}



void Update () {



display01 a = new display01(5,"程兆祥");



Text03.guiText.text = a.displayAll();



display02 b = new display02(100,"czx_main是程兆祥");



Text04.guiText.text = b.displayAll();



}



}



7.GetComponentInChildren方法的使用:



javas cript代码



//print(GetComponentInChildren(Rigidbody).name);

//可以运行,用来访问子对象上的组件



GetComponentInChildren(display01_js).display();

//可以运行,用来访问子对象上的脚本



C#代码



//

print((GetComponentInChildren(typeof(Rigidbody)) asRigidbody).name);

//可以运行,用来访问子对象上的组件



(GetComponentInChildren(typeof(display01))as display01).display();

//可以运行,用来访问子对象上的脚本



可以通过GetComponentInChildren()方法实现对子对象上的组合的访问,但这有一个前提,如果父对象上也有相同的组件,那么最终返回的是父对象上的组件。



8.字符串类型转换为浮点类型:

利用System命名空间:

float temp = (float)Convert.ChangeType(x_in,typeof(float));

float temp = Convert.ToSingle(x_in);

不利用System命名空间:

float a = float.Parse(x_in);



9.实现在网页传递给场景中对象多参数:

因为就目前所知,SendMessage()方法只能为对象的脚本方法传递一个参数,这样当脚本方法的参数是多个时,就成问题了。

利用System.IO命名空间的StringReader类:



voidEnterString(string enter_string) //将传递的参数字符串分割后传递给Move



{

///技术上要求传递给此方法的字符串(enter_string)是多行的,第一行是X值,第二行是Y值,第三行是Z值



StringReaderSR = new StringReader(enter_string);



stringx_enter = SR.ReadLine();

//获取第一行,即X



stringy_enter = SR.ReadLine();

//获取第二行,即Y



stringz_enter = SR.ReadLine();

//获取第三行,即Z



Move(x_enter, y_enter, z_enter);

//将分割好的参数传递给Move方法



}



void Move(string x_in, stringy_in, string z_in)

//测试多参数



//

void Move(stringx_in)

//测试单参数



{



Vector3Translate_temp = new Vector3(float.Parse(x_in),float.Parse(y_in),float.Parse(z_in));



//Vector3Translate_temp = transform.position;//测试单参数所用



//Translate_temp.x= float.Parse(x_in);

//测试单参数所用



transform.position = Translate_temp;



///下面是用来测试字符串转换浮点数的代码



//print((float)Convert.ChangeType(x_in,typeof(float)));



//print(Convert.ToSingle(x_in));



//print(float.Parse(x_in));



}



10.Unity3d中模型面片的上限

任意单体模型,当中的三角面片数量都不能超过65000,这一点在从其它软件中导入模型时尤其要注意。



11.关于使用Event类时需要注意的问题

因为Event类属于是Unity3d中GUI的事件类,所以在使用此类时,必须要由OnGUI方法来调用它,如果使用非OnGUI方法来调用的话,就会报“NullReferenceException:Object reference not set to an instance of an object

”的错。



比如下面的windowRegionFind()方法:



//本GUI窗体对鼠标光标屏幕坐标的感知



bool windowRegionFind(Rect windowIn)



{



//if (windowIn.Contains(Input.mousePosition))



if (windowIn.Contains(Event.current.mousePosition))



{



//s cript01.MouseInGUI= true;



returntrue;



}



else



{



//s cript01.MouseInGUI= false;



returnfalse;



}



}



通过OnGUI方法使用之



void OnGUI()



{



window01 = GUI.Window(0, window01,MyWindow01, window_title01); //在场景中显示定义好的window01GUI窗体



//设置window01GUI窗体只能在屏幕以内显示,不会出界



window01.x = Mathf.Clamp(window01.x, 0.0f, (Screen.width-window01.width));



window01.y = Mathf.Clamp(window01.y,0.0f,(Screen.height-window01.height));



a = windowRegionFind(window01);



//if(window01.Contains(Event.current.mousePosition))

//在OnGUI方法里直接使用Event类



//{



//s cript01.MouseInGUI= true;



//

a= true;



//}



//else



//{



//s cript01.MouseInGUI= false;



//

a=false;



//}



}



通过Update方法使用之



void Update () {



//如果



//a = windowRegionFind(window01);

//运行时会报错



}
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-6-15 22:13 , Processed in 0.091490 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部