Unity MMORPG游戏开发教程(一)——初识Unity
五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑。本系列文章以C#为介绍语言,基于Unity2017.4.x。
一、环境搭建
我使用的是Unity+VSCode,用的是mac系统,windows的自己搜资料,步骤差不多。
1.安装Unity:下载Unity,我下载的是Unity2017.4.21f1。下载下来是一个下载助手UnityDownloadAssistant-2017.4.21f1.dmg,双击打开安装。选择安装内容Unity2017.4.21f1、MonoDevelop/Unity Debugger、Documentation、Standard Assets。
2.安装VSCode:个人喜好,VSCode比较轻量,写代码流畅一点。下载最新版本就可以。
3.下载dotnet:我下载的是dotnet-dev-osx-x64.1.1.11.pkg,双击打开安装。
4.安装VSCode插件:插件可以选择unity3d-pack,由于我安装失败,所以把unity3d-pack里面的插件都安装了一遍:
C#
C# FixFormat
C# Snippets
Debugger for Unity
eppz! (C# theme for Unity)
MonoBehaviour Snippets
ShaderlabVSCode(Free)
Unity Code Snippets
Unity Tools
5.建立Unity项目:打开Unity,我新建的是2D项目
6.建立C#项目,目的是让VSCode对C#代码有提示。终端命令行cd到Unity项目根目录,运行命令dotnet new console创建dotnet命令行工程。Unity项目根目录下会生成 xx.csproj文件、obj目录、bin目录
7.添加unity库引用,目的是让VSCode能识别Unity的命名空间(UnityEngine、UnityEngine.UI等)。打开obj/project.assets.json文件,在compile节添加unity库路径,包括(有用到其他库自己添加):
"/Applications/Unity/Unity.app/Contents/Managed/UnityEngine.dll": {},
"/Applications/Unity/Unity.app/Contents/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll": {},
这样,Unity+VSCode的环境就搭建好,可以用VSCode写脚本了。
二、编辑器简介
1.工程结构管理器

2.场景层级管理器

3.场景编辑器

4.属性编辑器

新建工程时,工程结构管理器中,Assets目录下为空,可以在下面创建场景,双击场景在场景层级管理器看到它的结构,在场景编辑器里可视化编辑,右边的属性编辑器可以对相应对GameObject设置属性、添加组件(包括脚本)。有使用过cocos creator经验会很熟悉,不详述。
三、熟悉开发流程
首先必须了解一些基本概念,
1.在Unity里,游戏由GameObject组成(可以理解成cocos里的cc.Node),GameObject可以添加组件
2.组件基类为Component,但用户自定义的脚本都继承自MonoBehaviour(Component的子类,如同cocos creator里的cc.Component)
3.每个GameObject有基本的Transform,设置GameObject的坐标
Assets目录是游戏开发所有资源存放的地方,包括图片、声音、脚本资源。我开发游戏,一般只做一个scene,Assets目录下新建一个目录Scene,在下面新建场景Main(在文件系统中可以看到它的全称是Main.unity)。

双击,在场景层级管理器中可以看到它的层级结构,默认只有一个Main Camera。为了支持屏幕适配,编写一个C#脚本,在Assets目录下新建一个目录Script,用于存放C#脚本。新建C#脚本MainCamera(文件系统中MainCamera.cs),用VSCode打开(VSCode直接打开整个项目的根目录),添加以下代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MainCamera : MonoBehaviour { public float designWidth = 6.4f;
public float designHeight = 9.6f; // Use this for initialization
void Start () {
float screenHeight = Screen.height;
float orthographicSize = this.GetComponent<Camera>().orthographicSize;
float aspectRatio = Screen.width * 1.0f / Screen.height;
// fix the litte side
if (aspectRatio < designWidth / designHeight) { // fix width
orthographicSize = designWidth / (2 * aspectRatio);
this.GetComponent<Camera>().orthographicSize = orthographicSize;
Debug.Log("FIX_WIDTH, orthographicSize is " + orthographicSize);
} else { // fix height
orthographicSize = designHeight / 2;
this.GetComponent<Camera>().orthographicSize = orthographicSize;
Debug.Log("FIX_HEIGHT, orthographicSize is " + orthographicSize);
}
} // Update is called once per frame
void Update () { }
}
在Unity编辑器的场景层级管理器选择Main Camera,在属性编辑器中给它添加组件(Add Component -> Scripts -> Main Camera),现在可以设置游戏的设计分辨率了。

