2017-01-11 17:07:42 zzlyw 阅读数 16501
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4633 人正在学习 去看看 张刚

前言

经过前面《Unity3D入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了Unity3D的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文用到的东西其实不多,非常简单。在最后我们会把完整工程的源代码发布出来,以供初学者参考。先展示一下最后的运行效果吧。

1 准备工作

(1)开发环境:Win10 + Unity5.4.1

(2)图片素材准备:

黑棋子和白棋子

   

棋盘


获胜提示图片




2 开发流程

上文提到的素材可以直接下载我们给出的这些图,也可以自己制作。注意黑白棋子要做成PNG格式,以保证显示的时候棋子四个角是透明的。将用到的图片素材导入到工程当中。新建一个场景,创建一个Plane,作为MainCamera的子物体。将棋盘贴图拖动到Plane上,并且将Plane正面面向摄像机。


再创建四个sphere,作为Plane的子物体,分别命名为LeftTop、RightTop、LeftBottom、RightBottom。然后把他们的MeshRenderer勾选掉。这些球是为了计算棋子落点所设置的,所以需要把它们与棋盘的四个角点对准。


然后我们创建一个chess.cs脚本,绑定到MainCamera上。脚本中包含了所有的功能。需要绑定的一些物体如图所示。


chess.cs脚本如下:

using UnityEngine;
using System.Collections;

public class chess : MonoBehaviour {

	//四个锚点位置,用于计算棋子落点
	public GameObject LeftTop;
	public GameObject RightTop;
	public GameObject LeftBottom;
	public GameObject RightBottom;
	//主摄像机
	public Camera cam;
	//锚点在屏幕上的映射位置
	Vector3 LTPos;
	Vector3 RTPos;
	Vector3 LBPos;
	Vector3 RBPos;

	Vector3 PointPos;//当前点选的位置
	float gridWidth =1; //棋盘网格宽度
	float gridHeight=1; //棋盘网格高度
	float minGridDis;  //网格宽和高中较小的一个
	Vector2[,] chessPos; //存储棋盘上所有可以落子的位置
	int[,] chessState; //存储棋盘位置上的落子状态
	enum turn {black, white } ;
	turn chessTurn; //落子顺序
	public Texture2D white; //白棋子
	public Texture2D black; //黑棋子
	public Texture2D blackWin; //白子获胜提示图
	public Texture2D whiteWin; //黑子获胜提示图
	int winner = 0; //获胜方,1为黑子,-1为白子
	bool isPlaying = true; //是否处于对弈状态
	void Start () {
		chessPos = new Vector2[15, 15];
		chessState =new int[15,15];
		chessTurn = turn.black;

	}

	void Update () {

		//计算锚点位置
		LTPos = cam.WorldToScreenPoint(LeftTop.transform.position);
		RTPos = cam.WorldToScreenPoint(RightTop.transform.position);
		LBPos = cam.WorldToScreenPoint(LeftBottom.transform.position);
		RBPos = cam.WorldToScreenPoint(RightBottom.transform.position);
		//计算网格宽度
		gridWidth = (RTPos.x - LTPos.x) / 14;
		gridHeight = (LTPos.y - LBPos.y) / 14;
		minGridDis = gridWidth < gridHeight ? gridWidth : gridHeight;
		//计算落子点位置
		for (int i = 0; i < 15; i++)
		{
			for (int j = 0; j < 15; j++)
			{
				chessPos[i, j] = new Vector2(LBPos.x + gridWidth * i, LBPos.y + gridHeight * j);
			}
		}
		//检测鼠标输入并确定落子状态
		if (isPlaying && Input.GetMouseButtonDown(0))
		{
			PointPos = Input.mousePosition;
			for (int i = 0; i < 15; i++)
			{
				for (int j = 0; j < 15; j++)
				{   
					//找到最接近鼠标点击位置的落子点,如果空则落子
					if (Dis(PointPos, chessPos[i, j]) < minGridDis / 2 && chessState[i,j]==0)
					{
						//根据下棋顺序确定落子颜色
						chessState[i, j] = chessTurn == turn.black ? 1 : -1;
						//落子成功,更换下棋顺序
						chessTurn = chessTurn == turn.black ? turn.white : turn.black;                        
					}
				}
			}
			//调用判断函数,确定是否有获胜方
			int re = result();
			if (re == 1)
			{
				Debug.Log("黑棋胜");
				winner = 1;
				isPlaying = false;
			}
			else if(re==-1)
			{
				Debug.Log("白棋胜");
				winner = -1;
				isPlaying = false;
			}            
		}
		//按下空格重新开始游戏
		if (Input.GetKeyDown(KeyCode.Space))
		{
			for (int i = 0; i < 15; i++)
			{
				for (int j = 0; j < 15; j++)
				{
					chessState[i, j] = 0;
				}
			}
			isPlaying = true;
			chessTurn = turn.black;
			winner = 0;
		}     
	}
	//计算平面距离函数
	float Dis(Vector3 mPos, Vector2 gridPos)
	{
		return Mathf.Sqrt(Mathf.Pow(mPos.x - gridPos.x, 2)+ Mathf.Pow(mPos.y - gridPos.y, 2));
	}

