Siki_Unity_1-3_Unity零基础入门_古迹探险

时间:2023-12-17 21:51:32

1-3 Unity零基础入门 古迹探险

任务1/2:资料下载

链接:https://pan.baidu.com/s/1jHVymNk 密码:rbob

任务3:工程的创建和打开

Project:古迹探险

任务4:工程目录

任务5:资源的导入方式

方法1a. 在window->Asset Store->搜索

方法1b. 在Project面板上的搜索框内直接搜索想要资源的关键字即可,可以指定搜索范围

可以选为Asset Store(前提是在Edit->Preferences->General->勾选Show Asset Store search hits)

方法2. 从第三方.unitypackage中导入

将.unitypackage拖入工程面板即可

或是在工程面板右键Import Package->Custom Package,选择.unitypackage即可

方法3. 导入unity自带的资源(指的是安装unity自带的Standard Assets资源)

在工程面板右键Import Package->除了Custom Package之外的都是自带资源

如果在安装unity的时候没有勾选Standard Assets,则不会显示

Standard Assets里面的资源挺优质的

任务6:3D物体

1. 自带的简单3D几何体

cube/ sphere/ capsule/ cylinder/ Plane(单面显示,多用作地板)/ Quad面片(单面显示,小)/ Terrain/ Tree/ WindZone(风区,制造随风摇摆的效果)/ 3D Text等

2. 复杂的3D模型

Mesh Filter:网格,模型的形状

Mesh Renderer中的Materials:模型的特点,光滑度/透明等等

Texture:使用贴图

任务7:菜单栏

Mobile Input是Standard Assets中扩展出来的一个菜单,用来表示是否启动移动端的控制

GameObject菜单下方有一些有用的工具

Align With View:当想要把Camera的视角设置成当前Scene的视角的时候

任务8:工具栏

Center/ Pivot的区别

Center:中心点 有子物体的时候会计算平均的中心位置,可能会变化

Pivot:原点/ 坐标点 Position,在建模的时候一般就确定了

中间三个键:运行/ 暂停/ 逐帧运行

右上角Layers:每个GameObject都属于一个层,可以设定成锁定/不可见

任务9:窗口操作

任务10:Scene窗口下视野控制

飞行模式:按住鼠标右键进入飞行模式

鼠标移动进行视野旋转

WASD进行前进后退左右的控制

QE进行垂直上下的控制

任务11:Transform组件

任务12:控制物体移动的小技巧

Ctrl:

之前提到了按住ctrl移动物体的时候会一米一米地移动,那么步长可以修改吗?

Edit->Snap Settings->默认的move x/y/z 为1,可以修改

按住ctrl后也可以进行单位化的scale和rotate

v:

选定一个物体,按住v键,鼠标会自动吸附物体的顶点

可以将物体按照该顶点进行移动/ 旋转/ 缩放

移动时会将该顶点与其他物体的顶点进行吸附

任务13:导入资源,Prefab预制体

Prefab的instance中的Inspector上有Select/ Revert/ Apply

Select:会跳转到该instance对应的prefab上

Revert:

(如果instance的某些属性修改成和Prefab不同时,会以粗体显示,并且不会受到prefab的修改而改变)

Apply:点击某个instance里的Apply,会将该instance的属性值赋值给prefab(修改了prefab的属性)

如果有一个instance的prefab被删除了而仍需要保留该instance,但是instance会显示missing,在GameObject中选中break prefab instance即可;如果有某一个instance想脱离prefab的关联,也是选中break prefab instance即可

任务14&15:地形设计

作为开发,了解就好,团队里的美工会设计好的

3D Object->Terrain

选中pivot,从原点进行聚焦观察

创建一个Terrain后会在Project中自动创建一个New Terrain的文件,该文件保存了具体的地形数据,可以新建文件夹Terrains并命名为Terrain Data

组件:

Terrain Collider 地形的碰撞体

Terrain 设置地形的形状

Siki_Unity_1-3_Unity零基础入门_古迹探险

第一个按钮为Raise/Lower the Terrain Height:笔刷粉刷地形的时候地形会升高/(按住Shift)降低(最低值为0)

第二个按钮为Set the Terrain Height:升高地形,有一个height的值,升高的时候不会超过这个height,如果原地形的高度已经超过,则会慢慢降低地形直至该height;height旁边有一个flatten的按钮,会使整个地形的高度变为相同(flat),但不会超过maximun height

