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


    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 设置地形的形状

    第一个按钮为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将地形变得平滑

    7. 添加贴图Texture:选择GrassRockyAlbedo

    将size改为20, 20

    8. 实现群山环绕的效果

    Prefabs->Rock_Large, scale为0.3

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

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

    Prefabs里的石头/ruin随意加

    10. 添加草/植被

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

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

    手动调整大小位置旋转

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

    总体效果:

    任务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

    任务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->Lantern_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:修改成一个曲线

    也可以修改粒子数量

    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,减慢动画播放速度

     

    任务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

    之后需要代码来告诉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(0)) {
                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(0)) {
                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; // 类似

     

    完成

  • 相关阅读:
    whereis which type find
    souce and bash 的区别
    systemctl daemon-reload
    linux /etc/profile bashrc bash_profile
    ulimt 和 sysctl
    MySQL 问题总结
    asyncio
    Linux 中 MySQL 操作
    总结一波 Redis 面试题
    os 模块 和 re 模块
  • 原文地址:https://www.cnblogs.com/FudgeBear/p/8012775.html
Copyright © 2020-2023  润新知