	void OnGUI()
	{ 
		//绘制棋子
		for(int i=0;i<15;i++)
		{
			for (int j = 0; j < 15; j++)
			{
				if (chessState[i, j] == 1)
				{
					GUI.DrawTexture(new Rect(chessPos[i,j].x-gridWidth/2, Screen.height-chessPos[i,j].y-gridHeight/2, gridWidth,gridHeight),black);
				}
				if (chessState[i, j] == -1)
				{
					GUI.DrawTexture(new Rect(chessPos[i, j].x - gridWidth / 2, Screen.height - chessPos[i, j].y - gridHeight / 2, gridWidth, gridHeight), white);
				}               
			}
		}
		//根据获胜状态,弹出相应的胜利图片
		if (winner ==  1)
			GUI.DrawTexture(new Rect(Screen.width * 0.25f, Screen.height * 0.25f, Screen.width * 0.5f, Screen.height * 0.25f), blackWin);
		if (winner == -1)
			GUI.DrawTexture(new Rect(Screen.width * 0.25f, Screen.height * 0.25f, Screen.width * 0.5f, Screen.height * 0.25f), whiteWin);

	}
	//检测是够获胜的函数,不含黑棋禁手检测
	int result()
	{
		int flag = 0;
		//如果当前该白棋落子,标定黑棋刚刚下完一步,此时应该判断黑棋是否获胜
		if(chessTurn == turn.white)
		{
			for (int i = 0; i < 11; i++)
			{
				for (int j = 0; j < 15; j++)
				{
					if (j < 4)
					{
						//横向
						if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == 1 && chessState[i + 1, j] == 1 && chessState[i + 2, j] == 1 && chessState[i + 3, j] == 1 && chessState[i + 4, j] == 1)
						{
							flag = 1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j + 1] == 1 && chessState[i + 2, j + 2] == 1 && chessState[i + 3, j + 3] == 1 && chessState[i + 4, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//左斜线
						//if (chessState[i, j] == 1 && chessState[i + 1, j - 1] == 1 && chessState[i + 2, j - 2] == 1 && chessState[i + 3, j - 3] == 1 && chessState[i + 4, j - 4] == 1)
						//{
						//    flag = 1;
						//    return flag;
						//}
					}
					else if (j >= 4 && j < 11)
					{
						//横向
						if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == 1 && chessState[i + 1, j] == 1 && chessState[i + 2, j] == 1 && chessState[i + 3, j] == 1 && chessState[i + 4, j] == 1)
						{
							flag = 1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j + 1] == 1 && chessState[i + 2, j + 2] == 1 && chessState[i + 3, j + 3] == 1 && chessState[i + 4, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//左斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j - 1] == 1 && chessState[i + 2, j - 2] == 1 && chessState[i + 3, j - 3] == 1 && chessState[i + 4, j - 4] == 1)
						{
							flag = 1;
							return flag;
						}
					}
					else
					{
						//横向
						//if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)
						//{
						//    flag = 1;
						//    return flag;
						//}
						//纵向
						if (chessState[i, j] == 1 && chessState[i + 1, j] == 1 && chessState[i + 2, j] == 1 && chessState[i + 3, j] == 1 && chessState[i + 4, j] == 1)
						{
							flag = 1;
							return flag;
						}
						//右斜线
						//if (chessState[i, j] == 1 && chessState[i + 1, j + 1] == 1 && chessState[i + 2, j + 2] == 1 && chessState[i + 3, j + 3] == 1 && chessState[i + 4, j + 4] == 1)
						//{
						//    flag = 1;
						//    return flag;
						//}
						//左斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j - 1] == 1 && chessState[i + 2, j - 2] == 1 && chessState[i + 3, j - 3] == 1 && chessState[i + 4, j - 4] == 1)
						{
							flag = 1;
							return flag;
						}
					}

				}
			}
			for (int i = 11; i < 15; i++) 
			{
				for (int j = 0; j < 11; j++) 
				{
					//只需要判断横向  
					if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)  
					{  
						flag = 1;  
						return flag;  
					}  
				}
			}
		}
		//如果当前该黑棋落子,标定白棋刚刚下完一步,此时应该判断白棋是否获胜
		else if(chessTurn == turn.black)
		{
			for (int i = 0; i < 11; i++)
			{
				for (int j = 0; j < 15; j++)
				{
					if (j < 4)
					{
						//横向
						if (chessState[i, j] == -1 && chessState[i, j + 1] == -1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] == -1)
						{
							flag = -1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == -1 && chessState[i + 1, j] == -1 && chessState[i + 2, j] == -1 && chessState[i + 3, j] == -1 && chessState[i + 4, j] == -1)
						{
							flag = -1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j + 1] == -1 && chessState[i + 2, j + 2] == -1 && chessState[i + 3, j + 3] == -1 && chessState[i + 4, j + 4] == -1)
						{
							flag = -1;
							return flag;
						}
						//左斜线
						//if (chessState[i, j] == -1 && chessState[i + 1, j - 1] == -1 && chessState[i + 2, j - 2] == -1 && chessState[i + 3, j - 3] == -1 && chessState[i + 4, j - 4] == -1)
						//{
						//    flag = -1;
						//    return flag;
						//}
					}
					else if (j >= 4 && j < 11)
					{
						//横向
						if (chessState[i, j] == -1 && chessState[i, j + 1] == -1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] ==- 1)
						{
							flag = -1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == -1 && chessState[i + 1, j] == -1 && chessState[i + 2, j] == -1 && chessState[i + 3, j] == -1 && chessState[i + 4, j] == -1)
						{
							flag = -1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j + 1] == -1 && chessState[i + 2, j + 2] == -1 && chessState[i + 3, j + 3] == -1 && chessState[i + 4, j + 4] == -1)
						{
							flag = -1;
							return flag;
						}
						//左斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j - 1] == -1 && chessState[i + 2, j - 2] == -1 && chessState[i + 3, j - 3] == -1 && chessState[i + 4, j - 4] == -1)
						{
							flag = -1;
							return flag;
						}
					}
					else
					{
						//横向
						//if (chessState[i, j] == -1 && chessState[i, j + 1] ==- 1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] == -1)
						//{
						//    flag = -1;
						//    return flag;
						//}
						//纵向
						if (chessState[i, j] == -1 && chessState[i + 1, j] ==- 1 && chessState[i + 2, j] ==- 1 && chessState[i + 3, j] ==- 1 && chessState[i + 4, j] == -1)
						{
							flag = -1;
							return flag;
						}
						//右斜线
						//if (chessState[i, j] == -1 && chessState[i + 1, j + 1] == -1 && chessState[i + 2, j + 2] == -1 && chessState[i + 3, j + 3] == -1 && chessState[i + 4, j + 4] == -1)
						//{
						//    flag = -1;
						//    return flag;
						//}
						//左斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j - 1] == -1 && chessState[i + 2, j - 2] == -1 && chessState[i + 3, j - 3] == -1 && chessState[i + 4, j - 4] == -1)
						{
							flag = -1;
							return flag;
						}
					}
				}
			}
			for (int i = 11; i < 15; i++) 
			{
				for (int j = 0; j < 11; j++) 
				{
					//只需要判断横向  
					if (chessState[i, j] == -1 && chessState[i, j + 1] == -1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] == -1)  
					{  
						flag = -1;  
						return flag;  
					}  
				}
			}
		}       
		return flag;
	}    
}