第三个按钮为Smooth the Terrain Height:将地形变化变得平缓

第四个按钮为Paint Texture:绘制贴图

Edit Texture->Add Texture,select texture: 分为Albedo Smoothness和Normal,Normal不是必要的。Normal选择后会将凹凸不平的细节显示地更好

可以添加多张贴图,第一张被添加的贴图会覆盖整个Tarrain,第二张被添加的时候不会有任何效果,需要通过鼠标进行粉刷

添加贴图的时候下面有一个size的选择:表示一张贴图的大小(需要粉刷多张贴图到整个terrain)

第五个按钮为Place Trees:放置植被

Edit Trees->Add Tree->选择Tree的prefab->add

之后用笔刷粉刷即可,按住shift粉刷为减少树;

可以设置brush size/ tree density/ tree height (random)/ Lock width to height/ color variation等

第六个按钮为Paint Details:一般用来粉饰小草/植被的细节

Edit details->Add grass texture->选择贴图->笔刷粉刷即可(Opacity为密度)

草是贴图,而树是模型,草会随着你的视野方向改变而面向你

第七个按钮可以设置大小等(默认长宽为500m,一个大格为100m);这里设置成50*50*height(此时一个大格为10m);高度height为地形的最大高度,设置成50

可以设置笔刷的形状/ 大小size/ 影响地形的快慢opacity

在修改地形属性的时候右下角会有一个Clustering的处理光照进度条,如果不想要这个处理的话(耗费性能),Window->Lighting->Setting->Scene->uncheck Auto Generate

任务16/17/18:古迹探险地形设计

1. 放置人物 Meshes->dwarf_hero

2. 如何知道hero的大小呢?

创建一个cube,大小对比;调节hero高度在1-2m之间即可

3. 创建Terrain;width:20,length:20,height:20

4. 将自动生成的Terrain数据命名并放入Terrains文件夹

5 将hero放在(10, 0, 0)的位置

6. 地形粉刷

思路:三面环山,中间略微有起伏

size 100 opacity 30 粉刷山脉

size 100 opacity 5 粉刷中间空旷地区起伏

使用smooth height将地形变得平滑

Siki_Unity_1-3_Unity零基础入门_古迹探险

7. 添加贴图Texture:选择GrassRockyAlbedo

将size改为20, 20

8. 实现群山环绕的效果

Prefabs->Rock_Large, scale为0.3

环绕三面摆放,并将每一块石头手动随机旋转/调节大小等

Siki_Unity_1-3_Unity零基础入门_古迹探险

9. 既然为古迹探险,加入Ruin元素

Prefabs里的石头/ruin随意加

10. 添加草/植被

Meshes->Vegetation->Low有多种草的模型

Meshes->Vegetation->Bushes有树的模型

手动调整大小位置旋转

11. 将所有环境有关的GameObject(树/石/Ruin)放入empty gameobject Env

总体效果:

Siki_Unity_1-3_Unity零基础入门_古迹探险

任务19:刚体

Mass 质量,可以控制惯性

Drag 摩擦力(移动时的阻力)

Angular Drag 旋转时的摩擦力

Constraints:冻结某个属性(刚体效果不改变某个属性)

任务20:碰撞器

Box collider是最节约性能的,越复杂的collider越耗费性能,Mesh collider最耗费性能

Mesh Collider:需要assign一个mesh,选择和Mesh Filter相同的mesh即可

比如想要给Rock_Large添加一个Mesh Collider,需要展开Rock_Large,选中里面的Group1,添加一个mesh collider,把mesh选择为Group1即可(会自动选择)

NB: 不需要太精细的情况下,没必要选择mesh collider,因为太耗费性能;如果你的mesh比较简单,那么选择mesh collider是可行的

任务21/22:碰撞检测函数/ 碰撞信息取得

void OnCollisionEnter/Exit/Stay(Collision collision);

碰撞检测是基于刚体的,也就是说即使有collider但是没有rigidbody,碰撞检测是不可用的

碰撞检测的条件:https://docs.unity3d.com/Manual/CollidersOverview.html

Siki_Unity_1-3_Unity零基础入门_古迹探险

任务23:触发检测

勾选collider的is trigger,使得该collider成为一个触发器,其他物体可以进入该collider内部

void OnTriggerEnter/Exit/Stay(Collider other);