游戏启动后,会根据GameObject“Main Camera”的生命周期触发Main Camera脚本的Start方法,根据游戏尺寸对照相机调整显示高度(不适用于UGUI,UGUI待会介绍)。该适配方案要注意几个概念,Unity默认单元大小为100个像素,所以宽高是实际像素数除以100,照相机的orthographicSize等于照相机显示高度的一半。如设置为6.4x9.6,那么美术出资源时一屏的大小就是640x960。不同的手机屏幕自动做等比例缩放,具体缩放倍数,当实际屏幕宽高比小于设计分辨率时宽缩放到跟实际屏幕一样,否则高缩放到跟实际屏幕一样。另外一边相应等比例缩放,小的一边铺满全屏可以避免出现黑边,但也导致被裁剪,这种方式主要针对全屏的场景。
给主场景添加两个GameObject:SceneLayer和PopupLayer,分别作为场景和弹窗的根节点。

默认组件Transform只有位置没有大小,换成组件RectTransform,设置其大小为设计分辨率

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class StartCtrl : MonoBehaviour { public GameObject sceneLayer = null;
public GameObject popupLayer = null; // Use this for initialization
void Start () { } // Update is called once per frame
void Update () { }
}
在Unity编辑器的场景层级管理器选择Main Camera,在属性编辑器中给它添加组件(Add Component -> Scripts -> Start Ctrl),把场景层级管理器的sceneLayer、popupLayer拖到对应的属性完成关联。启动游戏后,GameObject“Main Camera”的生命周期就会触发StartCtrl里对应的方法,StartCtrl里的sceneLayer和popupLayer属性已被赋值为Main场景对应的子节点。后面我们会继续讲解如何使用这两个属性对界面进行分层管理。