运行效果截图:



小结

本程序实现了五子棋的基本功能,纯属娱乐而作。暂时没有加入各种UI、网络模块等。本程序经过了简单的测试,没有什么问题,如果大家在使用的时候发现有什么Bug,请联系我改正,谢谢。

*************************************************************************************

下面是工程源码下载地址:

https://github.com/zzlyw/FiveChess_Tutorial



2018-11-29 12:45:03 kybshj 阅读数 12593
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4633 人正在学习 去看看 张刚

Unity3D游戏引擎介绍

Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。使用Unity3D,开发者可以快速的开发出游戏。Unity3D引擎占据了游戏引擎市场45%的份额,居全球首位。因此,学习游戏开发,Unity3D的人才需求量最为庞大

Unity3D学习历程

俗话说,万事开头难。Unity3D的学习历程也是一样。学习Unity3D,大致分为以下七个步骤:

  1. 了解unity3d的菜单,视图界面。 这些是最基本的基础,可以像学word操作一样,大致能明白有几个菜单,几个基本的视图,各自起什么作用的就可以了。当然还要了解人物基本的比例和结构;
  2. 理解场景里面的坐标系统,输入系统,简单的向量概念。Unity3D的坐标系统及向量概念如果不理解清楚,不理解世界坐标,局部坐标的关系,即使一个简单的移动,缩放,旋转的几行代码,也会困惑你半天;
    Unity3D C#代码片段
  3. 学习创建基本的场景的一些基本概念:游戏对象,组件,脚本。在界面上分别体现在层次视图,项目视图及属性视图,要理清楚彼此之间的关系;
  4. 学习资源导入方面的一些基本元素:网格,材质,贴图,动画等;
  5. 学习脚本的生命周期,Start,UpDate,ONGUI这些基本的方法。了解,预制,时间,数学等常用的类及相关方法。理解游戏对象,组件,脚本彼此之间的关系;
  6. 进一步学习摄像机,灯光,地形,渲染,粒子系统,物理系统等等,这些每一个深入进去都是一个很复杂的主题;
  7. 一些更高级的概念:向量的加减法点乘叉乘,光照法线贴图,内存管理,图形优化等等;

