Unity3D中的JavaScript语言基础

2023-11-10

Unity中的JS,也称UnityScript,和基于浏览器的JS有比较大的区别,因为UnityScript是基于Mono的.net 的IL语言规范,CLR运行环境(Mono虚拟机)上设计的语言。

0.基本概念

Unity3d中的脚本可以与游戏对象链接,变量数值的修改以及实时预览脚本修改后的游戏效果,节省了很多脚本调整和调试的时间,提高了开发效率。

简单的项目和Unity中的大量例子和脚本资源包都是用JS。商业项目基本都用C#,因为C#和C/C++交互方便,丰富的数据结构和面向对象的架构利于大型程序的编写,很多强大的第三方插件是用C#开发的,方便工作流程。

编译过程:

UnityScript运行环境使用Mono  的.NET Framework。实际上,UnityScript是用Boo实现的,Boo是运行在Mono虚拟机上的一种语言,并且编译成本机代码。JavasScript很多典型的运行环境如String和Math库由Mono提供。你也就知道了为什么UnityScript中方法名要大写了,因为要与Mono中相同。

Unity中的脚本和传统的解释型(JIT解释)语言不同,都是需要经过编译的,因此速度都一样快。

这三种语言的代码最后都会被编译执行,而且脚本可以互相访问

库的调用:

Unity的脚本基于Mono的.net平台上运行,脚本都可以使用.net库,为xml,数据库,正则表达式提供了良好的解决方案。

Unity中js想调用mono的.net库,直接import即可。

import System;

import System.IO;

否则,你带指定完整的命名空间来调用函数,如System.IO.File.Open(),而不是File.Open()。

 

1.基本类型和语句:

1)数据类型

数值类型:char,byte,sbyte;short, ushort, int, uint, long, ulong; float,double; decimal.

布尔值:boolean

字符串:String,[index]符号

字符串[0]是字符串取下标为0的字符。

var s: String = "Whatever_it_may_be";

s =s.Replace("_"[0], " "[0]); // replace all the underscoreswith spaces

2)变量声明:

变量必须先声明[必须](编译缘故,且声明类型有利于减少太多常量,避免内存泄露发生),可以定义类型[可选]:

var playerName:String;

函数的参数也要声明类型:

function Test( playerName:String, baseInfo:Object )

{

}

如果声明时候定义或赋值了类型,那么不能再改变类型,除非声明时候不定义类型。

var a= "test";

a =5;// 报错


var a;

a ="test";

a =5;//正确

变量前面可以加public,protected, private来修饰;不写默认是public的,public的变量可以在Inspector视图中查看和编辑。

3)数组:

内建自定义数组(快功能简单):

var values : int[] = {1,2,3};

转换到Array数组(需要对数组处理),var arr = new Array(values);

Array对象数组(慢动态增长排序合并功能):

var arr = new Array(); arr.Push("good");

转换到内建数组(需要比较高的性能时候),var bArray : int[] = arr.ToBuiltin(int);

4)链表和泛型:

UnityScript可以使用泛型,所以当用到动态大小的数组时,最好用List来替代Array。基本上就没有什么理由要用到Array了,List更快并且功能更多。如果你需要混合类型的数组,你可以用Object List。UnityScript中泛型的语法与C#中接近,除了要加一个额外的“.”符号在“<>”之前。如C#中的"varmyList = new List<int>();"在UnityScript中对应的写法为:"var myList = new List.<int>();"。

5)运算符和表达式:

和C一样。

6)语句:

每行必须写分号; 比C多了for in 用于遍历对象元素,for(var i:int = 0; i < 10; i++)。

switch可以使用String变量。


2.函数

声明规则:

function函数名(参数1:参数类型, 参数2:参数类型...):返回值类型

{

}

unityScript中的函数可以视为Function类型对象,可以像变量一样进行赋值比较等操作。

 

不能写匿名函数。

Math需要用Mathf。


3.类(DOM js中没有类):

在Unity里,一个js文件就是一个类,unity引擎会为js文件自动生成一个类。

对于UnityScript脚本,Unity编译该文件时会自动的为脚本添加一个与脚本文件名相同的类,并自动地继承于MonoBehaviour。但对于C#或Boo,则需要在脚本中显式的写出类名和继承关系。要创建不继承自MonoBehaviour的类,用C#语言,或者从外部添加js脚本资源(就可以自己直接new对象出来了)。

//SayHello.js

#pragma strict // 严格类型检测,尽早生成错误,禁用动态类型,强制用静态类型(强类型)

