• 一个手把手教你怎么做2.5D游戏的过程,讲的很清楚,完全适合初学者或者想了解这方面的人
  • Unity2.5D效果探究

    2018-11-26 17:59:06
    2.5D可能并不是一个很精准的词,我这里所指的是DNF这种可以在3个轴向上运动的2D精灵类型的效果。 以DNF为例,精灵实际上没有Z轴坐标的,当按↑,人物向屏幕里(远离玩家)方向移动时(z轴),在渲染上,我们看到...

    2.5D可能并不是一个很精准的词,我这里所指的是DNF这种可以在3个轴向上运动的2D精灵类型的效果。

    以DNF为例,精灵实际上没有Z轴坐标的,当按↑,人物向屏幕里(远离玩家)方向移动时(z轴),在渲染上,我们看到人物是在向上移动。而我们按c,人物跳起(y轴),我们仍然看到人物在向上移动。这就是DNF类游戏看起来有点3d效果的奥秘:它营造一种我们在斜向下45度(或者其它角度)观看地面的感觉,因此当人物坐标在Z轴移动时,在屏幕投影位置上我们看到人物向上或向下移动。

    所以,这种效果可以通过3维坐标在渲染时的一个变换来完成。

    设点A(x1,y1,z1),那么它渲染时的世界坐标会变换为:

    x2 = x1,

    y2 = y1*cos(a)+z1*cos(90-a)

    z2 = 0

    其中a代表视线与xz平面的夹角,不过一般Y轴不计算投影,因为要保持精灵的正常显示,不能让它因斜视而变矮。

    因此,y2 = y1 + z1*cos(90-a)

    最开始,我打算了unity中为一个物体建立两个gameobject,一个物体赋值3维坐标,因为它处于真实位置,因此可直接使用物理系统,另一个物体用上面的映射方法,计算出坐标并使用它来表示精灵的位置,SpriteRenderer附加在第二个物体上。我确实这样实现了,也运行正常。

    不过后面我想到,可以用shader来更改显示位置,这样只用一个gameobject,用普通Sprite即可,比较符合直觉,也便于使用。下面先看下效果:

    45度角:

    yangxun983323204

    这样好处在于,物体的transform和boxcollider仍然是在正常的3D空间中的,所以碰撞检测可以完全以我们熟悉的3D物理组件来完成,而不需要自己实现。

    另外,对于要做小游戏的程序员来说,2D游戏对素材要求会小一些。。用此方式,表现力会比用单纯的2d精灵和2d物理好很多。

    附上shader,用精灵的默认shader改的:

    Shader "Sprites/YX2.5D"
    {
    	Properties
    	{
    		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    		_Color ("Tint", Color) = (1,1,1,1)
    		[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    		[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
    		[HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
    		[PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
    		[PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
    		[HideInInspector] ZFactor ("Z-Factor",float) = 0.707
    		[HideInInspector] WOrigin ("Origin",Vector) = (0,0,0,0)
    	}
    
    	SubShader
    	{
    		Tags
    		{ 
    			"Queue"="Transparent" 
    			"IgnoreProjector"="True" 
    			"RenderType"="Transparent" 
    			"PreviewType"="Plane"
    			"CanUseSpriteAtlas"="True"
    		}
    
    		Cull Off
    		Lighting Off
    		ZWrite Off
    		Blend One OneMinusSrcAlpha
    
    		Pass
    		{
    		CGPROGRAM
    			#pragma vertex SpriteVert
    			#pragma fragment SpriteFrag
    			#pragma target 2.0
    			#pragma multi_compile_instancing
    			#pragma multi_compile _ PIXELSNAP_ON
    			#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    			#include "UnityCG.cginc"
    			
    			#ifdef UNITY_INSTANCING_ENABLED
    
    				UNITY_INSTANCING_CBUFFER_START(PerDrawSprite)
    					// SpriteRenderer.Color while Non-Batched/Instanced.
    					fixed4 unity_SpriteRendererColorArray[UNITY_INSTANCED_ARRAY_SIZE];
    					// this could be smaller but that's how bit each entry is regardless of type
    					float4 unity_SpriteFlipArray[UNITY_INSTANCED_ARRAY_SIZE];
    				UNITY_INSTANCING_CBUFFER_END
    
    				#define _RendererColor unity_SpriteRendererColorArray[unity_InstanceID]
    				#define _Flip unity_SpriteFlipArray[unity_InstanceID]
    
    			#endif // instancing
    
    			CBUFFER_START(UnityPerDrawSprite)
    			#ifndef UNITY_INSTANCING_ENABLED
    				fixed4 _RendererColor;
    				float4 _Flip;
    			#endif
    				float _EnableExternalAlpha;
    			CBUFFER_END
    
    			// Material Color.
    			fixed4 _Color;
    			float4 WOrigin;
    			float ZFactor;
    			float YFactor;
    
    			struct appdata_t
    			{
    				float4 vertex   : POSITION;
    				float4 color    : COLOR;
    				float2 texcoord : TEXCOORD0;
    				UNITY_VERTEX_INPUT_INSTANCE_ID
    			};
    
    			struct v2f
    			{
    				float4 vertex   : SV_POSITION;
    				fixed4 color    : COLOR;
    				float2 texcoord : TEXCOORD0;
    				UNITY_VERTEX_OUTPUT_STEREO
    			};
    
    			v2f SpriteVert(appdata_t IN)
    			{
    				v2f OUT;
    
    				UNITY_SETUP_INSTANCE_ID (IN);
    				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
    
    			#ifdef UNITY_INSTANCING_ENABLED
    				IN.vertex.xy *= _Flip.xy;
    			#endif
    				float4 wpos = mul(unity_ObjectToWorld, IN.vertex)-WOrigin;
    				float4 wposMap = float4(wpos.x,wpos.y + wpos.z*ZFactor,0,wpos.w); 
    				OUT.vertex = mul(UNITY_MATRIX_VP,wposMap);
    				OUT.texcoord = IN.texcoord;
    				OUT.color = IN.color * _Color * _RendererColor;
    
    				#ifdef PIXELSNAP_ON
    				OUT.vertex = UnityPixelSnap (OUT.vertex);
    				#endif
    
    				return OUT;
    			}
    
    			sampler2D _MainTex;
    			sampler2D _AlphaTex;
    
    			fixed4 SampleSpriteTexture (float2 uv)
    			{
    				fixed4 color = tex2D (_MainTex, uv);
    
    			#if ETC1_EXTERNAL_ALPHA
    				fixed4 alpha = tex2D (_AlphaTex, uv);
    				color.a = lerp (color.a, alpha.r, _EnableExternalAlpha);
    			#endif
    
    				return color;
    			}
    
    			fixed4 SpriteFrag(v2f IN) : SV_Target
    			{
    				fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
    				c.rgb *= c.a;
    				return c;
    			}
    		ENDCG
    		}
    	}
    }

    使用方法为,创建一个材质,使用上面提供的shader,默认就是45度角的效果。然后SpriteRender使用该材质。

    为了方便起见,还写了一个c#脚本,方便视角、原点等参数设置,但它不是必须的:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Sprite25D : MonoBehaviour {
    
        public Vector3 Origin;
        public float Angle = 45;
        private new SpriteRenderer renderer;
        
    
        private void OnEnable()
        {
            Apply();
        }
    
        public void Apply()
        {
            if (renderer == null)
            {
                renderer = GetComponent<SpriteRenderer>();
            }
            Material mat;
            if (Application.isPlaying)
                mat = renderer.material;
            else
                mat = renderer.sharedMaterial;
            mat.SetVector("WOrigin", Origin);
            mat.SetFloat("ZFactor", Mathf.Sin(Angle * Mathf.Deg2Rad));
        }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    
    [CustomEditor(typeof(Sprite25D))]
    public class Sprite25DInspector : Editor
    {
    
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            GUILayout.Label("以下操作会修改sharedMaterial");
            if (GUILayout.Button("设置当前位置为映射原点"))
            {
                var inst = (target as Sprite25D);
                var pos = inst.transform.position;
                inst.Origin = new Vector3(pos.x, pos.y, pos.z);
                inst.Apply();
            }
            if (GUILayout.Button("重置原点为zero"))
            {
                var inst = (target as Sprite25D);
                inst.Origin = Vector3.zero;
                inst.Apply();
            }
        }
    }
    

    就是这样了

    展开全文
  • 所谓 2.5D 游戏,就是利用技术手段让 2D 精灵图片呈现 3D 视觉效果。今天这篇文章,将由 2.5D 游戏《A Place for the Unwilling》开发者 Martín Pane,为大家分享在 Unity 5 中实现游戏场景中各精灵层级规划与遮挡...

    所谓 2.5D 游戏,就是利用技术手段让 2D 精灵图片呈现 3D 视觉效果。今天这篇文章,将由 2.5D 游戏《A Place for the Unwilling》开发者 Martín Pane,为大家分享在 Unity 5 中实现游戏场景中各精灵层级规划与遮挡的过程。

    开发《A Place for the Unwilling》游戏第一部要解决的问题就是让精灵可以围绕其它精灵前后移动,呈现出真实的深度感觉。SpriteRenderer 组件有两个属性,可以改变场景中 Sprite 的渲染顺序。

    • Sorting Layer
      用于设置不同层的 Sprite 渲染顺序
    • Order in Layer
      用于设置在同一层中的 Sprite 渲染顺序

    如果想实时改变多个 Sprite 的渲染顺序,就需要修改一些属性以便无论精灵在场景中如何移动,均以正确的顺序渲染。由于“Oder in Layer”属性仅接受整型参数,所以利用 Z 轴似乎是个更好的选择。

    Unity 中 Sprite 的渲染优先级如下图,从高到低:

    如果两个 Sprite 的“Sorting Layer”和“Order in Layer”均相同,那么在 3D 世界坐标中离相机更近的 Sprite 会被先渲染。

    在明白了 Sprite 的渲染顺序后,接下来只要写个简单的脚本更改 Sprite 坐标的 Z 值为与其 Y 值成固定比例即可。但在此之前,先来解释一个重要的小概念,即如何设置精灵位于地面的底部。这里“底部”就是指 3D 世界中对象与地面接触的部分,示例如下:

    我们要做的是在改变 Sprite 坐标 Y 值的同时改变其 Z 值,上图在 3D 环境的效果如下图:

    理解了以上内容,就可以写脚本了,代码如下:

    首先需要设置的是“Floor Height”,该属性决定 Sprite 的下边界在 Y 方向的偏移。 在 3D 世界坐标中,它用于设置 Sprite 在场景中的 Z 深度。 如果一个 Sprite 的底部比其它 Sprite 更高,它将被渲染在其它 Sprite 后面。

    然后存储 Sprite 高度与宽度的半值,以便对 Z 坐标进行一些简单的数学运算。在《A Place for the Unwilling》游戏中使用了 30 度的等距切角,但您也可以将 Z 坐标设为与 Y 坐标一致,不影响游戏效果。

    这里使用 OnDrawGizmos 方法在当前的地面高度绘制一条线,以便可以在编辑器中设置为最终的精确位置。另外,对于有些游戏运行后永远不会移动的对象,可以使用“if(!Application.isPlaying)”和“#if UNITY_EDITOR”条件在运行时保存计算结果,因为可能会有上百个 Sprite 同时绑定该脚本。

    以上设置完成后,就可以在场景中移动 Sprite 并保证渲染顺序正常了,但还有两种情况需要更多的设置。

    在处理中心不在中间位置的 Sprite 时,需要将其分为几部分。以下面的建筑为例,由于它的底部是矩形,如果整个建筑仅设置一个 Floor Height 值,那角色将只能沿着它前方的那面行走,并且会遮挡角色!为了解决这个问题,就需要将建筑 Sprite 分为两个部分,并为每一边设置不同的地面,如下图:

    另一种情况是将某个 Sprite 作为另一个的子对象时。仍然以建筑为例,如果想为建筑增加窗户或招牌,这些附加物就不能使用与建筑相同的脚本,因为有些窗户可能位于建筑后面或顶部。这个问题很容易解决,只需创建建筑的子对象重置其坐标,并将 Z 值设为 -0.001,然后将所有需要附着在建筑上物体放置于该子对象下,将这些物体的 Z 坐标设为 0,这样就可以与实际建筑保持 0.001 的距离,并且它们离相机更近。

    最终 3D 环境下的完整场景如下:

    Unity 引擎本身就已经提供了非常灵活的工具来实现这样的功能,下面来看看这种实现方式存在的一些限制,以及一些有助于改进工作流程的扩展方法。

    这种实现方式最大的限制就是制作很薄的墙壁时,因为使用该方法必须将 Sprite 切割为多个与墙壁厚度一致的部分,以便场景中的物体可以在墙壁前后移动。示例如下:

    对于飞行物来说可能也比较麻烦,但如果注意其摆放的位置就可以避免出现问题。还可以通过修改 Sorting Layer 的值让它们永远位于场景主要对象的前方或后方。

    最后分享一下如何扩展这种方式以适用更多的场景。Isometric Colliders: 根据角色在游戏中的移动方式,实现一个小脚本为角色创建一个与游戏场景的图片摆放角度一致的碰撞体。

    IsoVector 类:该类包含一些常用的方向向量(N,W,E,S,NE,NW,SE,SW),以及从自定义方向获取向量(反之亦然)的方法,或者获取给定方向的反向向量(例如输入南获取北)等。

    本文介绍的内容不一定是最佳的解决方案,但也展现出了很好的学习思路,从最开始想到编写脚本调整 Sprite 的 Z 值来正确渲染一切对象,解决了一开始构建游戏场景的问题。随着继续扩展代码库,也丰富了一些自定义类来加入新功能,同时维护好项目结构。希望这篇文章对正在使用 Unity 开发这种等距游戏的开发者有帮助。


    Unite 2017 Shanghai 即将于5月11-13日在上海国际会议中心举行!目前5折个人通票已经开售,三人团购还可享受8折优惠!技术专场内容抢先看!更多信息请访问 Unite 2017 Shanghai 官方网站。

    展开全文
  • 2.5D游戏地图场景大图

    2020-06-23 14:16:41
    网上找到的地图素材,换点积分……纯2.5D素材,请各位收下
  • 如果你不了解2.5D游戏是什么,它基本上是个3D游戏而你可以想象是压扁的,所以游戏是只是沿着2D轴。 一些好的例子是:Super Mario Brothers Wii,Little Big Planet, orPaper Monsters. 一个很好的方法去做2...

    最近在研究Unity 3D,看了老外Marin Todorov写的教程很详细,就翻译过来以便自己参考,翻译不好的地方请多包涵。

    如果你不了解2.5D游戏是什么,它基本上是个3D游戏而你可以想象是压扁的,所以游戏是只是沿着2D轴。

    一些好的例子是:Super Mario Brothers WiiLittle Big Planet, or Paper Monsters.

    一个很好的方法去做2.5D游戏或者3D游戏,是通过一个流行,简单和价格实惠的游戏开发工具叫做Unity。

    所以在这个教程系列里面,我打算让你看到怎么使用Unity去创作一个简单的2.5D游戏叫做“Shark Bomber!”

    教程目标:

    如果你是刚开始接触Unity,但喜欢学习它,这个教程就针对你。你可以从头开始一步一步学到怎么去创作一个简单的游戏。

    在这个游戏中,你可以控制一个小的但是全副武装的飞机,你的工作是去轰炸邪恶的鲨鱼,保护那些可爱的小丑鱼。

    Unity 不使用 Objective-c,所以对与这个教程,你不必具备任何Objective-C 经验。然而有面向对象语言的经验是加分的,理想的是 C#,Java,or Actionscript.

    请记住,这个是一个Mac环境下开发的用户教程,windows用户可能无法精确找到相关设置。所以,请记住,你将只能在ios设备上做测试而不是模拟器。所以一定确保你有一个ios设备。

    OK,让我们潜入Unity,但是确保避免那些鲨鱼!

    安装 Unity

    首先让我们安装这个Unity 工具,如果你已经在你的mac下安装了就可以跳过此步。

    可以参考之前写过的博客的前半部分:

    http://www.cnblogs.com/jiangshiyong/archive/2012/06/20/2555731.html

    重要提示:本教程中,您需要选择“Start Pro / iOS Trial”选项,这样你就可以发布到AppleStore(而不是简单的“免费”选项!),或者在破解下只能学习使用,不能发布到AppleStore。

    注册完成后,Unity启动,你应该看到一个窗口,看起来像这样:

     

    关闭“Welcome to Unity”弹出框,去到File>New Project,选择一个磁盘上的某个文件夹并命名项目SharkBomber。确保所有的包都取消选中,然后单击“创建项目。


    现在你面对一块空白的面板。哇,有很多的按钮,是吧?不要担心 - 在下一节中,我们会一点一点去了解它们。

    1.Unity 编译器 介绍:

    让我们做一些额外设置,从一个已知配置里面得到一些东西。

    在应用程序窗口顶部的右上角你会发现一个选择框Layouts,从列表中选择“Tall”.这将重新排列窗口的内容(默认是"Wide"仅供参考)。

    现在找到左上角的栏(及在工具栏的下方),叫“Game”,拖动它到底部窗口附近直到你看到它将扑捉到底部的迹象,就把它拖到那吧。

     

     现在你应该看到下方图片上的布局:

     让我们快速过一下这些不同的面板:

    1.Scene:在这里你可以到处移动你的3D模型,可以浏览你的3D世界。

    2.Game:这就是你所选的摄像机(主摄像头)看到的实时画面直到你使用编译器。以及当你点击“Run”时

    你的游戏运行,你可以测试你的游戏。

    3.Hierarchy:你的对象树(例如很像HTML DOM),目前你只有一个摄像头,但我们之后会添加一些东西。列表中的对象目前在现场。

    4.Project:这是你项目中的内容,你的资产,音频文件,一切你现在或以后将要使用到的内容。

    5.Inspector:这里你可以看到在场景中所有选定的属性,你可以调整它们。Unity的独特之处是,当你运行你的场景时候,Inspector是活动的,所以它也是你的调试工具。

    6.Toolbar:这里,你有这些工具来交互在你的场景中的对象,运行和暂停按钮来测试你的场景,

     在你的Unity3D项目中,你可以有许多不同的场景,你可以在它们之间进行切换。目前,你有一个空的场景在编译器中打开,让我们把它保存下来。

       1.在Project面板中单击右键,选择“Create>Folder”- 一个新的文件夹出现了。

       2.把它重命名为“Scenes”- 你可以通过左键单击文件夹名称或通过选择文件夹然后按下“Enter”键。

       3.现在,你在主菜单上选择“File/Save scene”-导航保存对话框到【你的项目目录】/Assets/Scenes下

         把这个场景命名为“LevelScene”.

     OK - 完成。让我们来看看 - 在Project面板中打开Scenes文件夹 - 有你的LevelScene场景。爽!

     现在,我们开始准备运行游戏-点击上面的Play按钮!没有太大变化-但事实上你的游戏已经在Game面板中运行了!不要忘记停止该游戏,再次点击Play按钮(这一点很重要!)。

     2.设置一个iPhone Unity3D的项目

    关于Unity的优点之一是它可以为iPhone ,Mac,Wii和其它平台开发游戏。在本教程中,我们将建立一个iPhone游戏,所以我们需要先设定一些细节。

    从菜单栏中,选择“File>Build Settings”,然后点击“Add current”按钮来为你的项目添加目前所选的场景。添加后你可以看到它得到一个序列为0的编号,这意味着它是游戏开始时第一个要加载加载的场景。这正是我们想要的。

    从Platform列表中选择IOS,然后点击“Switch platform”按钮。Unity 的logo现在就出现在Ios一行上。

     这是我们所需要的所有设置,单击“Player settings”,然后关闭这个弹出窗口。你会注意到这个Player setting 在Inspector面板中打开,我们也需要在这里设置几项事情。

    在Inspector面板下的这个“Per-Platform Settings”,确保选择卡中显示一个 iPhone图标选中,如下:

     

    这里有很多设置,你从Xcode中了解过它们中的大部分,所以你一会可以自己探索和玩。

    现在使用这个Inspector进行以下更改:

        1.在这“Resolution and Presentation”项下,“Default orientation”(默认方向)选择“Landscape Left”。

      2.在这“Other settings”项下,“Bundle Identifier” 输入框中填入你想填任意内容(除了给出的默认内容)。

        3.在这“Other setings”项下,设置“Target Device” 为  “iPhone only”。

    最后一触摸:在左下方,这个“Game”标签下,你有不同的方向/决议去选,-选择“iPhone Wide(480*320)”来匹配默认的横向布局。

    如图,红线圈住的就是这些设置:

     

     

    恭喜,你现在有了一个基于“Hello World”的项目,你可以尝试在你的iPhone上运行。

     

    3.在你的iPhone上运行游戏

     为了测试到现在为止我们所做的一切,我们打算在Xcode和你的iPhone上完成测试这个项目。

    启动你最喜爱的Xcode版本 - 关闭欢迎界面如果有一键切换回Unity.这是一招Unity如何分辨

    用哪个Xcode版本,-只需要运行它。

     回到Unity,从菜单栏中选择“File>Build&Run”,这将再次弹出这个Build Settings,点击“Bulid

     and Run”按钮。

     你会问你在哪里保存你的Xcode项目。在你的项目目录里面创建一个名为“SharkBomberXcode”文件夹,

    (这是你Xcode的东西驻留的地方),作为一个文件名放在“SharkBomber”.

     

    过几分钟后这个项目被编译,你将有一个Xcode窗口打开的叫做 Unity-iPhone的项目。Unity已经生成了

    Xcode项目源代码,你现在可以把这个生成的项目通过Xcode编译和运行。

    你可能想看看源代码 - 但它实际上是一个导入一些框架的样板,包括一些dll 文件和一些assets(资源文件)

    ,所以没有太多你可以玩的。

    你有两个目的,所以确保你的ios 设备是插入的,并且选择“Unity-iPhone” target和你的设备。(我不能

    在模拟器上运行,如果你够伟大,但现在我只能连上真机运行),

    梦想成真 -点击Run 按钮,你的Unity 项目现在运行在你的iPhone上。

    干得好,你可以看到Unity的默认启动画面,并且蓝色背景的场景一角有些字“trial version(试用版)”。

    停止运行任务,切换回Unity,并且保存你的项目。

    4.设置场景

    首先让我们在scene上设置主摄像头。在“Hierarchy”面板中选择“Main Camera”,在Inspector面板中找到

    “Projection” 并把它设置成 “Orthographic(正楷)”,  "Size" 设置成“10”,在"Clipping Planes " 设置“Near” 为“0.5”,“Far”为“22”。现在你在这个scene里面看到在你的摄像机旁边有个盒子---这是个界限在这个场景上从你的角度什么将会看到。

    请注意我们已经设置相机 “Projection”(投影)为“Orthographic” (正面),这意味着深度坐标不会影响怎么观看在屏幕上观看东西--我们将有效地创建一个2D游戏。一会让我们做一些工作知道你熟悉Unity,然后我们将切换到3D投影。

     设置你的相机Position(位置)(在Inspector面板上)x,y,z轴为【0,0,0】,注意从现在开始,当我写Position(位置)为[x, y , z]时,就是设置这三个属性的值。

    在这个Project 面板中单击右键,然后选择“Create/Folder”,场景新文件夹“Textures”.然后下载这个背景图片

    http://cdn5.raywenderlich.com/downloads/background.png

    我已经把它跟其它一起放在游戏项目中。下载图片后,拖拽这个背景图到你刚刚创建的“Textures” 文件夹中,

    完成之后, 选中文件夹“Textures”下的“background” texture,并在左边的“Inspector”面板中观察这个纹理

    (texture)的属性:在底部Preview面板中会看到“RGB Compressed PVRTC 4bits.”,所以Unity 发现了我们

    导入的纹理(图片)并把它进行了压缩。

     

     从菜单栏选择“GameObject\Create other\Plane”,你会看到在摄像机旁边有一个蓝色长方形。

    这个是我们刚刚加到场景(scene)中的飞机,我们接下来应用我们已经得到的纹理。

    选中“Hieararchy”面板中的“Plane”,在“Inspector”面板中的顶部一个text filed中 的叫“Plane”输入

    “Background”. 这样操作改变这个对象的名字,这样就是让你怎样重新命名一个对象。有时候不能

    命名成功,你需要再点击下其它的文本框才行。

     把这个“background”纹理(texture)从“Project”面板中拖拽到"Hierarchy"面板中的“Background”

    对象上。在“Inspector”面板中设置这个飞机(刚才的重新命名Background)的位置(position)为

    [4, 0, 20],Rotation(旋转)为 [90, 180, 0],Scale(缩放)为[10, 1, 5],这就是你在“Scene”

    面板中面对着相机这个飞机的模型和选择,这样这个相机将看到这个飞机作为游戏的背景。

     

     

     现在,为了清楚地看到我们所拥有的场景,我们需要一些光(就像在现实生活中),在菜单栏中选择

     “GameObject\Create other\Directional Light”,这将会发一些光在你的场景中。在“Hierarchy”

    面板中选择“Directional Light”,并在“Inspector”属性面板中设置Position位置坐标为【0,0,0】.

    现在我们有了所有的设置和场景的背景,现在是时候添加一些对象并让它们动起来!

    5.添加3D对象到场景(Scene)

     从菜单栏中选择“GameObject\Create other\Cube” ,这样添加一个立方体到你的场景中。这将是这个游戏

    的玩家,所以将它重名为“Player”.设置位置为【-15,5.3,8】.你将会看到这个立方体出现在“Game”面板的屏幕

    中的左侧--这也是我们的飞机开始启动的地方,并且将要在海面上移动到达屏幕的另一端。

     

     现在让我们导入飞机模型!我们将使用免费的3D模型 ,Reiner网站上免费发布的 Reiner`s Tilesets(也看看它的模型的许可http://www.reinerstilesets.de/lizenz/)。开始,下载他的飞机模型(http://www.reinerstilesets.de/zips3d/mesh_airplane_linnen.zip)并对其进行内容进行解压缩。

     在"Project"面板里点击右键并选择"Create/Folder",重命名这个文件夹为“Models”.从你刚才解压缩的飞机模型文件夹中拖拽文件“airplane_linnen_mesh.obj”,并把它放到“Project”面板中的“Models”文件夹中。

     然后右键点击这个“Models”文件夹并选择“Create/Folder”,并重命名这个新的子文件夹为“Textures”,这里我们可以保存应用到这个模型的纹理文件。拖拽文件“airplane_linnen_tex.bmp”并把它放到最近新建的“Textures”文件夹中。

     下一步,在“Hieratchy”面板中选中这个“Player”对象,然后观看这个右上角的“Inspector”面板,

    那个"Mesh Filter"选项过滤器是条状的设置你的项目对象的几何(现在它设置一个立方体的几何形状);

    在子目录下里面有个叫“Mesh - Cube”的一行,你会发现一个点在中间的小圆圈,并点击它 ——

    这将打开一个弹出窗口,你应该双击这个飞机模型,这将改变的的几何对象为一个飞机。

      现在一个精致的细节——飞机看起来有点搞砸了。我没有3D专家,但我发现了怎样在Unity中修复它:在“Project”面板中选中“airplane_linen_mesh”,然后在"Inspector"面板中找到“Normals”选项并选择“Calculate”,然后向下滚动滑动条并点击“Apply”(应用)按钮。

      酷,现在你在场景中看到一个流畅的飞机!让我们来使用它的纹理:在你的“Project”面板中拖拽“airplane_linnen_tex”纹理文件,并把它放到“Hierarchy”面板中的“Player”. Unity 自动应用这些纹理到我们的场景中的飞机模型上。

      最后给飞机润色:为“Player”对象设置 Rotation(旋转)为 [0,90,350],Scale(缩放) 为[0.7,0.7,0.7],这将对这个飞机进行平面旋转和缩放,使它看起来像刚飞过海面。下面将要使我们飞机飞!

    6.使用C#开始Unity3D编程

     正如我们已在Unity的Build Settings 对话框中所看到,Unity 可以创建你的项目到一个 Wii game,一个iPhone game,独立的Mac game,等等。因为U,nity就是如此无所不能的中间层,你只需要一次编程你的游戏。一旦它需要某种或不同的构建就可以将它转换为特定于平台的代码。

     奇怪的是,在Unity中编程你将使用C#(而非Objective -C!),当Unity生成你的Xcode项目中时,它将C#代码自动翻译成特定于平台的代码。

      在“Project”面板中单击右键并选择“Create/Folder”,重命名这个新的文件夹为“Class”.右键点击这个“Class”文件夹并选择“Create/C Sharp Script”,并重命名新文件为“PlayerClass”. 在"Project"

    面板中单击右键并选择“Sync MonoDevelop Project” - 这将打开 MonoDevelop IDE- 只是你可以在C#下编程的IDE.

    注意:MonoDevelop是从 Linux中移植过来的程序,正如你所看到的用户界面皮肤,称为Gnome(侏儒),所以如果它不时地崩溃是正常的,尤其是当你尝试改变窗口的大小。如果出现这种情况,只需通过点击“Sync MonoDevelop Project”重新启动。

     以上是MonoDevelop GUI的三大块:

    1.浏览你的 MonoDevelop项目-在in Assets/Class目录下你将会发现 PlayerClass.cs文件。

    2.目前开源类概况。

    3.编辑区——有一些语法高亮显示和代码自动完成功能,将有助于你的编码。

    浏览你的项目找到 PlayerClass.cs文件,在编辑器中双击打开它。确认类看起来如下:

    using UnityEngine;
    using System.Collections;
    public class PlayerClass : MonoBehaviour {
     
    	// Use this for initialization
    	void Start () {
     
    	}
     
    	// Update is called once per frame
    	void Update () {
     
    	}
    }

     这个“using”条款包括库和框架,UnityEngine库给你些比如能让你访问iPhone的加速器,键盘输入和其他方便的东西之类的。

     你可以定义自己的新类并继承MonoBehaviour,它给你提供了很多免费的东西:当给定事件被触发时你可以覆盖被回调的一长串清单方法。

     只需几行在你空启动和更新方法下面 -这是2个重要的事件。

       *Start 被调用在你的对象出现在场景的适合,所以你可以进行你的初始化(类似于viewDidAppear:

        in UIController)。

      *Update 被调用在每当每帧渲染(即可能是30​​,60或100次每秒,你永远不知道多久),这里就是做你的动作,游戏逻辑等

      现在让我们却换回Unity一会。我们要使飞机飞过海,当它在场景的右侧消失后而在左侧再次出现。让我们来测量下我们需要将飞机移动到距离左边什么位置。在"Scene"面板的右上角,你会看到方向轴 Gizmo- 点击

    这个X手柄(它是一种红椎,我将管它叫手柄):

     这个将选择场景和使它水平朝向你。再次点击在这个gizmo左边的手柄--这将旋转周围的场景,你可能需要点击左侧的手柄几次,直到场景看起来像这样子:

     现在你可以使用鼠标在场景中滚动放大/缩小,并让它在“Scene”面板中适应大小。确保在上方的工具栏中的移动工具被选中,并在“Hierarchy”面板中选择这个“Player”.

     现在你看到一个新的gizmo(发明)出现,连接在飞机上一个绿色和一个红色的箭头。现在你可以拖动箭头轴,它们将使飞机沿着箭头的方向移动:

     你需要做的是点中红色箭头(横轴),并拖拽飞机到右边知道超出“Game”面板下方。

     开始在“Scene”面板中拖动,同时观看“Game”面板中的表现。把飞机停留在场景可视范围之外,并观看它在“Inspector”面板中的position(位置)。position 的X轴应该在“17.25”附近,-所以这是在场景右边的边距,你可以拖拽飞机向左移动距离左边距坐标为“-17.25”,所以我们将使用“18”和“-18”来包裹飞机的飞行。把飞机带回到原来在场景左侧的位置。

      切换回 MonoDevelop,在PlayerClass.cs文件中坐如下改变:

    //just after class declaration line
    public float speed;
     
    //inside the Update method
    if (transform.position.x > 18) {

    //get new speed
    	speed = Random.Range(8f,12f);
    	transform.position = new Vector3( -18f, transform.position.y, transform.position.z );
    }		
    transform.Translate(0, 0, speed * Time.deltaTime);

      正如你所猜想那样,你刚才在你的类中定义了一个公共类属性叫做“speed”,但是Unity的特别之处是所有的公共类属性都可通过这个“Inspector”面板访问!

      所以你可以在IDE中设置你类中属性的值,你可以监视你的属性值当游戏一边实时运行时。它是多么的酷啊!

     这个“transform”变量是针对每场游戏对象(场景中的一切都是一个游戏对象)处理对象空间位置:旋转,位置,缩放等的属性。因此每次Update的调用是为了变换这个对象的位置,一遍它移动到场景的右边。

      我们不能只是每次调用 Update时候设置变量让这个飞机移动,因为没有人知道每秒到底有多少次被实际调用。 相反,我们定义速度为每秒为单位,从上次调用更新所进过的时间分离出速度(Time.deltaTime).通过这种方式,对象总是独立于当前帧速率以相同速度移动。

     调用翻转有三个值--在每个轴上它有翻转。  你可以注意到 我们移动飞机在z轴上(第三个参数)-我们只能这么做因为我们要在场景中旋转这个飞机,所以翻转Z轴把它移动到玩家角度的右侧。

      查看"if"语句- 我们检查 如果transform.position.x大于18(为什么?)。如果如果是的话,我们将飞机的位置设置为相同的数值坐标但是“-18”在X轴。我们使用新建Vector3(x,y,z)设置坐标位置--我们将会使用大量的这些vectors为所有的定位;你注意到我们设置一个随机速度(8~12),这只是让飞机更随机的移动变得更有趣一些。

     这是我们准备看这个飞机移动!

     切换回Unity.从“Project”面板中拖动这个“PlayerClass”文件到“Hierarchy”面板上的“Player”对象上--这样你就附加一个类到一个游戏对象上。选中“Hierarchy”面板中的“Player”并观看右侧的“Inspector”面板-- 你将会在下方看到一个新的选项出现叫做“Player Class(Script)”,在那里你可以看到新的公共属性!“Speed”,为它设值“12”。

     ok ,准备好了。点击Play 按钮!你可以同时在"Scene"和“Game”面板中看到飞机飞来飞去,从右边飞出从左边飞回来。同时可以注意到在“Inspector”面板中Position的X轴也是变化的 -它向你显示在任何给定的时刻飞机在哪。当然飞机飞行的每时每刻速度都是随机变化的。

    一旦大功告成享受惬意时,不要忘记再次点击Play按钮停止这个游戏。

    需要休息吗?没问题-只需要保存你的Unity项目,你可以稍后再开启。当你带个一个Unity项目时候,它默认打开一个空的场景。为了加载你正在工作的场景- 双击在“Project”面板中的“LevelScene” -现在你可以继续工作了。

    7.跳动的鲨鱼

     下载并解压缩鲨鱼模型(http://www.reinerstilesets.de/zips3d/mesh_shark.zip)。同样,拖拽这个“shark.obj”文件到“Project”面板中的"Models"文件夹中,拖拽“sharktexture.bmp”文件到“Models/Textures”文件夹下。

     从菜单栏中选择“GameObject/Create other/Capsule” - 在“Hierarchy”面板中重命名这个“Capsule”对象为“Shark”.

    在你的“Project”面板中拖拽“sharktexture.bmp”纹理文件,并把它放到“Hierarchy”面板中的“Shark”上.在“Inspector”面板中的“Mesh Filter”一项中点击有一点在中间的圆圈,在弹出的窗口中双击这个Shark 模型。现在你应该在“Scene”和“Game”面板中看到Shark的几何形状。

     从“Project”面板中Models/Textures文件夹下拖拽“sharktexture”到“Hierarchy”面板中的“Shark”对象上- 这会给你的鲨鱼一个凶残的嘴和一对邪恶的眼睛!--我已经准备想轰炸它!

     确认“Shark”对象被选中,然我我们在"Inspector"面板中设置以下属性::Position – [20, -3, 8], Scale – [1.2, 1.2, 1.2] –这将把鲨鱼正好放到摄像机可见范围的右侧。--它将会从这里朝着场景屏幕的左端开始移动。

     

    现在我们希望这个鲨鱼与我们的炸弹相撞(通过爆炸,轰轰轰)。我们希望这个鲨鱼的对撞机或多或少的匹配这个鲨鱼的几何形状。正如你所看到的那样在场景中的鲨鱼里面有个绿色的胶囊形状(capsule).这个就是鲨鱼的对撞机(collider).让我们用它匹配这个邪恶鲨鱼的型体。

     在“Inspector”面板中找到这个“Capsule Collider” 并进行如下设置:Radius to “1″, Height to “5″, Direction “X-Axis”, Center to [0, 0, 0].现在你可以考到胶囊对撞机(capsule collider)已经旋转过并且或多或少的更加匹配鲨鱼的型体!

     

      最后,在“Project”面板中的“Models”文件夹下选中“shark”模型,然后在"Inspector"面板中找到“Normals”选项并选择“Calculate”,然后向下滚动滑动条并点击“Apply”(应用)按钮。。

      在“Project”面板中单击右键并选择“Create/Folder”,右键点击“Class”文件夹并选择“Create/C Sharp Script”,并重命名新文件为“FishClass.”. 在"Project"

    面板中单击右键并选择“Sync MonoDevelop Project”。MonoDevelop(编辑器) 就会弹出来。打开这个“FishClass.cs”文件并在里面添加如下代码:

    using UnityEngine;
    using System.Collections;
     
    public class FishClass : MonoBehaviour {
     
    	public float speed = 6f;
     
    	// Update is called once per frame
    	void Update () {
    		if (transform.position.x < -30 || transform.position.x > 30) {
    			//turn around
    			transform.Rotate(new Vector3(0,180,0));
    			transform.Translate( new Vector3(-10, -transform.position.y + Random.Range(-4,-1),0) );
     
    			//get new speed
    			speed = Random.Range(6f,10f);
    		}
    		transform.Translate( new Vector3(-speed*Time.deltaTime,0,0) );
    	}
    }


     这和我们所拥有的飞机非常相似。我们有个速度属性(单位为每秒)并在Update事件中处理我们使用transform.Translate来移动这个鲨鱼。

     注意这次我使用:

    transform.Translate( new Vector3(x,y,z) );

     这只是用来演示其中一些方法可以采用不同的参数 -然而分别通过3个值和1个矢量效果是相同的。 

      现在,让我们来看看鲨鱼当到达屏幕的范围做什么(-30~30的范围情况下,所以有一个当鲨鱼在屏幕之外的时刻时,你不能很轻易伏击当它进入时候)。

     当鲨鱼到底左右边界时它会转身朝着边界移动一下和改变速度。这样它只是来来回回,连续来回。

     调用transform.Rotate(new Vector3(x,y,z)),通过给定的值明显的绕轴选择物体,transform.Translate(new Vector3(x,y,z))你上次已经知道了。

     很容易!切换回Unity并把这个“FishClass”脚本 放到“Hierarchy”面板中的“Shark”对象上。现在点击Play按钮:你可以看到巨大的鲨鱼来来回回等待被轰炸。干得好!

     

    8.添加小鱼

     让我们做同样地步骤对我们的小鱼对象。我要把它变成一个很好的快速参考列表:

     1.下载并解压ClownFish model.

     2.拖拽“mesh_clownfish.obj”到“Project”面板中的“Models”文件夹里,并把“clownfish.bmp”放到“Models/Textures”文件夹下。

     3.选择“GameObject/Create other/Capsule”并在“Hierarchy”面板中重命名这个“Capsule”为“ClownFish”。

     4.点击“Mesh Filter”下的带圆点的圆圈按钮,并从弹出框中双击这个clownfish几何体。

     5.拖拽这个“clownfish”模型纹理到 “Hierarchy”面板的“ClownFish”对象上。

     6.当选中“ClownFish”对象时,在“Inspector”面板中改变以下这些属性:

    • Position to [-20, -1, 7]
    • Rotation to [0, 180, 0]
    • Scale to [0.4, 0.3, 0.3]

      7.从“Project”面板中拖拽“FishClass”脚本文件到“Hierarchy”的“ClownFish”对象上。这将指派相同的通用的fish class到这个clownfish身上。

      8.选择在"Project"面板中“Models”文件夹下的“mesh_clownfish”,然后在“Inspector”面板中找到“Normals”并选择它的“Calculate”选项,然后滑动到下方点击"Apply"按钮。

      点击Play按钮并观看发生了什么-- 现在你拥有两个移动的鱼而无需编写任何额外的代码!

    一切很完美 - 鱼类游来游去,飞机海平面飞行。我们需要一些轰炸。

    9.设定炸弹

     下载并解压缩这个Can model.同样,拖拽这个“colourcan.obj”文件到“Project”面板中的"Models"文件夹下并把“cantex.bmp”文件放到“Models/Textures”文件夹下。

     从菜单栏中选择“GameObject/Create Other/Capsule”,重命名这个对象为“Bomb”.从这个 “Mesh Filter”弹出框中双击这个炸弹罐几何体。拖拽“Project”面板“Models/Textures”文件夹下的“cantex”纹理到“Hierarchy”面板中的“Bomb”对象上。 在“Inspector”面板中点击 “Capsule collider”中的这个按钮 ,出现弹出框:

     

     在出现的弹出框中,选择“Reset” - 这种方式 对撞机(collider)将自动分配集合尺寸。酷吧!

     接下来选择“Project”面板“Models”文件夹下的“colourcan”模型,然后在“Inspector”面板中找到“Normals”并选择“Calculate”选项,然后滑动到下方点击"Apply"按钮。

     现在让我们加入一些新的东西!再次选中这个"bomb"对象,并在“Inspector”面板中找到“Capsule Collider”(胶囊对撞机)中选中这个“Is Trigger”复选框!选中这个可以让炸弹对象与其他对象碰撞是触发事件。

      但要做到这一点,我们还需要分配刚体(Rigid Body)炸弹(至少一个碰撞对象需要有一个刚体) 。从菜单栏中选择“Component/Physics/Rigidbody”(在“Hierarchy”面板中的Bomb对象必须选中)。

     一旦你这样做,一个新的选项带出现在“Inspector”面板中叫做“Rigidbody”。取消选中“Use gravity”(使用重力,我们不会利用重力),并勾选上“Is Kinematic”这样可以控制编程机身。这是所有我们需要启动的碰撞内容。

     10.预制游戏对象

      请记住“Hierarchy”面板显示的是目前场景中有什么,“Project”面板中持有你所有的对象?这不得不做一些事情来达到我们的目标 -- 有多少炸弹装上飞机,它们将释放入海。

     我们将做什么 ——我们将预制游戏(它将准备设置场景显示),但是我们不会把它添加到场景,我们要实例化(或者克隆如果你是个科幻小说迷)这个“prefab”(预制)成一个真正的活动场景中的游戏对象。

     在"Project"面板中单击右键并且选择“Create/Folder”,重命名它为“Prefabs”。右键单击“Prefabs”文件夹并且选择choose “Create/Prefab”.重命名这个新建的prefab为“BombPrefab”。注意这个小立方体的Icon是白色的——这表示一个空的预制。

     现在——拖拽“Hierarchy”面板中的"Bomb"到“Project”面板中的“BombPrefab”上。注意这个立方体的icon现在变为蓝色——意味着是一个完整的预制,准备被克隆。同样重要的——现在观看“Hierarchy”面板——“Bomb”字体变成了蓝色——这意味着现在这个对象是一个预制的实例。

     现在,我们有自己的炸弹集合,我们并不需要场景中原来的炸弹——右键单击“Hierarchy”面板中的"Bomb"对象并选择"Delete"。

     让我们Coding! 切换回MonoDevelop编辑器,并打开PlayerClass.cs文件,在“speed”属性声明厦门添加:

    public GameObject bombPrefab;

     你猜到了吗?在这个属性中我们将对BombPrefab保留引用并且按照我们的意愿行事。注意属性的类型为“GameObject”,正如我早前说过的那样游戏中所有的东西都是一个GameObject(很像Cocoa中的NSObject),所以它是安全的为任何事物设置这样的类型。

      现在切换回Unity并选择“Hierarchy”面板中的“Palyer”对象。正如你期望那样,在“Inspector”面板中在“Player Class(Script)”下有一个新的属性“BombPrefab”。让我们设置它的值:从“Project”面板中拖拽“BombPrefab”到“Inspector”面板中叫“None(GameObject)”上边——现在这个字段表示BombPrefab预制附加了值。

      我们将需要为子弹创建一个C# class,在“Project”面板中“Class”文件夹上右键单击并选择“Create/C Sharp Script”,重命名为“BombClass”。右键单击并选择“Sync MonoDevelop Project”——MonoDevelop工具弹出。打开BombClass.cs并用下面代码替换内容:

    using UnityEngine;
    using System.Collections;
     
    public class BombClass : MonoBehaviour {
    	private float ySpeed = -4f;
     
    	// Update is called once per frame
    	void Update () {
    		transform.Translate( new Vector3(0f, ySpeed*Time.deltaTime, 0f) );
    		if (transform.position.y < -11) {
    			Destroy(this.gameObject);
    		}
    	}
    }

     到目前为止这非常类似于我们所做过的一切——我们translate对象的每一帧,当超出屏幕边界时候做出适当的反应。在这个炸弹的事例中,我们只是要销毁对象 ,因为我们总是可以从bomb  prefab(炸弹预制)中制造新的。

     在代码中注意到 “this”指的是这个C# bomb class,而这个gameObject属性指的是在场景中的对象,所以我们销毁在场景中的对象并把它链接到所有的组件上。  在第二部分中,我们将会掉的游戏对象的层次结构,当你访问组件附加到对象的编程。

     

    11.轰炸鲨鱼

     你一直在等待最后一部分——无极的暴力:

     打开PlayerClass.cs文件,在Update方法的末尾添加:

    if (Input.anyKeyDown) {
    	GameObject bombObject = (GameObject)Instantiate(bombPrefab);
    	bombObject.transform.position = this.gameObject.transform.position;

    }

     让我们解释这些代码行::

     1.Input是让你存取键盘,鼠标,加速器和触摸的类。 当一个键被按下时 Input.anyKeyDown是 true,这只发生一次。,即按钮第一次按下时。然后直到另一个键被按下时Input.anyKeyDown 再次是 false。anyKeyDown实际上是一个方便的抽象对象——它实际上是true当一个鼠标按钮被点击时,或键盘按键按下或iPhone屏幕上的触摸点击。

     2.(GameObject)实例化(bombPrefab)是个神奇的线,冲一个预制(prefab)创建一个实例,并将其添加到场景中。

     3.最后我们设置炸弹的position位置跟飞机使相同的。

     酷——我们创建了我们的炸弹当玩家点击屏幕时候,它开始往下掉并且超出屏幕时它会自己销毁。

     让我们尝试一下它!切换回Unity并点击Play按钮——现在如果你在“Game”面板中点击,你会看到一个炸弹在飞机的位置点上创建。

      点击很多次——很多炸弹被创建。你应该听到炸弹的声音。但炸弹降落不下来!为什么呢?你已经能自己找到问题的解决方法吗?答案稍后公布。

     

    我希望你想通了,但这里的问题是:你尚未分配这个BombClass脚本到这个 Bomb Prefab(预定炸弹身上),这是为什么降落不下来的原因。在“Project”面板中的"Class"文件夹下拖拽BombClass文件到同样面板下的“Prefabs”文件夹中的“BombPrefab”文件上。在“Inspector”面板中,如果你看到Bomb Class Script框请勾选住。现在再次点击Play按钮。

     

      现在还不是十全十美——这些鲨鱼当你打它们时不会死。既然我们已经配置了(colliders)对撞机和刚体组件的炸弹,我们只需要添加代码来响应碰撞。切换回MonoDevelop编辑器中,并添加如下代码到BombClass类中:

    void OnTriggerEnter(Collider obj) {
    	if (obj.gameObject.name == "Shark") {
    		//reset shark
    		obj.gameObject.transform.rotation = Quaternion.identity;
    		obj.gameObject.transform.position = new Vector3(20f, -3f, 8f);
    		Destroy(this.gameObject);
    	}
    }


     让我们再次解释这些代码行:

      1. OnTriggerEnter是个方法调用,当这个刚体附着与另一个刚体碰撞时,第二个刚体作为一个参数传递。

      2.这里,我们检查炸弹命中的对象是否是“Shark”;

      3.如果这个鲨鱼被命中,然后第一对象旋转复位。

      4.第二,我们设置鲨鱼回到原来的位置。

      5.最后我们调用 destroy this.gameObject方法,使炸弹从场景中消失。

      很容易!难道不是吗?这是所有你需要的——切换回Unity,运行你的游戏! 命中鲨鱼消失,新的鲨鱼又进来了。

     

      你可以选择菜单栏 “File/Build&Run”,然后当Xcode弹出框出现,点击“Run”,现在你拥有了iPhone上的游戏! 

     

     

    源代码如下:sample project

    在本系列的第2部分,我们要提升一下档次,使这个游戏真的富有挑战性和乐趣!

     如需转载,请注明翻译出处 http://www.cnblogs.com/jiangshiyong/p/3074917.html

     

     

    转载于:https://www.cnblogs.com/jiangshiyong/p/3074917.html

    展开全文
  • Unity需要多摄像机 不同景深显示 ,不同物体的时候,想要改变 精灵的Layer层,怎么办 以"Player"层为例子,添加Add Layer 在Inspector视图下,有User Layer 11 为"Player" 可以选择其他的数字的User Layer层...

    在2.5D游戏项目中,不同精灵要分层显示怎么办

    意思是不在一起显示


    当Unity需要多摄像机 不同景深显示 ,不同物体的时候,想要改变 精灵的Layer层,怎么办



    以"Player"层为例子,添加Add Layer

    在Inspector视图下,有User Layer 11 为"Player"

    可以选择其他的数字的User Layer层,命名为"Player",或者自定义

    使用这句话,对应的 物体 的层数 就改变为"Player"

    gameObject.layer = 11;

    没错,对应的 数字 11,为 User Layer 11层


    只有在物体生成的时候,对其赋值就行了

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

    写完上面的内容,才发现 参考资料1 的文章 的解决办法不错。



    参考资料:

    1.

    【个人UNITY笔记】{基础} 2D游戏中使用Shader或Camera解决Sprite前后遮挡关系

    2.

    shader实例(十五)渲染队列进行深度排序

    3.

    4.

    5.

    展开全文
  • 这是使用Unity 游戏开发工具制作一个简单的2.5D 游戏系列教程的第二部分。如果你没有看到第一部分的话请先看。 在系列教程的第一部分,我们覆盖了一些怎样使用Unity的基础性知识 和使用 C#写一些脚本。我们创建了一...

     最近在研究Unity 3D,看了老外Marin Todorov写的教程很详细,就翻译过来以便自己参考,翻译不好的地方请多包涵。

     这是使用Unity 游戏开发工具制作一个简单的2.5D 游戏系列教程的第二部分。如果你没有看到第一部分的话请先看。

     在系列教程的第一部分,我们覆盖了一些怎样使用Unity的基础性知识 和使用 C#写一些脚本。我们创建了一个简单的游戏,一个飞机可以来回飞行同时轰炸鲨鱼,保护小鱼!

      在这个教程的第二部分也是最后一部分,我们将延长这个游戏添加一些收尾内容。我们将添加一个声音效果和音乐,完善游戏逻辑,并为游戏添加多个场景!

      如果你还没有这个项目,请下载我们在上个教程留下的 project,并使用Unity打开它。如果它不能启动和加载,确保点击Scenes\LevelScene选项,让它可见。

     好了,让我们学习更多有关Unity的知识,并完善这个游戏。

    1. 添加iCandy到游戏中

     

     你已经注意到 ,当炸弹击中鲨鱼时,它只是静静地消失,你会想:“那不是非常酷!”

     好吧,我们要添加一个很酷的水下爆炸效果!

     从菜单栏中选择“GameObject/Create other/Particle System”,你会看到一个粒子系统出现在场景中,在“Hierarchy”面板中重命名这个Particle System”为 “Explosion”(爆炸),设置这个Explosion的position位置为[1, 1, 8].

     现在你如果是一个粒子系统的专家——前往“Inspector”面板自己设置 ,如果你不是,只需要跟随我们的指导是很容易的。覆盖这些值到”Inspector“中:

    这里最重要的属性是“One shot”——当你检查它时,系统将只会发送一次粒子 ——正如爆炸那样。现在让我们设置动画值——只是尝试更多或更少的颜色相匹配(如果你不做,也并不重要):

     

     这里最重要的属性是“Autodestruct”(自毁)——当选中这个粒子系统时,当没有更多活动的粒子时将会把自己从场景中移出去。这正是我们想要的——它就像一个垃圾收集器。

     现在你有一个漂亮的小规模爆炸,你需要做一个像之前做炸弹的一样——做一个预制,在需要它的时候实例化,当它在场景中完成任务时让它自动销毁。

     在“Project”面板中“Prefabs”文件上右键单击,选择 “Create/Prefab”,重命名为 “ExplosionPrefab”.在“Hierarchy”面板中拖拽 “Explosion”对象到这个新建的“ExplosionPrefab”文件上。在“Hierarchy”面板中右键单击 “Explosion”并选择删除。

     在"Project"面板中右键单击,选择“Sync MonoDevelop Project”来打开MonoDevelop。打开BombClass.cs文件,并在里面添加如下代码:

    //right under definition of "ySpeed"
    public GameObject explosionPrefab;
     
    //inside OnTriggerEnter, right after Destroy(this.gameObject)
    Instantiate(explosionPrefab, transform.position, Quaternion.identity);


     现在切换回Unity并在“Project”面板中选中“BombPrefab”——在“Inspector”面板中你可以看到新的属性 “ExplosionPrefab”。只需要拖拽在“Project”面板中的“ExplosionPrefab”文件到这个新的属性文件上,你就设置好了。

      好了——点击Play按钮,观看你命中鲨鱼的爆炸效果。

     

    2.添加earCandy到游戏中 

     不要告诉Steve,但是对于我们iCandy不够的,我们也需要一些earCandy!

     我们怎么能只有一个游戏而没有背景音乐?我们要拜访另一个伟大的人——Kevin Macleod。他是一个伟大的电影和游戏音乐作曲家,他的作品有在 CC license许可下。所以你要使用他的东西不要忘了署名。

     打开链接:http://incompetech.com/m/c/royalty-free/index.html?keywords=the%20cannery

     一旦你到达这个页面时,下载“The Cannery”文件到你的硬盘上,并拖拽下载好的“The Cannery.mp3″文件到你“Project”面板的 “Audio”文件夹下。

     我们想把音乐全时段的循环播放——但是我们应该把它附加到那个对象上呢?

     好吧,让我们把它附加到camera相机上!这个camera也是一个游戏对象,并可以有其他附加组件。

     从“Project”面板中把“The Cannery”拖拽到“Hierarchy”面板中的“Main Camera”上。 选中“Hierarchy”面板中的“Main Camera”,并在“Inspector”面板中找到 “Audio Source”选项 ——勾选住“Loop”选项框并设置Volume值为“0.20”.

     就是这样简单——运行这个场景并享受这个新的背景音乐吧!

    3.使用Unity 创建一个GUI

     让我们进入一个新的领域——GUI。Unity为你提供一些标准的labels和buttons,但是这些都不是Unity强大的功能。然而,我们需要一个label来显示当前的得分;所以首先我们需要实现得分的逻辑。

     切换回MonoDevelop。 打开PlayerClass.cs文件并添加一个新的属性:

    public static int score = 0;

      啊哈!又有了新的东西—— “static”。当类被加载和时这个属性将被创建,不管是否有这个类的实例。此外,这个属性可以被其他类访问——这就是为什么我们要保持这个得分计数为静态类型的原因。

     接下来添加更新得分的方法(现在没有太大的意义,但只管先创建它)——看比分属性是如何通过类名访问:

    public void updateScoreBy(int deltaScore) {
    	PlayerClass.score += deltaScore;
    }

      再添加一个新方法到 PlayerClass——这将会在屏幕上绘制得分计数:

      

    void OnGUI() {
    	GUIStyle style = new GUIStyle();
    	style.fontSize = 20;
    	GUI.Label(new Rect(10,10,100,20), "Score:"+PlayerClass.score, style);
    );
    }

     "OnGUI"此事件在GUI layer(图形用户界面层)每一帧上被调用。

      GUIStyle是一个类,它类似一个CSS类——所以你可以使用fontSize,marginLeft这样的你所熟悉的CSS方法,否则现在只保留字体大小。GUI.Label()是个拥有3个参数的方法:一个矩形的Label,绘制的字符串,和text风格。这就是全部了。

     剩下的唯一的任务是:当我们有命中或没命中时更新比分。 打开BombClass.cs文件,并做如下代码修改:

     

    //add a new property
    public PlayerClass player;
     
    //replace the existing OnTriggerMethod with
    void OnTriggerEnter(Collider obj) {
    	if (obj.gameObject.name == "Shark") {
    		//reset shark
    		obj.gameObject.transform.rotation = Quaternion.identity;
    		obj.gameObject.transform.position = new Vector3(20f, -3f, 8f);
    		player.updateScoreBy(+1);
    		Destroy(gameObject);
    		Instantiate(explosionPrefab, transform.position, Quaternion.identity);
    	}
    	if (obj.gameObject.name == "ClownFish") {
    		//reset fish
    		obj.gameObject.transform.rotation = Quaternion.identity;
    		obj.gameObject.transform.position = new Vector3(-20f, -1f, 8f);
    		player.updateScoreBy(-1);
    		Destroy(gameObject);
    		Instantiate(explosionPrefab, transform.position, Quaternion.identity);
    	}
    }

     这跟我们以前的非常相似, 但我们有了一个新的属性叫做“player”,并且当我们需要更新分数时我们只需要调用player.updateScoreBy()。

     也为了使游戏更加有趣,如果你打的是鲨鱼你将得到一个点,如果你打的是小鱼,那么你将失去一个点。下载呢,塑造一场艰难的比赛!

     最后一件事——设置这个player(玩家)属性上的炸弹。现在我们不能像之前那样创建,因为炸弹是动态创建的,但幸运的是炸弹是由玩家自己创建,这样他可以在创建时设置这个玩家属性。

     让我们开始做——打开PlayerClass.cs文件并在这一行“bombObject.transform.position = this.gameObject.transform.position;”下方添加如下代码:

    BombClass bomb = (BombClass)bombObject.GetComponent("BombClass");
    bomb.player = this;

     这又有了新的东西了!让我们分析下:bombObject是一个GameObject对象的实例化(实例化返回),所以我们称之为“GetComponent”,并且这样我们可以访问所有连接的游戏对象组件——结果我们映射到一个BombClass——所以最后我们得到连接到游戏对象的C#类的引用。接下来,我们只要设置“player”属性(PlayerClass 的实例)。

      运行这个场景,你将会看到分数显示!

     

    4.Unity 对象和组件

     到这个地步,你对Untiy的游戏对象模型被引用已经有了足够的练习使用。更好地了解你实际上是在做什么,对不对?让我们做一个非常短的复习来看卡游戏中的涉及对象和组件是如何连接的。

     在“Inspector”面板中我们所看到的所有选项条目——这些事游戏对象中比较重视的组件。一个空的对象只有它的 transform选项条目——position, rotation, scale.这是所有的——一切附加组件。

    • Transform: provides position, rotation, and scale, as described above.(提供位置,旋转和缩放,如上所述。)
    • Mesh Filter: provides the geometry of the visible object.(提供可视对象的几何形状。)
    • Mesh Renderer: renders the geometry.(呈现几何。)
    • Rigidbody: handles physics.(处理物理。)
    • Audio Source: plays audio.(播放音频。)
    • Script: can programmatically update the object.(可以通过编程更新对象。)

     这些只是小数属性可以附加到一个对象上。为了更好的理解,让我们看卡这张图片:

     

     因此,脚本组件采用点视图方式。它会看起来更清楚一些,为什么我们不得不调用它:

    Destroy(this.gameObject);

     为了销毁一切跟对象有关的实例。通过游戏对象的属性我们可以访问所有其他组件,所以我们可以physics物理化或调整音量,等等。

     

    5.添加更多的场景

     现在我们的游戏是越来越好了,但是没有方式显示输和赢!

     所以让我们添加一个“you win”的场景,当玩家做出3点以上的成绩时。

     从菜单栏中选择“File/New Scene”,然后再次从菜单栏中选择“File/Save Scen”,弹出框中选择文件夹“【你的项目目录】/Assets/Scenes”,没有Scenes文件夹就创建一个,并以“WinScene”文件名保存。

     在“Hierarchy”面板中选中“Main Camera”并设置:Position [0, 0, 0],Projectio为“Orthographic”, Size 为 “10″, Near 为 “0.5″ and Far 为 “22″。从菜单栏中选择“GameObject/Create Other/Directional Light”并在“Inspector”面板中设置:Position [0, 0, 0].

     我们想要在场景中放一个平面(像在我们游戏中的背景),并放一个图片在它上面叫“you win”,所以让我们像在第一部分中所做一样:从菜单栏中选择“GameObject/Create Other/Plane”并在“Inspector”面板中设置:Position [0, 0, 8], Rotation 为 [90, 180, 0], Scale 为 [3, 1, 2].

     下一步下载并保存 Vicki Wenderlich所做的这个图片到你的硬盘上,浏览如下:

     拖拽下载的“gameover_youwin.png”到“Project”面板中的“Textures”文件夹中。这个纹理被导入后看起来有点脏——这是因为压缩的原因,只需要在“Project”面板中选中 “gameover_youwin”纹理,然后在“Inspector”面板中找到 “Format”并改变它的值为 “16bits”,并点击“Apply”。现在把“Project”面板中的“gameover_youwin”拖拽到“Hierarchy”面板中的“Plane”上。在你的“Game”面板中你应该看到“You win”——Vicki所绘制的这个邪恶的鲨鱼漂浮起来。

     我们需要让它活动起来——当场景被点击时,游戏应该重新启动:在“Project”面板中的“Class”文件夹下右键单击,并选择“Create/C Sharp Script”,然后重名为“GameOverClass”。在"Project"面板中右键单击并选择“Sync MonoDevelop Project”。在MonoDevelop中打开新建的 GameOverClass.cs文件,并替换如下代码:

    using UnityEngine;
    using System.Collections;
     
    public class GameOverClass : MonoBehaviour {
    	// Update is called once per frame
    	void Update () {
    		if (Input.anyKeyDown) {
    			PlayerClass.score = 0;
    			Application.LoadLevel("LevelScene");
    		}
    	}
    }

     当玩家点击这个屏幕时候,比分重置和重新加载游戏场景。Application.LoadLevel()只需要加载场景的名字——很容易。

     切换回Unity:从“Project”面板中的“Class”文件夹下拖拽 “GameOverClass”脚本文件到“Main Camera”上。

     现在在项目中包括这个场景下 选择 “File/Build Settings”,并在弹出框中点击 “Add current”按钮,关掉框框。你已经添加这个场景到这个项目的建设中。

     然我们也快速添加“You loose”场景!像上次一样,制作一个“New scene”,然后保存这个新场景为“LooseScene”到这个“Scenes”文件夹下。

     在“Hierarchy”面板中选中 “Main Camera”并设置: Position [0, 0, 0], Projection to “Orthographic”, Size to “10″, Near to “0.5″ and Far to “22″。从菜单栏中选择“GameObject/Create Other/Directional Light”,并在"Inspector"面板中设置:Position [0, 0, 0]。从菜单栏中选择“GameObject/Create Other/Plane”,并在"Inspector"面板中设置: Position [0, 0, 8], Rotation to [90, 180, 0], Scale to [3, 1, 2]。

     下载这个“You Lose”图片保存在你的硬盘上面,预览如下:

     

     采取以下步骤包装这个场景:

      1.拖拽下载的“gameover_youlose.png”到“Project”面板中的“Textures”文件夹下。

      2.在“Project”面板中选中 “gameover_youlose”纹理,然后在“Inspector”面板中找到“Format”改变它为“16bits”,并点击 “Apply”。

      3.从“Project”面板中拖拽 “gameover_youlose”文件到“Hierarchy”面板中的“Plane”上。

      4.从“Project”面板中的“Class”文件夹下拖拽“GameOverClass”文件到这个“Main Camera”。

      5.从菜单栏选择“File/Build Settings”,在弹出框中,点击“File/Build Settings”按钮,关掉弹出框。

     这里——你有3个场景,但你需要把它们联系起来!

     进入到这个LevelScene场景——通过双击“Project”面板中的 “LevelScene”。切换到MonoDevelop并打开PlayerClass.cs文件。我们要去修改这个updateScoreBy方法来检测你是否赢得超过3点还是在负3点以下。

     

    //replace the updateScoreBy method with this code
    public void updateScoreBy(int deltaScore) {
    	PlayerClass.score += deltaScore;	
    	if (PlayerClass.score>3) {
    		Application.LoadLevel("WinScene");
    	} else if (PlayerClass.score<-3) {
    		Application.LoadLevel("LooseScene");
        }
    }

         

    现在你的场景工作流程被设置。你可以在Unity中点击Play按钮运行游戏。其实——你为什么不点击“File/Build&Run”,当Xcode弹出框——点击“Run”,也就尝试在您的iPhone上运行游戏。

    6.展望2.5D——最后

     是时候了,让你在本系列教程的第二部分看你一直期待的2.5D技术!

     我将提前爆料一个秘密——我打算把它几乎为3D展示,为您的开发增添乐趣!

     截止到现在,我们已经设置这个 cameras’ projection(摄像机的投影)为“Orthographic”(正面),这让场景看起来像一个普通的2D游戏—到此为止!

     在你的LevelScene场景中选中 “Main Camera”,并在“Inspector”面板中改变这个Projection为“Perspective”,和 “Field of View”为“100″(以Perspective的角度看).好了,点击这个Play按钮,在2.5D下观看你的游戏。是不是很酷呢?

     但是我们不能止步于此。

     这有个计划——使游戏变得更加困难写,并演示如何旋转和移动摄像机,每一次的得分增加,我们将按钮圆弧路径移动摄像机,并改变它的角度。这样你越在游戏中进步,你将不得从怪异的角度看目标和尝试轰炸鲨鱼!

     切换回MonoDevelop,并对 PlayerClass.cs文件做如下更改:

    //add the properties
    public GameObject mainCamera;
    public GameObject gameBackground;
    public float nextZ = 0;
     
    //at the end of the updateScoreBy method
    if (PlayerClass.score>0) {
    	nextZ = PlayerClass.score*2.5f;
    }
     
    //at the end of the Update method
    if (nextZ > mainCamera.transform.position.z) {
    	mainCamera.gameObject.transform.Translate( 
    		3* Mathf.Sin(transform.position.z/2 ) * Time.deltaTime, 
    		0, 
    		-Mathf.Sin(transform.position.z /2 ) * Time.deltaTime *0.3f
    	);
    	mainCamera.gameObject.transform.RotateAroundLocal( Vector3.up, Time.deltaTime*0.1f );
    	gameBackground.gameObject.transform.RotateAroundLocal( Vector3.up, Time.deltaTime*0.1f );

    }

     好吧——大量的代码,但是这正是我们需要的。让我们一点一点地分析它:

     首先,我们生命属性来引用Main Camera和Background plane(平面)。我们将移动和旋转摄像头,我们也要将背景旋转。

     这个摄像机从它当前Z轴为0的位置移动到朝着background 7.2Z的位置。所以每次玩家得分,这个nextZ被设置为2.5,然后5.0,然后7.5——通过这些值Main Camera转换到用sin函数的圆弧状的东西。

     所有的数学函数通过Mathf类——正如这个sin函数为 Mathf.Sin()。所以我们旋转摄像机使用transform.RotateAroundLocal,我传递一个值(Vector3.up)绕轴,通过角度旋转。我们使摄像机和背景一起旋转,这样摄像机始终面对着背景(即用不完的屏幕背景)。

     更重要的事情——让我们连接新的公共属性。切换回Unity,在“Hierarchy”面板中选中“Player”对象。从“Hierarchy”面板中拖拽 “Main Camera”到“Inspector”面板中的新的 “Main Camera”属性上;从“Hierarchy”面板中拖拽“Background”对象到“Inspector”面板中的新的 “Game Background”属性上

     恭喜,你终于完成了!点击“File\Build and Run”,run the finished game on your iPhone.以怪异的角度轰炸鲨鱼吧!

     

    7.Unity调试

     我想不免会触及一些话题,因为当你自己开发时,你会碰上麻烦,你需要调试你的游戏,incident,一些简单的事情要牢记:

     1.不要忘记在toolbar工具栏上有一个暂停按钮,所以你如果需要停止执行游戏,并检查所有对象的属性——只需要点击Pause按钮,然后浏览你周围的厂家,在“Inspector”面板中查看各种属性值。

     2.如果你不确定你的方法是否触发了,在控制台打印一条消息(类似在Xcode中)。使用:Debug.Log(“message”); 将消息打印到控制台。你可以选择菜单栏“Window/Console”,来调出控制台窗口。

     3.养成这种习惯:当你在MonoDevelop完成编码时,你切换回Unity看一看Unity的状态栏(在应用窗口的底部)——如果你写了错误的代码,将不会被验证,你会得到有红色的错误消息,你点击这些错误消息就能马上带你回到MonoDevelop。

     4.如果你的对象不动——三重检查你的script脚本文件是否连接到你的对象上。

     5.当你运行你的游戏时,你可以改变在“Inspector”面板中的值,只管尝试不同的值。当你暂停游戏时:NB在“Inspector”面板中的所有值都被重置到你运行游戏之前的数据。因此,如果你忘了停止游戏和你进行的更改,它们会丢失,所以请务必完成测试后停止游戏,然后继续开发。

     

    源代码如下:sample project

    如果你想学习更多有关Unity的知识请访问它们的论坛网站www.unity3D.com/support/.也可以看下Unity C# Reference.

     

     如需转载,请注明翻译出处 http://www.cnblogs.com/jiangshiyong/p/3150991.html

     

     

    转载于:https://www.cnblogs.com/jiangshiyong/p/3150991.html

    展开全文
  • 上一篇文档介绍了2D游戏中如何使用Unity创建Isometric Z As Y Tilemap。本篇文章将在前文基础上继续讲解如何正确处理图片的遮挡关系、图片渲染顺序。尤其是当Tilemap中的图片大小不一致、图片需要在原有网格位置上...
  •   首先我得说Unity3D已经做的很好了,搞这些东西意义真心不大。具体Unity3D有什么优势我之前也写...我的新的工作大概就是写一个cocos2d-x的2.5D游戏。如果按照我自己的想法,那肯定是U3D来做,不过我在技术上从来
  • 2.5D游戏中地图的即时生成算法的研究与分析
  • 在上一篇文章[Unity3D]Unity3D游戏开发之角色控制漫谈>一文中,博主与大家分享自己在角色控制方面的一些感悟。今天呢,我们继续来探讨Unity3D角色控制的内容,今天博主将解决在上一篇文章中没有解决的问题,即自由...
  • Unity 3D本来是由德国的一些苹果粉丝开发的一款游戏引擎,一直只能用于Mac平台,所以一直不被业外人士所知晓。但是后来也推出了2.5版,同时发布了PC版本,并将其发布方向拓展到手持移动设备。Unity 3D游戏开发学习...
  • 1.ZTest & ZWrite ZTest:深度测试,开启后测试结果决定片元是否被舍弃,可配置 ZWrite:深度写入,开启后决定片元的深度值是否写入深度缓冲,可配置 ZTest可设置的测试规则: ZTest Less:深度小于当前缓存...
  • 2D与2.5D的关系可以看成X轴与Y轴旋转了指定的角度后形成的新的平面。 首先需要知道坐标旋转算法:   通过矩阵的知识可以知道,X轴的基向量为[1,0];Y轴的基向量为[0,1]。有X和Y轴基向量组成的矩阵是一个单位矩阵...
  • 一、前言 本文转自:GameRes游资网 原文作者:zhihudaye ...amp;amp;tid=307874&...extra=page%3D1%26filter%3Dsortid%26sortid%3D6 二、服务器源码 https://github.com/kbengine/kbe...
  • 1、为什么有那么多游戏引擎还要自己写一个游戏引擎? 我本身并不是学图形学的,只是一个有三年游戏开发经验的客户端程序员。我的工作经历告诉我,如果不自己写一个游戏引擎(即便最终不能有实际应用)那么就不会...
  • 由于游戏还没有开发完成,在此先不放出游戏内的截图,只贴出测试截图及拐点计算方法。 1.初始化所有三角形 2.利用A*算法计算所有经过的三角形列表 3.计算拐点 拐点计算代码: using UnityEngine; using ...
  • 博主曾经坦言自己是一个喜欢国产RPG游戏的人,《仙剑奇侠传》、《轩辕剑》、《古剑奇谭》等游戏都为博主带来了许多温暖的回忆。那么什么是回合制呢?让我们将视线转移到三足鼎立的三国时代,只见张飞挺着丈八蛇矛,...
1 2 3 4 5 ... 20
收藏数 845
精华内容 338
热门标签