因此,Unity3D入门相对容易,真的要精通,那是相当难的。

Unity3D快速入门途径

通常,学习Unity3D有以下三种途径:

  1. 通过官方文档和书籍。我们知道,Unity3D的官方文档是没有中文的,因此,国内大部分入门Unity3D的学习者往往首先会选择一本类似于从入门到精通类型的书籍,再结合网上的一些教程进行学习。比如口碑比较好的《Unity 3D游戏开发》,书中很全面的介绍入门Unity3D的内容。但是,书和文档最大的缺点就是纯文字,在没有人的指点下,自学往往感觉很抽象,即使跟着书中文档写出了案例Demo,也很难举一反三的做出自己系统的游戏项目。入门书籍往往给所有人的感觉是,需要这本书的同学很难看懂这本书,能看懂这本书的人已经不需要这本书了。不过,书作为一本字典用随时查阅还是不错的;
  2. 通过教学视频。教学视频的优点就像在学校上课一样,跟着老师的思路走,并且全程都是实战的操作演示,学习者可以跟着老师一步一步练习,视频也可以随时暂停或者重复观看重点,完全解决了书籍学习的缺点。我接触过比较专业,讲的最细致的教程可以推荐一个网站https://www.paws3d.com/learn/,里面有免费的学习课程,也有收费的高阶课程,花几百块钱就能从入门到精通。不光是包含教程,还有一对一的线上服务,可以随时答疑。
  3. 通过教育培训机构。去培训机构培训虽然提供最全面的服务,但是动辄几万元的昂贵价格就让不少学习者止步。而且需要到专门的地方,拿出专门的几个月时间去学习。所以在此我就不对介绍打广告了。

综上所述,最好最快最经济的快速入门Unity3D的方法还是第二种通过教学视频的学习。它能互补其他两种方式抽象和价格高昂的缺点。每天拿出自己合适的时间,就可以快速从入门到精通,并且找到适合自己的Unity3D相关的工作。

2018-05-23 16:17:39 weixin_41101885 阅读数 10255
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4633 人正在学习 去看看 张刚