function sayHello()

{

}

等价于C#中:

#pragma strict

public class SayHello extends MonoBehaviour

{

  function sayHello()

    {

    }

}

但是,你可以在同一个文件中声明多个类,尤其是当你需要使用一些辅助工具类时非常有用,一般这种辅助类没有继承自MonoBehaviour。

class ButtonState {

  var currentState : int;

  var offset : Vector2;

}

如果你在一个文件中声明了MonoBehaviour的子类,但类名与文件名不匹配的话,即使是大小写不一致,你也会碰到麻烦。

一定要理解,当你在js文件中编写行为脚本是,你实际上在编写一个类:

a) 类及其对象:文件名就是类名,如果文件名是foo.js,你就可以在其他地方以var x = new foo()的格式进行调用;

b)类的方法和预定义方法有一些特定的方法是实现系统预先定义的一些事件处理器,如Start、FixedUpdate等。任何事件中,声明的一个函数就是这个文件所代表的类的一个方法。

c) 类的属性:文件中在函数定义之外编写的代码都在该类的范围之内执行,声明的变量也是该类的成员变量。类中的静态函数、变量本质上是类的方法与属性

实例:

/*whenyou drag the behavior onto a gameobject, these values will be visible andeditable

*/

public name : String;

 

/*otherscripts which have a reference to this object (e.g. if they're attached to thesame object) can see public functions

*/

publicage : int;

 

/*privatemembers are NOT visible to other scripts, even if they have a reference to thisobject

*/

private favoriteColor : Color;

 

/*youcan assign a value to bestFriend by dragging a gameObject with an attached copyof the foo behavior to this property. This will give you access to bestFriend'spublic methods and members

*/

public bestFriend : foo;

 

/*this function will be called every frame by Unity, so it's actually an eventhandler

*/

function Update(){

 

 /*transform is a property inherited from thegameObject the behavior is attached to*/

var t = transform;

 }

 

function Bar(){

  // this is just a function, if you don't callit yourself, it will never do anything

}

 

4.继承

Unity里需要extends关键字:

class MyHello extends Hello

{

}

DOM js中用prototype里的bind()方法。

Unityjs里面还提供了虚拟函数。

 

类的继承也是不同的。在JavaScript和C#中,方法是隐型并且不可重载,除非方法声明中添加虚拟关键字。不同的是C#只重载那些包含重载关键字override的方法。而JavaScript不需要关键词,只要重载类方法就可以覆盖,其它的都可继承得到。

//Foo.js

var foo = "hello, world";

 

function doEet () {

  // does nothing, intended to be overridden

}

将会生成:

//Foo.js

import UnityEngine;

classFoo extends MonoBehaviour {

  public var foo = "hello, world";

 

  public function doEet () {

    // does nothing, intended to be overridden

  }

}

 

子类写法:

//PrintingFoo.js

class PrintingFoo extends Foo {

   function doEet() {

    print( foo );

  }

}

创建虚函数

classFoo

{

     virtual function DoSomething ()

     {

         Debug.Log("from baseclass");

     }

}

//SubFoo.js

class SubFoo extends Foo

{

     virtual function DoSomething()

     {

          Debug.Log("from subclass");

     }

}

//Elsewhere

varfoo : Foo = new SubFoo();

foo.DoSomething();//printsfrom sub class

如果你要调用父类的方法,用关键字super。示例如下:

class SubFoo extends Foo

{

  virtual function DoSomething()

  {

    super.DoSomething();// 不是虚函数,应该不需要super修饰就可以直接调用。

    Debug.Log("from sub class");

  }

}

//Elsewhere

varfoo : Foo = new SubFoo();

foo.DoSomething();//prints"from base class" and "from sub class"

类间通信:Use-a方式(关联关系)比继承耦合度底得多,易于修改维护

/*Foo.js */

varbar : Bar;

function Start(){

  bar = gameObject.GetComponent(Bar);

}

function doEet(){

  // do my own thing

  if( bar ){

    bar.doEet();

  }

}

/*Bar.js */

  function doEet(){

    // do something special

  }


5.对象

Unity中不一定可以用new 创建对象(普通类可以,特殊类不行,各种脚本都一样)。特殊类:用编辑器工程视图右键或者组件Create js 或者C#的类都是继承自MonoBehaviour类,对这种类型的类不能new出来一个对象,原因是Unity会为这种类自动创建对象,并调用被重载的方法。 

