入门案例 - 3D古迹冒险

该文详细介绍了在Unity中创建3D古迹冒险场景的步骤,包括地形设计、贴图应用、碰撞检测、灯光设置和导航网格生成等关键技术。通过调整地形高度、粉刷贴图、放置植被和树木,以及添加动态元素如火堆和粒子效果,构建了一个生动的冒险环境。同时,文章还讲解了如何使用NavMeshAgent实现角色寻路,以及通过动画系统控制角色动作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

入门案例 - 3D古迹冒险

地形设计基础

创建Terrain[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKh41v53-1681220998518)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411115053277.png)]

设置长宽50*50

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wqg3hLTZ-1681220998519)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411115209391.png)]

创建地形之后会自动生成一个这样的文件保存地形数据

height是地形最大高度

Raise/Lower工具

升降地形

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tr168E50-1681220998519)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411115404571.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Oe0YgjJ-1681220998520)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411115630176.png)]

关掉每次自动生成,因为太吃性能了

降低地形

按住Shift之后再粉刷就是降低地形了

PaintHeight工具

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D7gE3TQt-1681220998520)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411121018303.png)]
Height设置

设置地形抬高的最高点

Flatten

用来把整个地形粉刷到某个高度上

注意这个粉刷高度不会高于最大高度

SmoothHeight工具

让地形变得更平滑

PaintTexture绘制贴图工具

Add

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hppabc1h-1681220998520)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411121509162.png)]

在这里添加地图

同时需要法线和正常贴图

Edit

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AicjlY6l-1681220998521)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411121611168.png)]

可以在这里去掉法线贴图

Remove删除

Edit Textures - Remove

这样就移除了

粉刷

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1AGC22ER-1681220998521)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411121913197.png)]

第一章贴图会覆盖整个地形,第二章贴图需要单独粉刷

PlaceTrees种树工具

Add

Edit Trees - Add Tree

Remove移除

Edit Trees - Remove Tree

按住Shift可以减少树的数量

Paint Details工具

用来粉刷细节,植被

Add Grass添加草

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a0hrcrh6-1681220998521)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411123228163.png)]

Opacity修改密度,草只需要一张贴图

古迹探险关卡搭建

基础搭建

创建主角

思路:先通过人物和地形的比例掌握大小

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5BfaG0nB-1681220998522)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411130327673.png)]

通过主角和cube的大小比较

创建地形

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MM3ziJex-1681220998522)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411131400525.png)]

把光光调低一点,方便观察细节

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJ6r107A-1681220998522)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411131440544.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oYnqKnvk-1681220998522)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411131545232.png)]

上贴图

基础贴图 设置大小为20*20

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Dk6A7hM-1681220998523)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411132131645.png)]

用预制体模型的Rock做点山

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z5TV27PH-1681220998523)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411133010013.png)]

加石头等装饰

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cs9SkMHJ-1681220998523)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411133917560.png)]

添加植被

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lPftbKOe-1681220998524)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411134726664.png)]

稍微调节一下大小和方位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LDsSfpER-1681220998524)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411135648353.png)]

添加树木

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7kVGnBYw-1681220998525)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411140823040.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t4EW7vHn-1681220998525)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411141643251.png)]

碰撞器

替换地形的碰撞器,把地形自带的Terrain Collider(因为这个碰撞不正常)禁用掉,添加一个Box Collider

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gx7EFsMQ-1681220998525)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411143022639.png)]

从正上方用ISO视野编辑碰撞器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cj0PMk5q-1681220998525)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411143104007.png)]

选中Edit Collider

碰撞体检测函数

在代码里检测物体碰撞

碰撞脚本给到主角/sphere

OnCollisionEnter/Exit/Stay方法
    //碰撞检测方法
    //当小球跟其他物体发生碰撞时,就会调用这个方法
    private void OnCollisionEnter(Collider collision)
    {

    }
    //当小球结束碰撞时调用
    private void OnCollisionExit(Collider collision)
    {

    }
    //碰撞持续的时候调用这个方法
    private void OnCollisionStay(Collider collision)
    {

    }

碰撞信息获得

        print(collision.collider);
        print(collision.collider.name);
        print(collision.collider.tag);

注意,碰撞检测至少需要发生碰撞的物体中一个有刚体

两个物体都得有碰撞器Collider

触发检测

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-edJlDQgS-1681220998526)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411160231073.png)]

勾选上Is Trigger变成触发器

和碰撞器的区别:触发器时没有碰撞的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R6yhrVQq-1681220998526)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411160334704.png)]

取消掉Mesh renderer就能隐形[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZBoJxmd-1681220998526)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411160522490.png)]

OnTriggerEnter/Exit/Stay方法
    //触发检测
    void OnTriggerEnter(Collider other)
    {
        print("OnTriggerEnter" + other);
        print("OnTriggerEnter" + other.name);
        print("OnTriggerEnter" + other.tag);
    }
    void OnTriggerExit(Collider other)
    {
        print("OnTriggerExit" + other);
        print("OnTriggerExit" + other.name);
        print("OnTriggerExit" + other.tag);
    }
    void OnTriggerStay(Collider other)
    {
        print("OnTriggerStay" + other);
        print("OnTriggerStay" + other.name);
        print("OnTriggerStay" + other.tag);
    }