最近刚刚开始接触unity3d,因此想把自己的学习路线记录下来,方便自己以后总结。

由于毕业论文的关系,需要使用Unity3D开发,做虚拟现实的应用,使用的设备是HTC vive pro产品。

初始学习,由于没有基础,因此一团乱,总结一下目前看过的教程和书籍。

1、开始看的是b站上极客学院讲解的unity3d的入门课程,对操作的界面有了初步的了解,不需要看完,看到编程之前就可以。

2、由于需要使用C#编程,因此需要一点C#的基础,看的是siki学院老师上传到百度云的视频资料,讲解的十分基础,适合我这种还没写过代码的小白。

3、在有了一定的编程基础以后,就需要对Unity里的API接口有一定的了解,看的是SIKI学院的API入门教程,老师把一些基础的接口都进行了总结和讲解,免费的

4、官网有较为详细的教程,siki学院没有讲解过的知识,而且自己需要的通过官方的教程进行了进一步的了解。

5、并不是做广告,自己在图书馆找了很多的关于VR的书,感觉适合自己的是《HTC vive VR 游戏开发实战》,根据里边的例子做一下,可以有很好的提升,前边提到的siki学院就是通过这本书了解到的。

6、对于自己想知道的模块,Unity的官方文档有很详细的介绍。但是如果没有老师带领入门的话,初始还是很难看懂的,因此需要前边的铺垫。注意的是:如果自己的英语水平还是可以的话,最好是看英文的介绍文档,不懂的用有道词典查一下,这样做的好处是看Unity软件的时候更加的方便,毕竟软件目前还是英文的,自己写代码也是用英文的,看翻译过来的就不太方便转换思维。

总结,通过以上的尝试,有了一个对软件的基础的了解,接下来便是根据自己的项目进行进一步的针对性的尝试,后续会进行持续的记录。

2016-12-16 16:23:43 u011490813 阅读数 5751
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4633 人正在学习 去看看 张刚

最近对Unity3d进行学习的过程中,发现unity不仅入门教程做的丰富,而且Script API文档也是看过的所有API文档中最清晰易用的。不得不说,这极大降低了入门unity3d的门槛。

Unity3d入门学习资料  

    Unity3d的学习首先从官方tutorials入手,如图1所示。



     Tutorial中最经典的demo便是Roll-A-Ball,直接看英文的视频讲解各种术语听起来有点头晕,有些东西也讲得太啰嗦。不过没关系,下面的这个unity圣典的中文教程绝对能满足你对unity开发入门的基本需求,作者逻辑清晰,讲解细致,不得不说入门视频首选:Unity5.2入门课程 - 进入Unity开发的奇幻世界

    每个tutorial中配套有相关的开发视频,并且能找到相关demo源码。在对unity3d的界面视窗和基本操作,以及对SceneGameObjectcomponent有基本了解之后,从demo源码入手学习是最快的,很容易加深对unity3d工程的理解,以及对Script API document的熟悉。


Unity3d和Android的类比学习

    由于许多人有Android开发经验,Android与unity3d两者在设计上有诸多相似之处,下面以Android的角度来与unity3d进行类比学习,以加深对相关概念的理解。

一、坐标系:




    Unity3d的三维坐标系,再加上不同的参考基准,相比Android的二维坐标系要复杂很多:

    1.在处理GameObjecttransform相关属性,如positionrotationscale时,假如直接用 鼠标放缩移动工具,三维坐标系拖动起来太难控制了。最方便精准的控制方式为两种:第一种是直接设定属性值;第二种便是shift+点击单个坐标轴,将三维坐标转到两位坐标进行控制。

    2.另外针对不同参考基准,unity坐标系划分为几种:

    1)世界坐标系:以描述所有场景内所有物体作为基准

    2) 局部坐标系:GameObject之间在位置上可构成父子关系,以父GameObject为基准

    3) 相机坐标系:相机是最终Game视角的真正观察者,以相机为基准,观察整个场景中    GameObject的立体位置前后和遮挡关系。

   4) 屏幕坐标系:很简单,就是把屏幕当作二维坐标,描述像素在屏幕中的位置。

    其中Transform提供了各坐标系相互转换的接口。

    3.向量和矩阵运算

    二维空间中,单纯对xy坐标进行操作,书写容易。但三维空间,向量和矩阵的运算形式的简洁性和高效性便体现出来。向量主要用于坐标轴的控制,矩阵对阵列数据的放缩、旋转和平移,以前学的《矩阵分析》理论便派上用场啦。 