任务24:Unity中的四种灯光

Create->Light->Directional Light/ Point Light/ Spotlight/ Area Light

Directional Light:直射光/ 平行光/ 太阳,它的position是没有影响的,只有rotation是有影响的;在天空盒子里可以看到一个太阳,太阳是位于直射光的后面的,当直射光旋转的时候,太阳的位置也会随之改变

Point Light:点光源/ 灯泡,属性Range,Intensity

SpotLight:手电筒/ 从一点发射一个锥形范围的光,锥形的大小和长度是可调节的

Area Light:区域光,主要用于烘培,实际环境的光照设置不会使用它

任务25:给场景添加火堆

古墓探险不需要太强烈的光,将directional light调成日出的状态(180, 90, 0), indensity 0.3

创建一个空物体Light,将Direcitional light放在其下,并添加一个Point light

调成暗紫色,intensity调弱一点,分别放几个在山上

调成弱黄色,放几个在空地上

创建火堆Bonfire:

Prefabs->*_01 火堆头

Prefabs->Barrier_02 火堆底

在Bonfire中创建一个point light,放置在火堆的正中间,颜色偏黄,intensity调强

制作成Prefab方便日后修改

任务26/27:Lightmapping

Lightmapping 光照贴图

如果不使用光照贴图的话,光在游戏运行时对场景的影响是需要实时计算的,耗费性能

如果使用lightmapping的话,会提前将光照计算好,烘培成贴图,将贴图贴在环境模型上,实际运行时就不需要实时进行计算了,能够很大提高性能

将Terrain,Env及其孩子勾选成static的;再将所有灯光也勾选成static

将所有灯光的mode选择成baked

Window->Lighting->Settings

Scene中的Debug Settings中点击Generate Lighting

会发现整个环境亮了许多,将直射光改为Rotation的x值改为191.2;点光源的range调小,重新烘焙

此时若是禁用了灯光,会发现环境下的灯光效果不变(不再是real time了)

但是这样的话火堆的效果就没有了,火焰需要一闪一闪的效果

火堆光的进一步改进:

将火堆光的mode改为mixed,表示即可以实时计算,又可以烘培

并将其的Shadow Type改为Hard Shadows或Soft Shadows(hard烘培时间会慢一点)

任务28:使用粒子系统创建火焰

在Bonfire下创建Effects->Particle System

Shape:修改成火堆的大小

Start Lifetime:生命时间改小一点 1.5

Start Speed:速度设置为Random between two constants 1~1.5

粒子样子:FX->Fire->flame 4x4,这是一个4*4的动画效果

在Fire中创建material flame,shader选择Particles->Additive;texture选择flame 4x4;颜色设置成白色

将该material指定给粒子系统

改变粒子系统的Renderer中的material即可

但是这时候texture的动画效果没有展示

勾选粒子系统的Texture Sheet Animation,将Tiles设置成4*4(4行4列的动画)

现在已经有火焰的效果了,但是粒子太大了

修改粒子系统的Start Size即可

粒子应该越来越小:

Size over Lifetime:修改成一个曲线

Siki_Unity_1-3_Unity零基础入门_古迹探险

也可以修改粒子数量

Emission中的Rate over time可以修改成1-20

任务29: 创建动画(火光闪烁)

通过动画系统实现灯光的闪烁

1. 选中Bonfire的点光源

2. Window->Animation->Create->将新建的Flicker.anim放在文件夹Animations中

会自动在Bonfire的点光源里创建一个Animator的组件,用来控制动画的播放;和在Animations文件夹下创建一个动画文件Flicker.anim和一个叫Point light的动画状态机

3. 编辑Flicker动画

Window->Animation,以打开animation窗口,并选中Flicker或点光源

Add Property->Light->Intensity 火光亮度

经过不同时间,调整intensity数值(火焰效果需要intensity的变化很大)

Add Property->Transform->Position 火光左右摇摆

把sample设为25,减慢动画播放速度

Siki_Unity_1-3_Unity零基础入门_古迹探险

Siki_Unity_1-3_Unity零基础入门_古迹探险

任务30:导航系统-导航网格生成

导航系统(寻路系统):角色朝某个地方运动时,通过导航系统寻找最短路径,并沿着最短路径到达指定位置,并会自动进行避障

进行导航网格的烘焙:

确保Env和Terrain的navigation static是勾选状态