使得用Unity非常有趣的一件事是,它的类采用了非常自由的mixin策略。通常你可以非常快速简单的查到你所需要的类。最通用的一个例子是Transform类,对于你正在处理的一个对象,所有被附加到该对象的相关联的类,都可以简单快速的获取它的属性和方法。

比如,典型的动作就是你会访问名叫"transform"的变量,它代表与该对象关联的Transform类的实例。如果你需要相关的位置坐标,就访问transform.position(一个 Vector3对象);如果你需要它的GameObject,就访问transform.gameObject;如果你需要它的渲染器,就访问transform.renderer。等等。一般如果你一个对象的主要属性,你就可以快速获取该对象所有其他的属性。

 

6.js和C#单向通信,不能双向通信,因为编译问题

js访问C#脚本组件:

//createa variable to access the C# script

private var csScript : CSharp1;

function Awake()

{

    //Get the CSharp Script

    csScript =this.GetComponent("CSharp1");//Don't forget to place the 'CSharp1'file inside the 'Standard Assets' folder

}

   

//rendertext and other GUI elements to the screen

function OnGUI()

{

    //render the CSharp1 'message' variable

    GUI.Label(new Rect(10,30,500,20),csScript.message);

}

C#访问js脚本组件:

using UnityEngine;

using System.Collections;

public class CSharp2 : MonoBehaviour

{

    //create a variable to access the JavaScriptscript

    private JS1 jsScript;

    void Awake()

    {

        //Get the JavaScript component

        jsScript = this.GetComponent<JS1>();//Don'tforget to place the 'JS1' file inside the 'Standard Assets' folder

    }

    //render text and other GUI elements to thescreen

    void OnGUI()

    {

        //render the JS1 'message' variable

        GUI.Label(newRect(10,10,300,20),jsScript.message);

    }

}

 

7.使用第三方库:

第三方.NET库如XML-RPC可以以新建资源Asset的方式引入。

 

8.调试

可以用print函数,Log()函数或者Debug.Log(),想设置断点,用Debug.Break()函数。

print() 函数将会生成消息,并输出到状态栏及控制台中,但仅限MonoBehavioour类范围内。

更好的办法是使用Debug.Log("insert messagehere");,该方法到处都可使用。还可用Debug.LogWarning 和 Debug.LogError生成警告和错误消息。

Debug.Break(); 可以将游戏暂停在一个精确的点。当一种特定的情条件发生时,如果你想检查对象的状态的时候,这个特性非常有用。

开发环境运行项目时,编辑界面也是完全实时更新的,你可以查看对象实例的内部状态。


参考整理自:

http://www.cnblogs.com/x3d/p/3838619.html

更多的细节:阅读和编写大量unityScript代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity3D中的JavaScript语言基础 的相关文章