二、界面布局和控件的ID引用

 

下面从unity3dGameObject引用和GameObject中的组件引用分别进行叙述。

1.unity3dGameObject引用

    在界面布局元素中,Android叫控件,unity3dGameObject(游戏对象)。Android的的布局文件中定义了所需要的控件,在Java代码中通过查找id(findViewById)进行引用和控制。

    Unity3d的布局定义在scene文件中,并且在Hierarchy窗口中展现了所有GameObject列表。GameObject通过在inspector窗口中添加脚本组件来实现具体的逻辑控制。假如脚本中要对另外一个GameObject进行控制,比如roll-a-ball游戏中,球撞完所有立方体之后,需要触发一个文本UI的显示,显示为“You win!”,就需要球所在的游戏对象Player的脚本类中定义一个public变量: 

 public GUIText winText;

    随后在playerinspector面板中指定wintext对应的 GUI text对象,如图2所示。便可在脚本代码中实现修改GUIText对象的显示逻辑:winText.text = “You win!”     


    随后在playerinspector面板中指定wintext对应的 GUI text对象,如图2所示。便可在脚本代码中实现修改GUIText对象的显示逻辑:winText.text = “You win!”     

2

   另一种引用的方法是设置为GameObject设置tag,通过GameObject.FindWithTag("tag")获取到需要引用的GameObject。下一段内容中会对此方法进行介绍。

2.引用其他GameObjectComponent(组件)

    假如一个脚本组件想调用另一个GameObject的脚本组件中的public方法,怎么办呢?这种应用场景出现在roll-a-ball游戏中的球体撞击到立方体时,立方体需要调用球体绑定的脚本中的addScore函数,对分数显示GUI Text进行修改,实时更新分数。

    绑定到GameObject的脚本组件,本身是一个类文件,随着Scene的周期开始和结束,创建和销毁自己的实例。在整个内存空间中,应该是属于单例的,但实际上并不写成单例模式,那怎么获取其中的实例对象呢?

    其实原理很简单,直接通过GameObject来获取其绑定的脚本即可,下面便是具体方法:

    1) GameObject设置tag,一个tag便能分类一个或一类的GameObject,名字可以自定义,如图3所示。

3

       2) 随后在脚本中通过tag获取到具体的GameObject

     GameObject gameControllerObject = GameObject.FindWithTag("pickup");
     if (gameControllerObject != null)
     {
         gameController = gameControllerObject.GetComponent <GameController>();
     } else {
         Debug.LogError("Cannot find 'GameController' script", transform);
     }

    3) 从步骤中获取的GameObject实例,获取其脚本组件,并对其Public方法进行调用:

   PlayController gameController;
   gameController = gameControllerObject.GetComponent <PlayController >();
   gameController.AddScore(scoreValue);

  三、生命周期

    AndroidServiceActivity都有自己的生命周期,也直接决定了不同函数的调用顺序。unity也是如此,unity脚本有自己固定的生命周期函数,常见函数如下:

   执行顺序为:awake>start>update

   更多函数的执行顺序如图4所示,欲知更多可参考这篇文章:Unity3D中自带事件函数的执行顺序

                                                 图4

四、界面跳转

    Android一个完整的界面称之为Activity,通过startActivity来启动一个新的Activity实现跳转。但在Unity中称之为Scene(场景或关卡),假如只有一个scene,直接切换相机视角便可实现画面变化。但是如何实现不同scene的切换和跳转呢?

    在Scenes文件夹中创建不同的scene文件,File->Build Settings,可以看到图5界面。若创建的scene无法展现出来,首先确保scene文件是有内容的,然后点击“Add Open Scenes”,就可以实时加载进来。

                                            图5

    每一个scene文件都会对应一个level,要跳转到某个scene有两种方法:scene文件名和index level。下面是实现不同scene文件循环跳转的方法:

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class SwitchScence : MonoBehaviour {
    public int scence_level;
    private int delay_cnt = 0;
       // Use this for initialization
       void Start () {
       }    
       // Update is called once per frame
       void Update () {
        delay_cnt ++;
        if (delay_cnt == 100) {
            SceneManager.LoadScene(scence_level);
            delay_cnt = 0;
        }       
    }
}

     在Unity5.3中只要调用:SceneManager.LoadScene(scence_level),便可跳转到指定levelscene