Unity中的四种灯光

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jkgEHxnh-1681220998526)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411162052167.png)]

这个数值影响亮度

旋转会影响光线角度

DirectionalLight

平行光会影响大光照,天空盒太阳的位置

PointLight 点光源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I6MOPvWp-1681220998526)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411162939552.png)]

球体是点光源发散的范围

SpotLight聚光灯

锥形的大小和圆圈的大小都是可以调节的[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wxco8eov-1681220998527)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411163215652.png)]

AreanLight区域光

主要是在烘焙的时候使用的

给场景添加火堆

先打些点光源照亮轮廓

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8bemJuMJ-1681220998527)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411163556101.png)]

先把平行光主光源调整暗

用点光源照亮四周的环境

颜色改成偏蓝一点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DEstor02-1681220998527)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411164245204.png)]

创建火堆

没啥好说的,用一个石墩和火台和点光源做成预制体

LightingMapping光照贴图

如果不使用Lightmapping的话,引擎内的光源都是实时计算的,非常吃性能;

用lightmapping的话,就直接吧光照烘焙成贴图了,省性能

操作
  1. window - lighting - setting 打开光照的窗口
  2. 需要烘焙的内容,静态static都给勾选上;在光线里,只选择需要烘焙的物体,比如火炬
  3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ugfSos41-1681220998527)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411180026962.png)]直接在这里选择GenerateLighting就能生成光照贴图;能看到烘焙完之后整个场景亮了一点,因为相当于贴图上已经又一层灯光效果了,所以这里把灯光给禁用掉;禁用之后防线整个场景都黑了,因为灯光没烘焙上;
  4. 不仅要把物体设置为静态的,还要选出所有需要烘焙的灯光,吧需要烘焙的灯光属性从Realtime改成baked,然后重新进行烘焙[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2B2CsaLA-1681220998528)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411180550922.png)]烘焙结束之后把所有灯光禁用掉也不会影响光照了[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fFJLvgtl-1681220998528)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411180722662.png)]
  5. 这时候感觉光线有点亮,可以通过修改直射光的方式,方式再重新烘焙
  6. 火光改成mixed模式,继续用烘焙也需要实时计算

使用粒子系统创建火焰

用火堆实现粒子系统

右键Effects - ParticleSystem

通过shape模式修改形状

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Moh5SX4y-1681220998528)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411194815650.png)]使用随机速度

修改粒子的材质

先给一个例子使用的材质

shader选择 Particles/Additive

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1XibIjJu-1681220998528)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411195000371.png)]

然后拖拽赋值材质

颜色使用白色

把材质指定给粒子系统
Render

先把材质给到render

然后设置动画播放

Texture Sheet Animation

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H27TyxTw-1681220998529)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411195237523.png)]

在这里设置4*4

发射数量改成随机[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0wO70XnU-1681220998529)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411195754825.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovd00lmh-1681220998529)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411195920591.png)]

设置size over lifetime的曲线为从大变小

利用动画系统给灯光加上闪烁效果

操作

选中灯光,windows - animation - creat

通过控制强度关键帧实现,需要打开录制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vPwIGWrN-1681220998529)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411201558024.png)]

给灯光添加运动让他们看起来没那么同步[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u1DfxW51-1681220998530)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411202142077.png)]

导航网格生成

先烘焙导航网格

windows - Navigation - Bake

取消草的Navigation就能在烘焙时穿过草

取消石头的可行走区域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWUyyrs7-1681220998530)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411204536787.png)]

把所有石头在Object里设置成not walkable

给主角添加导航组件Nav Mesh Agent

让这个体积和主角保持一致

撰写脚本

拿到鼠标坐标的脚本

    //用射线检测获取目的地
    //判断是否输入
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                print(hit.point);
            }
        }
    }
//得到寻路组件
public NavMeshAgent agent;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JGzLb98G-1681220998530)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411205603381.png)]

专项速度通过Angular Speed控制

控制摄像机跟随

//拿到跟随目标
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 = offset + hero.position;
}

给角色加动画

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ivwJ5yuG-1681220998530)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411210605845.png)]

先赋值状态机

吧idle给到默认状态

根据速度判断是否切换动作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eqqDzE5c-1681220998531)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411210846999.png)]

当速度大于0,就切换Walk

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhp0gYHz-1681220998531)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230411210936353.png)]

统一取消淡出时间

所有脚本

英雄移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Hero : MonoBehaviour
{


    //得到寻路组件
    public NavMeshAgent agent;
    //用射线检测获取目的地
    //得到状态机组件
    public Animator anim;




    //判断是否输入
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                //print(hit.point);
                agent.SetDestination(hit.point);
            }
        }

        anim.SetFloat("Speed", agent.velocity.magnitude);
    }


    

}

摄像机移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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 = offset + hero.position;
    }
}

tions;
using System.Collections.Generic;
using UnityEngine;

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 = offset + hero.position;
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值