随机推荐

  • fiddler抓包工具入门到入职之如何精准的定位前后端的bug

    Fiddler是一款强大的网络调试工具 可以拦截和分析HTTP请求和响应 帮助开发者定位前后端的问题 下面介绍如何使用Fiddler精准定位前后端的Bug 并使用Python代码进行操作 拦截HTTP请求和响应 打开Fiddler 在 Fi
  • 无法连接虚拟设备 sata0:1,因为主机上没有相对应的设备——解决方案

    其实并不复杂 就两个步骤 你装完虚拟机之后什么也别干 如若开虚拟机或虚拟机里面的系统时 出现标题状况 则可以这样解决 1 点击虚拟机 再点击左侧页面编辑虚拟机设置 2 选择CD DVD IDE 将使用物理驱动器的选项改为下方的使用ISO映像
  • 什么是IDaaS?推荐一款开源的IDaaS产品

    IDaaS是云时代的身份和访问管理 IAM 他们之间的关系 IDaaS SaaS IAM IDaaS是一个云服务平台 客户使用提供IDaaS服务相关的产品 例如单点登录 智能多因素认证 来实现云时代所需的既安全又高效的身份和访问管理功能 一
  • 保持工作稳定情绪与心理健康的八大秘诀

    近期发生的新闻热点再度引发公众对稳定情绪和心理健康的关注 有时候我们遇到的最大的敌人 不是运气也不是能力 而是失控的情绪和口无遮拦的自己 如何在工作中保持稳定的情绪 谈谈你的看法 在工作中保持稳定的情绪对于个人的心理健康和工作效率都至关重要
  • 并行单边jacobi算法 奇偶序列

    单边jacobi算法大家都非常熟悉 就是不停地计算旋转矩阵 简单说就是计算c和s 然后旋转 然而其中做一轮旋转 任何两列都需要旋转一次 需要n n 1 2次单独的旋转 这样的旋转其实是可以并行来实现的 这也就是为何jacobi算法最近比较热
  • SpringDataRedis 使用

    1 SpringDataRedis 特点 2 使用 SpringDataRedis 步骤 3 自定义 RedisTemplate 序列化 4 SpringDataRedis 操作对象 1 SpringDataRedis 特点 提供了对不同
  • C#开发学习~~~Console.WriteLine()

    前言 奥利给 冲冲冲 概述 Console WriteLine 是system名称空间中Console类中的一个方法 用于向控制台写入字符串并换行 其格式项采用如下形式 index alignment formatString index
  • 关于返回值RESULT

    关于返回值RESULT HRESULT Here s the RESULT 值分成32位值 HRESULT值中16到30这15个比特位包含的是设备代码 设备代码标识的是可以返回HRESULT返回代码的操作系统部分 由于Windows操作系统
  • P1089 津津的储蓄计划

    题目描述 津津的零花钱一直都是自己管理 每个月的月初妈妈给津津300300元钱 津津会预算这个月的花销 并且总能做到实际花销和预算的相同 为了让津津学习如何储蓄 妈妈提出 津津可以随时把整百的钱存在她那里 到了年末她会加上20 20 还给津
  • Spring 事件发布

    前言 事件发布是 Spring 框架中最容易被忽视的功能之一 但实际上它是一个很有用的功能 使用事件机制可以将同一个应用系统内互相耦合的代码进行解耦 并且可以将事件与 Spring 事务结合起来 实现我们工作中的一些业务需求 和 Sprin
  • 各大知名游戏引擎分析报告

    游戏引擎之争就像编程语言之争一样 在游戏开发圈永远是一个火爆的话题 目前市面上主流的一些游戏引擎 我们来给他们做一些比较 了解他们的历史 特点 为了严谨 备注一下写这个文章的时间编写时间是2021年4月20日 目前国内主流在用的游戏引擎有
  • git未在指定分支修改,保存并切换到正确分支(解决未在指定分支修改问题)

    我们在开发一个需求的时候 可能会忘记切换到开发分支上面 下面是切换到正确分支并保存修改的操作 1 将修改的代码暂存到stash git stash 2 切换到正确的分支 git checkout 正确的分支 3 从stash中取出暂存的代码
  • oracle修改临时表出现已使用的事务正在处理临时表问题

    错误提示 ORA 14450 试图访问已经在使用的事务处理临时表 解决方法 通过第一句sql来查找临时表的object id 然后代入第二局sql来生成第三句sql语句 最后再执行第三句sql语句即可kill session 执行修改表的操
  • 查看Quartz 调度任务 job 的状态

    首先 明确一点什么是 jobkey JobKey jobkey new JobKey name group jobkey相当于一把钥匙连接 所有从 schedule 中 获取 信息的钥匙 如果想获取 初始化信息 则 scheduler ge
  • 使用git rebase压缩提交(commits)

    我使用 git 有一段时间了 但老实说 我很少关注凌乱的提交历史 最近在学习 git rebase 想分享一下如何使用这个命令来压缩整理提交 Commits 五步完成 简而言之 总共有五个步骤 运行git rebase i head x x
  • 【具有路由 WSN 模拟器的随机方式移动】具有路由 WSN 模拟器的随机方式移动(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 经过我们的研究和实践 我们提出了一种具有路
  • vim: 未找到命令

    解决 一键配置所有 yum y install vim 检查是否安装 rpm qa grep vim 出现以下的的命令即安装完毕
  • 如何提高链表的查询效率

    使用跳表 1 链表的变形 跳表 跳表是一种我们不常见的数据结构 但由于其优秀的特性 在工业中 常常被用来代替红黑树 进行查找 插入和删除 Redis的有序集合就是用跳表来实现的 跳表本质上是采用 二分 的思路来改造链表 所以这要求链表必须是
  • HCIP-H12-221练习题

    HCIP H12 221练习题 习题1 由于属性AS PATH不能在AS内起作用 所以规定BGP路由器不会宣告任何从IBGP对等体来的更新信息给其IBGP对等体 A 正确 B 错误 答案 A 习题2 通过重发布命令注入BGP的路由 其Ori
  • Unity3D中的JavaScript语言基础

    Unity中的JS 也称UnityScript 和基于浏览器的JS有比较大的区别 因为UnityScript是基于Mono的 net 的IL语言规范 CLR运行环境 Mono虚拟机 上设计的语言 0 基本概念 Unity3d中的脚本可以与游