• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

Unity3D中JavaScript与C#区别

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2019/0819/607.html

 第一个也是最容易辨别的一点就是声明变量和办法。
JavaScript的脚本:
 
1.  private var cubeTransform; 
 
在C#中,常州网站开发建设同样的代码则会是:
 
1.  private Transform cubeTransform; 
 
这对办法同样适用,在C#中,一个办法什么值也没有返回,那么他的返回值为 void 类型,但是在JavaScript中则能够省略。
 
类的继承也是不同的。在JavaScript和C#中,办法是隐型并且不可重载,除非办法声明中添加虚拟关键字。不同的是C#只重载那些包含重载关键字的办法。而JavaScript不需求关键词,只需重载类办法就可继承他们。我们来看一个JavaScript类继承的例子:
 
1.  class Weapon extends Item 
 
2.  { 
 
3.       //Class members and declarations 
 
4.  } 
 
在C#中,同样的代码则会是:
 
1.  public class Weapon : Item 
 
2.  { 
 
3.       //Class members and declarations 
 
4.  } 
 
这就是这两种代码的主要区别,实践上他需求定义全部的东西,像执行产出代码,访问GameObject和组件,激光投射等等。还有一些其他的不同点,比方导入函数库的关键字(在JavaScript中用“Import”,在C#中运用“using”),但是这些声明和关键字的不同就比拟容易明白了。
 
1.  //do this: 
 
2.  private var score:int; 
 
3.  //instead of this: 
 
4.  private var score; 
 
======================================================
 
运用JavaScript来获取GameObject很简单,你只需求调用Find()静态办法,并把想要的GameObject的称号作为参数:
 
 
 
1.  private var pawnGO:GameObject; 
 
2.  function Awake() 
 
3.  { 
 
4.      pawnGO = GameObject.Find("Pawn"); 
 
5.  } 
 
 
 
用C#也很类似:
 
 
 
1.  using UnityEngine; 
 
2.  using System.Collections; 
 
3.   
 
4.  public class PawnGetter : MonoBehaviour 
 
5.  { 
 
6.      private GameObject pawnGO; 
 
7.   
 
8.      void Awake () 
 
9.      { 
 
10.         pawnGO = GameObject.Find("Pawn"); 
 
11.     } 
 
12. } 
 
在不思索两种言语的关键字和格式不同的状况下,代码是完整一样的(第一个代码的第四行和第二个代码的第八行是相同的)。不论代码是强类型还是弱类型,GameObject.Find()办法总是会返回一个GameObject值。
 
 
 
 
 
如今,让我们看看如何取得游戏开发运营一个GameObject上的组件。假定“PawnMover”组件赋给“Pawn”GameObject,让我们来看看如何运用JavaScript取得“PawnMover”组件:
 
1.  private var pawnGO:GameObject; 
 
2.  private var pmSC:PawnMover; 
 
3.  function Awake() 
 
4.  { 
 
5.      pawnGO = GameObject.Find("Pawn"); 
 
6.      pmSC = pawnGO.GetComponent("PawnMover"); 
 
7.  } 
 
根本上,要取得“PawnMover”组件,我们所需求做的就是从“Pawn”GameObject调用GetComponent()办法,并把所需组件的称号作为参数。除了称号,我们也能够经过组件类型作为参数,但是像上面的例子我们用名字就行了。由于JavaScript是弱类型,返回值为组件,我们不需求把组件给PawnMover 类作为结果。在C#中也是一样的:
 
1.  using UnityEngine; 
 
2.  using System.Collections; 
 
3.   
 
4.  public class PawnGetter : MonoBehaviour 
 
5.  { 
 
6.      private GameObject pawnGO; 
 
7.      private PawnMover pmSC; 
 
8.   
 
9.      void Awake() 
 
10.     { 
 
11.         pawnGO = GameObject.Find("Pawn"); 
 
12.         //returns a CS0266 error 
 
13.         pmSC = pawnGO.GetComponent("PawnMover");//<=returns a CS0266 error 
 
14.         //this is the right way to do it when using C# 
 
15.         pmSC = pawnGO.GetComponent< PawnMover >();  
 
16.     } 
 
17. } 
 
用C#就不可能只是调用GetComponent()办法并把该组件的称号作为参数了,这样他会招致错误CS0266,也就是说C#不能从一个类型隐型转换为另一个格式。由于C#属于强类型,我们不能把组件类型转换为PawnMover类型。我们需求调用一个办法传送这个类型,强迫GetComponent()办法返回“PawnMover”对象而不是组件。
 
======================================================
 
 
 
这系列第三节,解释JavaScript和C#在Unity3d游戏引擎中编程时有什么不同。倡议你最好先去阅读第一和第二节,便当了解这节内容。
 
在第三节中,主要解说用JavaScript和C#让一个GameObject向前挪动有什么不同。如今我们来看一段运用JavaScript让一个GameObject向前挪动的代码:
 
 
 
 
 
public var goTransform:Transform;
 
private var vel:int = 2;//how fast the game object is being moved 
 
 
 
 
 
function Awake() 
 
{
 
//get this GameObject's Transform
 
  goTransform = this.GetComponent(Transform);
 
}
 
 
 
 
 
// Update is called once per frame 
 
function Update() 
 
{
 
//moves the containing GameObject forward
 
goTransform.position.z = goTransform.position.z + vel;
 
}
 
把这个脚本的目的是在每一个更新周期使goTransform的z轴坐标增加来控制让goTransform向前挪动的,如今让我们看看用C#编写代码会是什么样的:
 
using UnityEngine; 
 
using System.Collections;   
 
public class PawnMover : MonoBehaviour 
 
{
 
public Transform goTransform; 
 
private int vel = 2;//how fast the game object is being moved  
 
 
 
void Awake() 
 
    { 
 
         //get this GameObject's Transform 
 
        goTransform = this.GetComponent<Transform>(); 
 
    }   
 
// Update is called once per frame 
 
     void Update() 
 
    { 
 
         //returns a CS1612 error 
 
        goTransform.position.z=goTransform.position.z + vel;//<=returns a CS1612 error 
 
         //this is the right way to do it when using C# 
 
goTransform.Translate(Vector3.forward * vel);//moves the containing GameObject forward 
 
 
 
    } 
 
 
这里常州手游开发我们能够看到,在C#中不能像JavaScript脚本中那样直接改动goTransform的z轴坐标值来挪动,这样会产生CS1612error,由于我们是要改动一个值而不是援用该值。为了防止这个错误,在用C#编写脚本时,我们用办法挪动GameObejct,比方Translate()、 Rotate()、 RotateAround()等等。这些办法都是Transform类得公共成员变量。
 
=======================================================
 
 
 
 
         yielding pauses代码关于游戏编程是相当有用的,你能够用它更好的控制你游戏中的事情。无论是用JavaScript或C#都不能简单的中缀Update()办法。置信你曾经猜到了,我们今天要谈论的是这两种言语对此的处理计划有什么不同。我们这节中会给出这种处理计划的常用实例。如今我们来看看JavaScript是如何yield的:
 
 
 
 
 
private var textS:String; 
 
private var counter:float = 0; 
 
function Update () 
 
 
    //call the function that waits three seconds to execute 
 
    WaitThreeSeconds(); 
 
 
//This function waits three seconds before executing 
 
function WaitThreeSeconds() 
 
 
    //Waits three seconds 
 
    yield WaitForSeconds(3); 
 
    //converts the counter to a String and stores its value in textS 
 
    textS = "Three seconds has passed, now I'm counting..."+counter.ToString(); 
 
    //add one to the counter 
 
    ++counter; 
 
 
 
 
function OnGUI() 
 
 
    //The next line displays the first line of text 
 
    GUI.Label(new Rect(20,20,250,20), "I will start counting in 3 seconds."); 
 
    //Displays the counter 
 
    GUI.Label(new Rect(20,40,500,20),textS); 
 
 
这个代码在屏幕上输出了两个文本,第一行会在开端不久就被渲染出来,第二行只会在暂停3秒后呈现,yield代码只会执行一次,然后再正常执行Update()循环(也就是说不会再等三秒在去执行一次WaitThreeSeconds())。有一点要留意,我们晓得能在函数内用yield,Update()办法是不能被暂停的。
 
如今来看看C#代码:
 
using UnityEngine; 
 
using System.Collections; 
 
public class Yield : MonoBehaviour 
 
 
    private string textS; 
 
    private float counter = 0; 
 
    void Update () 
 
    { 
 
        //doesn't generate an error but doesn't work either. 
 
        WaitThreeSeconds();//<=does nothing 
 
        //start the coroutine named WaitThreeSeconds 
 
        StartCoroutine("WaitThreeSeconds");//<=right 
 
    } 
 
    //Waits three seconds before executing 
 
    IEnumerator WaitThreeSeconds() 
 
    { 
 
        //Waits three seconds 
 
        yield return new WaitForSeconds(3); 
 
        //converts the counter to a String and stores its value in textS 
 
        textS = "Three seconds has passed, now I'm counting..."+counter.ToString(); 
 
        //add one to the counter 
 
        ++counter; 
 
    } 
 
     
 
    void OnGUI() 
 
    { 
 
        //The next line displays the first line of text 
 
        GUI.Label(new Rect(20,20,250,20), "I will start counting in 3 seconds."); 
 
        //Displays the counter 
 
        GUI.Label(new Rect(20,40,500,20),textS); 
 
    } 
 
 
主要区别就是我们常州游戏开发培训在C#中不能把yield放在函数中运用,需求运用IEnumerator接口,之所以这样只是由于C#就是这么设计的(关于IEnumerator接口的更多信息能够在)我们不能像调用普通函数那样调用WaitThreeSeconds(),即使那么做也不会有任何反响的。所以我们的处理方法就是想调用协同那样调用WaitThreeSeconds()。(例如14行)
 
另外一个区别就是在21行,我们要用yield return new WaitForSeconds(3)来交换 yield WaitForSeconds(3)代码,由于我们用IEnumerator接口需求一个返回值。
 
====================================================
 
 
 
 
先来看点儿根底学问:何为射线投射?望文生义,就是用程序模仿了一个理想生活中被打出的一道射线(“Ray”,译者:O(∩_∩)O哈哈~我的名字)。在游戏编程中相当有用,Raycast类能够返回源点到射线碰撞某物体的间隔(有的时分被用作得到碰撞物体的称号)。Unity3D没有单独的Raycast类,它是被Physics, RaycastHit 和 Ray 功用分散的类。
 
我来举一个用JavaScript投射射线的例子:
 
 
 
//Creates a ray object 
 
private var ray : Ray; 
 
//creates a RaycastHit, to query informarion about the objects that are colliding with the ray 
 
private var hit : RaycastHit  =  new RaycastHit(); 
 
//Get this GameObject's transform 
 
private var capsTrans : Transform; 
 
 
 
function Awake() 
 
 
//get this Transform 
 
capsTrans = this.GetComponent(Transform); 
 
 
// Update is called once per frame 
 
function Update () 
 
 
//recreate the ray every frame 
 
ray = new Ray(capsTrans.position, Vector3.left); 
 
//Casts a ray to see if something have hit it 
 
if(Physics.Raycast(ray.origin,ray.direction, hit, 10))//cast the ray 10 units in distance 
 
 
//Collision has happened, print the distance and name of the object into the console 
 
Debug.Log(hit.collider.name); 
 
Debug.Log(hit.distance); 
 
 
else 
 
 
//the ray isn't colliding with anything 
 
Debug.Log("none") 
 
 
 
 
 
来看看它是如何工作的:
 
首先,我们需求创立一个射线对象(Ray object),并且每帧都要重新创立一次(例如第2和20行),该射线类具备如光线投射的方向和来源等属性。
 
然后,我们需求一个RaycastHit类对象,获取射线与其他GameObject的碰撞发作时的间隔和一些其他的细致信息。
 
接下来,我们需求从Physics类中调用Raycast()静态办法(例如23行),这个办法将实践的投射出一道射线,记载下射线源点、投射方向、RaycastHit 对象和间隔这些参数,然后把间隔和碰撞结果传送到RaycastHit对象。
 
乍一听起来可能有些乱,但是多尝试几回就纯熟了(更多信息请查看http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html),接下来看看C#代码:
 
 
 
using UnityEngine; 
 
using System.Collections; 
 
  
 
public class Raycast : MonoBehaviour 
 
 
//Creates a ray object 
 
private Ray ray; 
 
//creates a RaycastHit, to query informarion about the objects that are colliding with the ray 
 
private RaycastHit hit = new RaycastHit(); 
 
//Get this GameObject's transform 
 
private Transform capsTrans; 
 
  
 
void Awake() 
 
 
//get this Transform 
 
capsTrans = this.GetComponent<Transform>(); 
 
 
// Update is called once per frame 
 
void Update () 
 
 
//recreate the ray every frame 
 
ray = new Ray(capsTrans.position, Vector3.left); 
 
//Casts a ray to see if something have hit it 
 
if(Physics.Raycast(ray.origin, ray.direction, out hit, 10))//cast the ray 10 units in distance 
 
 
//Collision has happened, print the distance and name of the object into the console 
 
Debug.Log(hit.collider.name); 
 
Debug.Log(hit.distance); 
 
 
else 
 
 
//the ray isn't colliding with anything 
 
Debug.Log("none") 
 
 
 
 
 
 
当投射射线时,这两种编程言语之间独一的区别在第28行代码上。如今来看看我们怎样Out关键词来传送hit对象呢?由于在C#中Raycast()办法需求RaycastHit参数做参考,这恰巧也是out关键词做的事情。所以我们用传送一个Raycast()的参考来替代传送对象(就仿佛我们在JavaScript中做的那样)。

上篇:上一篇:Unity3d 插件研讨之EasyTouch插件
下篇:下一篇:cocos2d-x 3.x pageView的使用