查看: 1747|回复: 2
打印 上一主题 下一主题

[经验分享] 场景运行及脚本需要注意的一些问题

[复制链接]
ZackD    

715

主题

22

听众

4万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
26224
精华
17

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

跳转到指定楼层
楼主
发表于 2013-9-26 15:48:22 |只看该作者 |倒序浏览
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
回复

使用道具 举报

13

主题

8

听众

4583

积分

中级设计师

Rank: 5Rank: 5

纳金币
13
精华
0

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

沙发
发表于 2013-10-9 14:31:58 |只看该作者
这个文章太有用了,谢谢分享!
回复

使用道具 举报

2

主题

1

听众

1143

积分

助理设计师

Rank: 4

纳金币
350
精华
0
板凳
发表于 2013-10-28 10:58:04 |只看该作者
感谢楼主分享
回复

使用道具 举报

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

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-17 07:35 , Processed in 0.163236 second(s), 29 queries .

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

© 2008-2019 Narkii Inc.

回顶部