生成导航网格

Window->Navigation->Bake

点击bake生成蓝色区域,为可行走区域

Agent Radius:控制不可行走区域的半径,修改成0.1

Agent Height:

因为草是可以穿越的,所以把草的Navigation static取消勾选

发现一些石头/树的上方也是可行走的,选中石头的Mesh renderer组件(Group1),Navigation->Object->Navigation Area->Not Walkable(树也类似)

控制Hero在导航网格上行走

给Hero添加导航组件Nav Mesh Agent后会自动生成一个圆柱体,用于计算某个区域是否可以穿过的参照,需要保证圆柱体和Hero模型大小保持一致:Radius/ Height

Siki_Unity_1-3_Unity零基础入门_古迹探险

之后需要代码来告诉Hero要去的目的地(下个任务)

任务31:通过导航系统控制英雄的移动

思路:通过鼠标在地面上点击的点作为目的地,让导航系统控制英雄向目的地移动

创建Hero.cs并attach到Hero

1. 获取目标位置:鼠标按下的时候,向鼠标点击的位置发射一道射线,判断射线和Terrain的哪一个位置发生碰撞,获取该位置

Input.GetMouseButtonDown(0); // 鼠标左键按下

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // main camera中的ScreenPointToRay()将屏幕坐标转换为一道射线;Input.mousePosition为屏幕坐标

RaycastHit hit; // 用来保存碰撞信息

Physics.Raycast(ray, out hit); // 如果与任意碰撞器发生碰撞,返回true;out参数hit为碰撞信息

hit.point; // 碰撞的地面位置(x,y,z)

2. 控制角色到达位置:将hit.point的点赋值给Nav Mesh Agent

using UnityEngine.AI;

public navMeshAgent agent; // 得到Nav Mesh Agent;

agent.SetDestination(hit.point); // 设置Nav Mesh Agent的目的地点

3. 成功,但是角色转向太慢了

Nav Mesh Agent->Angular Speed=360

public class Hero : MonoBehaviour {

    public NavMeshAgent agent;

    // Update is called once per frame
void Update () {
if(Input.GetMouseButtonDown()) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit)) {
agent.SetDestination(hit.point);
}
}
}
}

任务32:控制摄像机的跟随

调整相机的跟随位置(12.22, 7.27, -5) (39.3, 0, 0) (Hero位置(12.078, 1.363, 0))

创建FollowTarget.cs并attach到Main Camera上

public Transform hero; // 跟随目标的Transform(Transform组件就够用了)

private Vector3 offset; offset = transform.position - hero.position; // 偏移量

transform.position = hero.position + offset; // 相机位置的跟随

public class FollowTarget : MonoBehaviour {

    public Transform hero;
private Vector3 offset; // Use this for initialization
void Start () {
offset = transform.position - hero.position;
} // Update is called once per frame
void Update () {
transform.position = hero.position + offset;
}
}

任务33:控制角色的动画播放

动画效果为Animations中的四个动画文件,我们这里需要的是idle/ walk和run

通过动画状态机进行动画的控制

Hero->Animator中需要动画状态机

在Animation文件夹中创建Animation Controller,叫做HeroController,并赋值到Hero

编辑动画状态机:

选中Hero,Window->Animator

设置默认状态Entry,将idle动画拖到Entry

状态切换:

idle->walk; // 通过速度的检测来切换状态

如何获得Nav Mesh Agent中的Speed呢

在Animator窗口左侧Parameter中添加一个float speed

将walk动画拖到Animator窗口中

右键idle状态,make transition,指向walk状态

点击transition的线

在Inspector中添加一个condition:speed greater than 0

取消勾选Has Exit Time,因为动画的切换会随时发生

在Hero.cs中

public Animator anim; // 获取Animator组件

anim.setFloat("speed", agent.velocity.magnitude); // 赋值给speed

public class Hero : MonoBehaviour {

    public NavMeshAgent agent;
public Animator anim; // Update is called once per frame
void Update () {
if(Input.GetMouseButtonDown()) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit)) {
agent.SetDestination(hit.point);
}
} anim.SetFloat("speed", agent.velocity.magnitude);
}
}

walk->run; // speed>2时

run->walk; //类似

walk->idle; // 类似

Siki_Unity_1-3_Unity零基础入门_古迹探险

完成

Siki_Unity_1-3_Unity零基础入门_古迹探险