您的位置:首页 > 移动开发 > Unity3D

【Unity3D游戏开发学习笔记】(六)上帝之手—GameObject的操作

2015-11-01 15:30 573 查看
在Unity中,所有实体都属于游戏对象(GameObject),比如外部导入到场景中的模型,Unity自带的立方体等等,而要将这些GameOject进行管理,交互等操作,则需要用到脚本来实现,上一节我们已经学习了如何建立一个脚本并绑定到一个物体上,现在我们将进一步学习如何通过脚本对GameObject进行控制。

一、创建GameObject

在Unity里面,创建游戏对象有两种方式:

通过编辑器可视化添加,这一点我们在本系列博客的第三篇:【Unity3D游戏开发学习笔记】(三)移山倒海—Terrain的建造 中已经提到

第二种,则是通过脚本进行创建和删除,这种方式会相对灵活,接下来要讲的也正是这一种方式。

首先,我们新建一个脚本,暂时命名为:GameObjectControl好了,然后打开脚本,并进行以下编辑:

using UnityEngine;
using System.Collections;

public class CreateObjects : MonoBehaviour {

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {

}

void OnGUI()
{
if(GUILayout.Button("创建Cube",GUILayout.Height(50)))
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent<Rigidbody>();
cube.GetComponent<Rigidbody>().useGravity = false;
cube.GetComponent<Renderer>().material.color = Color.red;
cube.name = "Cube";
cube.transform.position = new Vector3(0.0f, 5.0f, 0.0f);
}

if (GUILayout.Button("创建Sphere", GUILayout.Height(50)))
{
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.AddComponent<Rigidbody>();
sphere.GetComponent<Rigidbody>().useGravity = false;
sphere.GetComponent<Renderer>().material.color = Color.green;
sphere.name = "Sphere";
sphere.transform.position = new Vector3(5.0f, 5.0f, 0.0f);
}
}
}


然后保存脚本,并绑定到Camera上,运行,我们就会发现在界面上多了两个按钮,然后分别点击之后,场景当中就会出现一个立方体和一个球体。



我们简要介绍一下几个主要用到的函数:

GameObject.CreatePrimitive()创建一个GameObject对象并指定一个Unity自带的模型(如果想要生成别的物体可以使用GameObject.Instantiate(),这个我们后面说到)

AddComponent< T>() 和 GetComponent< T>() 添加和获取GameObject的组件

transform.position 设置物体在世界坐标系下的位置,如果是想要相对父节点的位置,则使用transform.localPosition

二、获取GameObject

通过脚本获取GameObject有两种方式:

通过声明一个Public变量,然后在Inspector视图进行赋值

通过GameObject的属性对象名称来获取

public GameObject obj;//通过Inspector直接赋值
// Use this for initialization
void Start()
{
if (obj == null)
obj = GameObject.Find("Cube");//根据名称直接在整个场景当中搜索该物体
}


三、添加组件和修改组件

新建的GameObject一般情况下都是没有任何功能属性的,我们需要给它赋予各种游戏组件它才能有自己相应的游戏功能。比如我们拿刚刚那个例子来说:

cube.AddComponent<Rigidbody>();
cube.GetComponent<Rigidbody>().useGravity = false;
cube.GetComponent<Renderer>().material.color = Color.red;


我们这里给cube这个物体添加了一个叫Rigidbody的组件,这是一个刚体组件,有了这个组件,这个物体就受到物理引擎的作用,然后我们修改这个组件的useGravity属性,使它不受重力的作用,并把它材质属性中的颜色改成了红色。大家可以试一下改变它的重力属性,设为true,然后运行的时候我们就能看到立方体往下掉。总的来说,我们给游戏添加组件通过AddComponent< T>()的方法,获取组件则是通过GetComponent方法,然后如果是需要销毁组件,则使用Destroy(),该方法需要提供参数,如果参数是GameObject,就会将这个Object都销毁了。

四、发送广播和消息

在游戏当中,广播和消息是游戏对象之间通讯的一个快捷方式,就像广播那样,由发送方进行消息的发送,而Receiver游戏对象里的Monobehavior脚本都能收到。它主要是通过GameObject.SendMessage(string methonName, object value = null, SendMessageOptions options = SendMessageOptionsRequireReceiver)函数发送的。下面我们来看个例子。