2017-01-06 11:22:19 zzlyw 阅读数 10351
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4633 人正在学习 去看看 张刚

《Unity3D入门教程》会带领零基础的初学者,一步步学会使用Unity3D来开发简单的应用程序,走近游戏开发的世界。本系列教程虽然不会面面俱到地深入到全部的知识点,但是会涉及到所有入门阶段所需要掌握的必备技能。通过本教程的学习,可以快速“入门”。师傅领进门,修行在个人。当我们掌握了基本的框架和技能后,就可以自由选择自己喜欢的点去深入学习。本教程是博主自己学习Unity3D时候总结的学习笔记,基本能够涵盖住入门阶段所需要学习的点。希望能都对读者有哪怕那么一点点的帮助,也不枉敲了那么久的键盘,码了那么些字。Enjoy Unity3D!


------------------------------------------------------------------------------------------------------------------

1 Unity3D介绍

Unity3D是一个跨平台的游戏开发引擎,它能够帮助开发者快速构建游戏场景,进行游戏开发与发布。它支持将开发好的作品发布到Windows、Mac OS、Android、iOS、Linux等多种平台。另外,Unity3D官方版本目前可以运行在Windows和Mac OS上,当然还有可以运行在Linux上的非官方版本。


打开Unity3D官网,可以开到如下的画面,可见Unity3D的主要目标还是集中在游戏开发上,也包含VR/AR的开发。


2 Unity3D下载与安装

https://store.unity.com/cn/?_ga=1.18936120.1875984010.1467707827

打开上面Unity商店网址,会看到如下的界面。


选择免费的个人版,点击进入。


可以直接点击下载安装程序,也可以点击底部最右侧的“Unity旧版本”。我一般会选择后者,因为这样就可以自由选择要安装的版本。开发中最好采用一样的版本,否则在打开别的程序的时候总会根据Unity版本重新生成工程,来回转换难免不会出现什么隐含的Bug。点击“Unity旧版本”后,实际上看到的列表中也包含最新的版本。


根据你的系统选择相应的版本下载即可。例如我的是Win10 64位,我就点击5.4.1的“下载(Win)”按钮,选择Unity编辑器(64位)下载。我没有选择最新的版本,因为我已经有其他的程序是使用这个版本编辑的。如果你喜欢最新版,完全可以下载最新版,都是没问题的。

之后在你的下载目录会有“UnitySetup64-5.4.1f1.exe”这个文件,双击运行。一路点继续,到安装路径的页面可以更改安装路径,其他都默认即可。安装完后,如果没有使用破解补丁破解,界面是灰白色的,破解后是深灰色的。其实使用功能上没什么区别,反正现在有了免费的个人版,对于我们做研究来说,破解与否没差别。


第一次打开Unity可能需要登陆账号,可以随便注册一个登陆即可。点击“NEW”,输入工程名和路径,点击“Create project”。


至此,表示软件安装成功,可以正常运行了。

3 程序打包发布

按Ctrl+S,保存当前场景,可以命名为MyScene。之后在Project中的Assets下就会有已经保存的场景。然后File——Build Settings,出现下面的面板


点击“Add Open Scenes”就能将当前场景添加到待生成的列表里,然后左下方的平台就选择“PC, Mac & Linux Standalone”,然后点击Build。然后会要求你选择发布程序的路径和输入名称。如果和我一样选择默认路径,发布程序名称为“test”那么会在工程目录下看到发布出的程序。


双击test.exe,会出现如下对话框:


将分辨率设置为640*480,勾选Windowed,点击Play,就会看到如下场景:


好了,现在我们已经成功发布了一款应用程序。尽管这个程序什么功能都没有,但是它仍然是我们使用Unity3D成功发布的第一个应用程序,具有非凡纪念意义。它表明我们已经走在Unity3D开发之路上了。


Unity 3D 入门 介绍

博文 来自: han1202012

unity 3D入门

阅读数 759

没有更多推荐了,返回首页