using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class TestViewCtrl : MonoBehaviour { public Text txtHello = null; // Use this for initialization
void Start () {
txtHello.text = "你好";
} // Update is called once per frame
void Update () { }
}
打开回刚才那个预制体,选择根GameObject,在属性面板选择添加组件TestViewCtrl,并将对应ui组件拖到脚本组件的属性上进行关联,这样我们就可以通过TestViewCtrl控制这个界面了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class StartCtrl : MonoBehaviour { public GameObject sceneLayer = null;
public GameObject popupLayer = null; // Use this for initialization
void Start () {
Object prefab = Resources.Load("Prefabs/TestView", typeof(GameObject));
if (!prefab) {
Debug.Log("Prefab is null");
return;
} GameObject gameObj = Instantiate(prefab) as GameObject;
gameObj.transform.SetParent(popupLayer.transform);
} // Update is called once per frame
void Update () { }
}
Unity MMORPG游戏开发教程(一)——初识Unity的更多相关文章
- Unity 2D游戏开发教程之精灵的死亡和重生
Unity 2D游戏开发教程之精灵的死亡和重生 精灵的死亡和重生 目前为止,游戏项目里的精灵只有Idle和Walking这两种状态.也就是说,无论精灵在游戏里做什么,它都不会进入其它的状态,如死亡.于 ...
- Unity 2D游戏开发教程之摄像头追踪功能
Unity 2D游戏开发教程之摄像头追踪功能 上一章,我们创建了一个简单的2D游戏.此游戏中的精灵有3个状态:idle.left和right.这看起来确实很酷!但是仅有的3个状态却限制了精灵的能力,以 ...
- Unity 2D游戏开发教程之使用脚本实现游戏逻辑
Unity 2D游戏开发教程之使用脚本实现游戏逻辑 使用脚本实现游戏逻辑 通过上一节的操作,我们不仅创建了精灵的动画,还设置了动画的过渡条件,最终使得精灵得以按照我们的意愿,进入我们所指定的动画状态. ...
- Unity 2D游戏开发教程之游戏精灵的开火状态
Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 “开火”就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
- Unity 2D游戏开发教程之为游戏场景添加多个地面
Unity 2D游戏开发教程之为游戏场景添加多个地面 为游戏场景添加多个地面 显然,只有一个地面的游戏场景太小了,根本不够精灵四处活动的.那么,本节就来介绍一种简单的方法,可以为游戏场景添加多个地面. ...
- Unity多玩家网络游戏开发教程1章Unity带有网络功能
Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件.专门提供了对网络功能的支持. 可是.大部分开发人员第一次接触到的还是Unity自带的网络功能.也就是大家常 ...
- Unity 3D游戏开发学习路线(方法篇)
Unity 3D本来是由德国的一些苹果粉丝开发的一款游戏引擎,一直只能用于Mac平台,所以一直不被业外人士所知晓.但是后来也推出了2.5版,同时发布了PC版本,并将其发布方向拓展到手持移动设备.Uni ...
- Unity 2D游戏开发教程之2D游戏的运行效果
Unity 2D游戏开发教程之2D游戏的运行效果 2D游戏的运行效果 本章前前后后使用了很多节的篇幅,到底实现了怎样的一个游戏运行效果呢?或者说,游戏中的精灵会不会如我们所想的那样运行呢?关于这些疑问 ...
随机推荐
- 用PCA(主成分分析法)进行信号滤波
用PCA(主成分分析法)进行信号滤波 此文章从我之前的C博客上导入,代码什么的可以参考matlab官方帮助文档 现在网上大多是通过PCA对数据进行降维,其实PCA还有一个用处就是可以进行信号滤波.网上 ...
- 学会python可以上天!20行代码获取斗鱼平台房间数据,就是这么牛逼!
Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...
- keras实现简单性别识别(二分类问题)
keras实现简单性别识别(二分类问题) 第一步:准备好需要的库 tensorflow 1.4.0 h5py 2.7.0 hdf5 1.8.15.1 Keras 2.0.8 opencv-p ...
- Redis持久化方式的选择
本文将介绍Redis持久化的两种方式:快照持久化和AOF持久化,并对两种方法进行分析和对比,方便在实际中做出选择. 持久化 什么是持久化 Redis所有数据保存在内存中,对数据的更新将异步地保存到磁盘 ...
- Python练习:九九乘法表
打印 n * n 的乘法表 #打印 9*9 乘法表 def Multiplication(n): # n - 定义打印的行数 max_len = len(str((n)**2)) #计算最大值的占位( ...
- 了解Scala反射
本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...
- 分析Class类和ClassLoader类下的同名方法getResourceAsStream
在读取本地资源的时候我们经常需要用到输入流,典型的场景就是使用Druid连接池时读取连接池的配置文件.Java为我们提供了读取资源的方法getResourceAsStream(),该方法有三种: Cl ...
- Nginx的“远方表哥”—Tengine
本文收录在Linux运维企业架构实战系列 今天想起当初研究nginx反向代理负载均衡时,nginx自身的upstream后端配置用着非常不舒服: 当时使用的淘宝基于nginx二次开发的Tengine, ...
- TCP的三次握手与四次挥手
TCP的三次握手与四次挥手 一.TCP(Transmission Control Protocol 传输控制协议) TCP是面向对连接,可靠的进程到进程通信的协议 TCP是提供全双工服务,即数据可在同 ...
- The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
使用EF时,在Limda表达式中( query.Where(x => x.CheckInDate >= bd.Date);)查询的时候抛出了这个异常,网上查到的发现,并不能解决问题. 后来 ...