我们新建一个脚本叫Receiver:

using UnityEngine;
using System.Collections;

public class Receiver : MonoBehaviour {

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {

}

void ShowNumber(int num)
{
Debug.Log("我是: "+ this.transform.name + " 我收到的数字是 : " + num);
}
}


然后我们将原来的GameObjectControl.cs文件改一下:

using UnityEngine;
using System.Collections;

public class CreateObjects : MonoBehaviour {

private GameObject[] receiver = new GameObject[2];

// Use this for initialization
void Start()
{

}

// Update is called once per frame
void Update () {

}

void OnGUI()
{
if(GUILayout.Button("创建Cube",GUILayout.Height(50)))
{

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
receiver[0] = cube;
cube.AddComponent<Receiver>();
cube.AddComponent<Rigidbody>(); cube.GetComponent<Rigidbody>().useGravity = false; cube.GetComponent<Renderer>().material.color = Color.red;
cube.name = "Cube";
cube.transform.position = new Vector3(0.0f, 5.0f, 0.0f);
}

if (GUILayout.Button("创建Sphere", GUILayout.Height(50)))
{
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
receiver[1] = sphere;
sphere.AddComponent<Rigidbody>();
sphere.AddComponent<Receiver>();
sphere.GetComponent<Rigidbody>().useGravity = false;
sphere.GetComponent<Renderer>().material.color = Color.green;
sphere.name = "Sphere";
sphere.transform.position = new Vector3(5.0f, 5.0f, 0.0f);
}

if (GUILayout.Button("发送消息", GUILayout.Height(50)))
{
receiver[0].SendMessage("ShowNumber", 999, SendMessageOptions.RequireReceiver);
receiver[1].SendMessage("ShowNumber", 222, SendMessageOptions.RequireReceiver);
}
}
}


在分别创建了立方体和球体之后,点击发送消息,我们可以看到以下结果:



Message相关有3条指令:

SendMessage (“函数名”,参数,SendMessageOptions) //GameObject自身的Script

BroadcastMessage (“函数名”,参数,SendMessageOptions) //自身和子Object的Script

SendMessageUpwards (“函数名”,参数,SendMessageOptions) //自身和父Object的Script

关于第三个参数使用:

SendMessageOptions.RequireReceiver //如果没有找到相应函数,会报错(默认是这个状态)

SendMessageOptions.DontRequireReceiver //即使没有找到相应函数,也不会报错,自动忽略

五、克隆游戏对象

克隆游戏对象跟创建游戏对象不一样,创建游戏对象,得出来的GameObject我们需要对他进行加载组件才能有自己的功能,而克隆游戏对象则可以克隆一个完全具有一定功能的游戏对象(包括其所有的组件)。通过克隆对象,我们可以节省很多的时间,比如子弹的发射,完全可以采用克隆的手段生成大量的子弹而不用我们自己手动新建并且添加属性。同样还是GameObjectControl这个例子,我们改动一下:

在OnGUI上新增一个函数

if (GUILayout.Button("CloneCube", GUILayout.Height(50)))
{
GameObject obj = Instantiate(receiver[0]);
obj.GetComponent<Rigidbody>().useGravity = true;
obj.transform.position = new Vector3(0, 0, 0);
}


在分别点击创建立方体和球体之后,点击CloneCube的按键,我们可以看到每点一次就会生成一个红色的Cube出来并且往下落(因为我们设置了它的重力属性)



然后我们可以发现在Hierarchy界面上出现了很多的Cube(Clone)的Object。

六、移动、缩放,旋转

移动物体

要使游戏对象在原来的基础上继续移动,在代码中可以通过transform.Translate(Vector3 offset)实现,参数是移动的数值.

缩放物体

使用transform.localScale = new Vector3(x,y,z);

分别代表的是x轴方向上缩放x,y轴方向上缩放y,z轴方向上缩放z

整体缩放可以通过将localScale乘一个系数实现。

旋转物体

游戏对象的旋转方式有两种:

围绕自身旋转

围绕某一个点或者是某向量旋转

transform.Rotate()函数是自身的旋转,Unity里面提供了很多的实现方式

transform.RotateAround()则是围绕某个点旋转

这节就先到这O(∩_∩)O,下一节会介绍一些常用的工具类~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: