今天含泪开一个新坑——Unity 3D。由于导师调整任务,最近要和师兄一起搭建3D虚拟仿真平台,特此学习。ROS也会继续学习下去,希望能够兼容到一起。Let’s get it !
1 Unity 3D 界面设置与介绍
- 目前使用的版本是:Unity 2020.3.25
- 推荐一个教学平台:www.sikiedu.com
1.1 Unity 下载
在这里给大家推荐一篇教程,很详细,亲测有效!我就不做重复工作了!
1.2 界面介绍
目前感觉这种界面布局蛮舒服的,大家可以改成这种形式。
具体设置方式:
click Layout(右上角)——select tall
click Project 右边的设置——select One Column Layout
目前 Unity 只支持 C#脚本文件(Scripts),不再支持 Monodevelop和 Java.
可以将C#文件的编译器直接设置为:Visual Studio Community 2019
步骤:Edit -> Preferences -> External Tools -> External Script Editor
解释一下,之前默认的 Open by file extension 是指根据拓展名进行选择。
设置字体:JetBrains Mono
设置方式:Visual Studio -> 工具 -> 选项 -> 字体和颜色
1.3 各个窗口功能介绍
主要的功能窗口有:Scene、Game、Hierarchy、Project、Inspector 5部分
-
Project 工程面板
作用:展示工程内容,包括:场景、音效、材料、脚本、功能包等等。 -
Hierarchy 层级面板
作用:展示当前场景中的布局和内容,各个游戏物体(GameObject)可以分成多个层级 -
Inspector 检视面板(属性面板)
作用:管理各个游戏物体的属性(由哪些组件(component)组成),还可以添加新的组件 -
Scene 场景面板
作用:显示当前场景 -
1.3.5 Game 游戏面板
作用:显示游戏运行过程,通过照相机 (main camera)显示。
2 简单的操作介绍
2.1 游戏物体的创建、复制、删除等
- 创建
在对应场景的层级面板中点击 Creat 创建新的游戏物体(GameObject),物体会默认出现在 Scene界面的最中间 - 复制
游戏物体右键点击 Duplicate 复制,复制后的游戏物体与原物体大小、位置均相同,快捷键:Ctrl+D - 删除
Delete
注意:Unity中不提供复杂游戏物体,需要通过3DMax、Maya等绘制。
2.2 场景基本操作
- 对某一物体聚焦: F
- 查看物体周围:ALT+左键
- 切换视野:Persp:透视视野 ISO:平行视野 ,不同视野下鼠标右键作用不相同
- 放大缩小视野:鼠标滚轮
- 在 Movetool下可以移动物体
2.3 世界坐标系和局部坐标系
- 坐标系(Coordinate System)
x : 右左
y : 上下
z : 前后
(其中,右、上、前分别是三个方向的正方向) - 局部坐标系
如果一个物体有父物体的话,子物体的坐标是相对于父物体的相对坐标
(相对坐标和世界坐标有一定的换算关系) - 默认单位为:m
2.4 工具使用
前四个最为常用,分别是:
Hand tool 视图工具
Move tool 移动工具
Rotate tool 旋转工具
Scale tool 缩放工具
分别对应快捷键:Q、W、E、R
其余的需要注意的是:Global 和Local 坐标系的切换;Pivot是基准中心(原点),Center是碰撞中心,一般使用 Pivot 和 Local 即可,剩下的具体使用时再进行介绍。
3 Roll A Boll案例
经过前期了解后,正式开始开发第一个案例。
3.1 创建一个平面(plane)
平面默认尺寸问为10x10,要求大小为20x20,即将x和z的scale设置为2
由于初始平面是白色的,我们想要更改颜色(材料)的话,需要给游戏物体添加材料。
在Assets新建一个 Materials 文件夹,创建一个材料属性,修改名字为 BackGround。
此时,双击打开创建的材料文件,设置属性。里面可以选择自己想要的颜色。
将创建好的材料拖拽到平面上即可为平面添加属性。
3.2 创建一个运动体 Player(Sphere)
步骤和创建平面一样
- 1 创建一个球体Sphere,改名为 Player,球体采用标准尺寸
- 2 添加材料,可以选择自己喜欢的颜色
- 3 改变材料属性smoothness为0(即让球体不反光)
注意!!网格渲染(Mesh renderer)更加逼真,碰撞(Collider)要简化一些,Unity可以自动帮助我们进行碰撞检测!
3.3 给Player添加物理属性(连接刚体Rigidbody)
步骤:
- 1 在检视面板Inspector中为Player添加刚体Rigidbody组件
此时,Player就拥有了一些物理属性,比如受力、碰撞等。运行游戏进行检查,此时小球可以自由下落到平面上。
3.4 通过C#脚本控制小球(Player)的运动
3.4.1 一些基础语法知识
- 代码中的类名和文件名保持一致
3.4.2 控制小球持续向右运动
//引用系统提供的类
using System.Collections;
using System.Collections.Generic;
//引用Unity引擎
using UnityEngine;
public class PlayerController : MonoBehaviour
{
//设置一个公开属性 private是私有属性,不显示标签
public Rigidbody rd;
//Start is called before the first frame update
void Start()
{
//将代码与Player的刚体组件关联
rd = GetComponent<Rigidbody>();
}
//Update is called once per frame
//60 frame/s 游戏一秒60帧
void Update()
{
//给Player施加一个持续向右 1N 的力
//力用一个三维向量来表示
rd.AddForce(Vector3.right);
}
}
控制效果:
3.4.3 监听键盘并控制小球的运动
代码:
/引用系统提供的类
using System.Collections;
using System.Collections.Generic;
//引用Unity引擎
using UnityEngine;
public class PlayerController : MonoBehaviour
{
//设置一个标签
public Rigidbody rd;
//Start is called before the first frame update
void Start()
{
rd = GetComponent<Rigidbody>();
}
//Update is called once per frame
//60 frame/s 游戏一秒60帧
void Update()
{
//监听(得到输入)
//得到一个浮点数据
float h = Input.GetAxis("Horizontal");//a=-1,d=1
float v = Input.GetAxis("Vertical");//w=
Debug.Log(h);
rd.AddForce(new Vector3(h, 0, v)*10);
}
}
对比之前的直接输入力的代码相比,有其中三行发生了变动:
float h = Input.GetAxis(“Horizontal”);//a=-1,d=1
float v = Input.GetAxis(“Vertical”);//s=-1,w=1
rd.AddForce(new Vector3(h, 0, v)*10);
其中,input.GetAxis()代表获取键盘上的指令,Horizontal 代表水平方向,也就是左右移动,默认按键是a和d(可以进行修改),Vertical 代表垂直方向,也就是前后移动,默认按键是w和s。
控制效果:
3.5 控制相机跟随移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowTarget : MonoBehaviour
{
//设置一个公开的属性,通过拖拽Player进行属性添加
public Transform playerTransform;
//定义一个内置属性,类似变量,用于在两个函数之间调用
private Vector3 offset;
// Start is called before the first frame update
void Start()
{
//首先在开始之前,计算相机与小球之间的位置偏差
offset = transform.position - playerTransform.position;
}
// Update is called once per frame
void Update()
{
//控制相机始终按照初始位置偏差跟踪小球
transform.position = playerTransform.position + offset;
}
}
控制效果:
可以看出,相机始终是跟随小球进行运动的。
3.6 添加墙(防止小球掉落)
由于之前小球在平面上运动,一不小心就会掉落下去。我们通过添加墙,来给小球的运动添加限制条件。
我们添加4个cube分别作为4堵墙,如下图所示。
此时小球的运动会受到墙的限制,控制结果如下图所示。
3.7 通过预制体来布置食物
- 预制体(Prefab):有时我们需要布置大量重复的物体,我们希望他们的尺寸和材料永远保持一致,预制体便应运而生。预制体可以创建大量的子模型,并使得子模型永远和预制体本身有同样的属性。
- 预制体的创建:
(1)新建一个预制体文件夹 Prefabs,设置好需要的游戏物体的属性,并将其拖拽到此文件夹下。
(2)接着,根据需要复制预制体,生成实例(Instance),放到需要的位置即可。
3.8 给食物添加旋转效果
直接给 Prefab Food_1添加一个脚本控制文件,可以保证小球持续旋转:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Food : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.Rotate(Vector3.up);
}
}
效果如下所示:
3.9 通过碰撞检测-检测碰撞到的食物
首先,为食物添加标签,直接给预制体添加即可:
给小球(Player)的C#文件添加碰撞检测事件:
//碰撞系统事件,碰到物体时会触发
private void OnCollisionEnter(Collision collision)
{
//检测碰撞到的游戏物体的标签是不是“Food”
if (collision.gameObject.tag == "Food")
{
//销毁碰撞到的游戏物体
Destroy(collision.gameObject);
}
}
查看游戏效果:
3.10 通过触发检测,吃食物
上一小节,我们已经成功控制小球吃掉了食物。但还有一点不足是,碰撞瞬间小球的运动状态发生了变化,这是我们不希望看到的,因此本节将采用另一种方法进行检测,并销毁食物。
- 触发检测与碰撞检测的区别:
碰撞检测时,小球与食物会发生物理接触,可能会影响小球的运动状态;
触发检测时,小球到达某一区域附近便会触发,不会发生物理接触,运动状态不发生改变。
触发检测打开方式:
给小球(Player)的C#文件添加触发检测事件:
private void OnTriggerEnter(Collider other)
{
//检测触发到的游戏物体的标签是不是“Food”
if (other.tag == "Food")
{
//销毁触发到的游戏物体
Destroy(other.gameObject);
}
}
查看游戏效果:
3.11 添加计分器
在游戏过程中,我们希望每次吃掉食物,都可以获取一定的分数,计分器选择分数累加的结果。
在设计计分器时,需要引进UI模型中的Text:
Hierarchy>>create>>UI>>Text,命名为 ScoreText
我们可以发现,除了我们新建的ScoreText,还多了Canvas和EventSystem,其中Canvas是画布层,也就是我们布置UI的位置,EventSystem是事件交互选项,用来布置按钮之类的,目前不会用到。
在进行UI设计之前,需要先进行Scene窗口设置:将 3D 切换为 2D,双击Canvas即可打开画布。可以调整Text的位置和大小直到得到满意的效果,还可以在属性面板更改颜色等。这里,我们将得分置于右上角:
此时,在游戏界面,得分也会相应显示在右上角:
这时,得分显示是固定的,我们希望分数能够根据我们吃食物的过程动态变化。这就需要我们在Player 的C#脚本中将分数与Text关联。
代码如下:
//引用系统提供的类
using System.Collections;
using System.Collections.Generic;
//引用Unity引擎
using UnityEngine;
//引入UI命名空间
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
//设置一个标签
public Rigidbody rd;
//设置一个得分标签
public int score = 0;
//设置一个Text的得分显示标签,在游戏运行之前我们需要将Text拖拽到这个标签下,建立连接
public Text scoreText;
//Start is called before the first frame update
void Start()
{
rd = GetComponent<Rigidbody>();
}
//Update is called once per frame
//60 frame/s 游戏一秒60帧
void Update()
{
//监听(得到输入)
//得到一个浮点数据
float h=Input.GetAxis("Horizontal");//a=-1,d=1
float v = Input.GetAxis("Vertical");//w=1,s=-1
//Debug.Log(h);
rd.AddForce(new Vector3(h, 0, v));
}
//触发检测事件
private void OnTriggerEnter(Collider other)
{
//检测触发到的游戏物体的标签是不是“Food”
if (other.tag == "Food")
{
//销毁触发到的游戏物体
Destroy(other.gameObject);
//每吃掉一个食物,得分加1
score++;
//将得分显示在Text中
scoreText.text = "分数:" + score;
}
}
}
效果显示:
3.12 添加游戏胜利标签
我们希望在吃完所有食物以后,可以显示游戏胜利的字样。
类似得分显示,我们需要先添加一个UI的Text选型,设定好想要显示的字符、样式以及位置。此时,可以先把这一游戏物体关闭,等到吃完所有食物后,再通过代码激活,最终显示在屏幕上。
代码如下图所示:
//引用系统提供的类
using System.Collections;
using System.Collections.Generic;
//引用Unity引擎
using UnityEngine;
//引入UI命名空间
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
//设置一个标签
public Rigidbody rd;
//设置一个得分标签
public int score = 0;
//设置一个Text的得分显示标签,在游戏运行之前我们需要将ScoreText拖拽到这个标签下,建立连接
public Text scoreText;
//设置一个游戏物体标签或者Text标签,将对应的WinText拖拽到此标签下,建立连接。
public GameObject winText;
//Start is called before the first frame update
void Start()
{
rd = GetComponent<Rigidbody>();
}
//Update is called once per frame
//60 frame/s 游戏一秒60帧
void Update()
{
//监听(得到输入)
//得到一个浮点数据
float h=Input.GetAxis("Horizontal");//a=-1,d=1
float v = Input.GetAxis("Vertical");//w=1,s=-1
//Debug.Log(h);
rd.AddForce(new Vector3(h, 0, v));
}
//触发系统事件
private void OnTriggerEnter(Collider other)
{
//检测触发到的游戏物体的标签是不是“Food”
if (other.tag == "Food")
{
//销毁触发到的游戏物体
Destroy(other.gameObject);
score++;
scoreText.text = "分数:" + score;
//因为总共有10块食物,当吃光所有食物后,游戏结束,激活游戏胜利显示
if(score == 10)
{
winText.SetActive(true);//激活为 true, 关闭为 false
}
}
}
}
显示效果为:
到这里,游戏设计基本结束了!大家可以发现,我们在实现过程中有些部分还需要拖拽游戏物体到指定标签来建立连接实现。事实上,这些完全可以通过代码来完成,后续将会讲到。文章来源:https://www.toymoban.com/news/detail-415531.html
4 游戏打包
在第3节中,我们完整创建了一个游戏。这一节也是本讲的最后一节,将为大家介绍下制作出来的游戏如何进行打包。
首先,进行打包设置:
File>> Build Settings>>Player Settings :
在这里,我们可以设置分辨率、游戏模式(全屏 or 窗口)等
接着,返回到 Build Settings 进行游戏输出:
依次选择要输出的画面和输出平台
输出到某一指定文件夹中,点击对应的 .exe文件即可打开游戏:
至此,第一个游戏的全部工作已经结束,当然其中涉及到的Unity和C#编程知识还只是冰山一角,后面再接再厉!奥利给!!再次感谢 Siki老师以及Siki学院!文章来源地址https://www.toymoban.com/news/detail-415531.html
到了这里,关于Unity 3D 学习(一)——Roll a ball的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!