Unity2020 3DRPG游戏开发教程笔记

/ 0评 / 1赞 / 

有使用到的教程:
M_Studio : Unity2020 3DRPG游戏开发教程

使用的软件:
Unity hub 3.3.0-c1
Unity 2020.3.24f1c1 (64-bit)
Visual Studio 2019

平台:Windows 11 64-bit

前言:
这次一定 这次一定不放弃

Unity2020 3DRPG游戏开发

M_Studio

01:Create Project 创建项目导入素材

使用 Unity2020.2 创建新 3D 项目

安装 Universal RP 并将整个项目升级到URP

使用Unity版本:2020.2
创建3D项目,package manager中安装unversal RP,
右键创建Rendering=>Universal Render PipeLine=>Pipeline Asset(urp的设置文件)

菜单的Edit中选择Project Settings,切到Graphic选单,将刚才创建的设置文件拖到那个显眼的框框里面
支线:可以在Quality(质量)选单中为不同的渲染质量选择不同的渲染设置文件.

因为版本问题(Unity2020后不能在软件内使用资源商店),无法在软件内部访问Asset Store,需要在网页端进行资源导入.
回到Unity,打开Package Manager,切换Package到My Asset,选择你想要导入的素材,右下角download,再import
(选素材之前记得确认素材对渲染管线的支持情况)

在Edit=>Render Pipeline=>Universal Render Pipeline=>中可以升级当前场景或者当前项目的素材的渲染管线.

本节所使用的素材:
[场景]Low-Poly Simple Nature Pack
[角色]Dog Knight PBR Polyart

02:Build Level 尝试熟悉基本工具

还是要注意素材需要支持通用渲染管线

添加SkyBox:Windows-Rendering-Lighting-Envirinment-SkyboxMaterial

修改SkyBox在光照-环境-天空盒材质里

直接将项目素材从Assets拖拽到hierarchy(图层?)窗口,可以保留其初始的位置值

URP改变人物影子:
Max Distance:离镜头多少米开始渲染阴影
CascadeCount:分层级来渲染
Shadow Resolution:
开启HDR:后期Post Processing处理时会用到
Anti Aliasing(MAAA):抗锯齿
Soft Shadows:虚阴影
Normal Bias:调节阴影缝隙

场景LightingSetting
新版本需要自行创建Lighting Setting
Windows-Rendering-Lighting
LightMode:Baked Indirect
Lightmapper:GPU

颜色没有改变
在Environment内的Lighting Source改为Color;也可自己设置颜色

铺设&简单摆放技巧
V:定点自动吸附
选中摄像机,按下 Ctrl+Shift+F 可以将摄像机位置固定在当前位置下
收纳归类好习惯
用空的Object来分栏

摆放prefeb,完成简单场景

03:PolyBrush 发挥创意构建场景

PolyBrush:

Pack Manager中安装Poly Brush,并在它的页面中点开Samples,根据渲染管线导入对应 Shader
安装完成之后,菜单会多出一个Tool,选择Polybrush=> Polybrush Window打开Polybrush的悬浮窗
Polybrush窗口顶部的几个图标功能分别是:
地形高矮,地形柔化,地形颜色,刷预制体,刷图片

高矮:
左键上升,按住Ctrl再点击则是下降
Shift+滚轮是内圈大小,Ctrl+滚轮调整外圈大小
Direction可以选择变化方向,默认的Normal是法线方向,其他的建议自己尝试

柔化:
比较类似,大家动手试一试吧

颜色:
需要先用之前导入的shader创建对应的Material,拖拽至地面,刷的颜色才能生效

刷预制体:
可以将想要刷的预制体拖拽至调色盘(Current Palette)中,
选择想要刷的预制体,在Brush Loadout中可以调整出现的概率

按住Ctrl再点击便是删除
Hit Surface is Parent选项可以将刷进去的预制体变为地面的子物体,方便整理

ProBuilder:

安装ProBuilder,Samples中导入URP支持
Tool=>ProBuilder打开菜单,右上角三个点可以将文字描述更改为图标描述,按住Shift再移动鼠标可以看到功能介绍
有齿轮的则可以按住Alt或者Option点击出菜单
创建一个物体,形状选择Plane,下面的Width Segments和Length Segments可以设置长款的顶点数量
默认创建出的物体,锚点是在边角,在ProBuilder的菜单中选择中心点按钮(具体看视频)可以将锚点设置为中心

(可选)打开Project Settings=>Package Manager选项中开启Enable Preview Package,安装ProGrids
安装完成后场景左上角便会多一个图标,点击启动,可以增加参考线,以及移动吸附功能

因为ProBuilder创建的物体默认是正方形顶点,可以在ProBuilder菜单中找到那个长得像折纸的图标,将对应物体的顶点改为三角形连接

来自麦扣的作业:做一个地图!!!物体记得分类!!!

本节所使用的素材:
[SkyBox]FREE Skybox Extended Shader

04:Navigation 智能导航地图烘焙

polybrush的其他设置:

给材质球更改为Polybrush材质,使其可以用Polybrush上色

移动的时候,按住Ctrl+Shift可以吸附在表面上

在polybrush刷树的时候,按住V好像就能直接吸附了

调整可移动区域(设置导航)

给地板设置为静态(两种方法都可以):

然后就可以将地板设置为可行走的区域

然后可以选中所有的树,将其设置为 Not walkable

烘焙之后,将可以看到可移动区域。

给角色添加导航:

同时将烘焙代理的大小调整为角色大小

可攀爬角度一般是30°— 45°

添加导航的障碍:

胶囊为给物体描边,box为方形,以此来设置不可行走的范围

切割选项选中后,将会在地面上实时切割区域,将其设置为不可行走

05:MouseManager 鼠标控制人物移动

创建空对象,创建新的C#脚本并绑定上去

使用Enents:

using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

//Class EnentVector3 并非继承于MonoBehaviour,需要序列化
[System.Serializable]

//继承UnityEvent<Vector3>
public class EnentVector3 : UnityEvent<Vector3> { }

public class mousemanager : MonoBehaviour
{
    //用于保存鼠标点击的坐标点
    public EnentVector3 OnMouseClicked;
}

NavMeshAgent的文档链接

destination是导航的目标点

接下来使用的是:Camera.ScreenPointToRay

返回从摄像机通过屏幕点的光线。

另一个:Physics.Raycast

public static bool Raycast (Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask, QueryTriggerInteraction queryTriggerInteraction);

这个方法会返回一个RaycastHit类型的值,所以我们需要先创建一个RaycastHit类型的变量

//用于保存Physics.Raycast的RaycastHit类型的返回值
RaycastHit hitInfo;

为了让鼠标在触碰到不同东西时有鼠标指针的变化,同样需要用到射线碰撞返回碰撞信息

//使用Physics.Raycast画ray这条射线,碰撞点输出到hitInfo
if(Physics.Raycast(ray, out hitInfo))
{
    //鼠标光标切换
}

Physics.Raycast的定义:public static bool Raycast(Ray ray, out RaycastHit hitInfo);

在Update中执行SetCursorTexture();使其实时的检测这条射线的相关信息,并且实时的将hitInfo的信息返回

接下来是鼠标控制

void MouseControl()
{
    //如果鼠标按键0(左键)按下,并且hitInfo获取到的碰撞体不是null
    if(Input.GetMouseButtonDown(0) && hitInfo.collider != null)
    {
        //如果点击的碰撞体上的标签是Ground(鼠标点击地面)
        if (hitInfo.collider.gameObject.CompareTag("Ground"))
        {
            //?.的意思是判断前面的OnMouseClicked是否为空,不为空时执行Invoke将其启动
            OnMouseClicked?.Invoke(hitInfo.point);
            //每次鼠标点击地面,都会将那个点的坐标传回OnMouseClicked这个事件,OnMouseClicked这个事件可以将人物的NavMeshAgent的destination设置到这个点
        }
    }
}

到此为止鼠标控制.cs的全部代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

//Class EnentVector3 并非继承于MonoBehaviour,需要序列化
[System.Serializable]

//继承UnityEvent<Vector3>
public class EnentVector3 : UnityEvent<Vector3> { }

public class mousemanager : MonoBehaviour
{
    //用于保存Physics.Raycast的RaycastHit类型的返回值
    RaycastHit hitInfo;
    //用于保存鼠标点击的坐标点,在Unity界面显示
    public EnentVector3 OnMouseClicked;

    private void Update()
    {
        SetCursorTexture();
        MouseControl();
    }

    //设置指针贴图
    void SetCursorTexture()
    {
        //创建射线ray来自Camera:主摄像机获取点 来自鼠标
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        //使用Physics.Raycast画ray这条射线,碰撞点输出到hitInfo
        if (Physics.Raycast(ray, out hitInfo))
        {
            //切换鼠标贴图
        }
    }

    void MouseControl()
    {
        //如果鼠标按键0(左键)按下,并且hitInfo获取到的碰撞体不是null
        if(Input.GetMouseButtonDown(0) && hitInfo.collider != null)
        {
            //如果点击的碰撞体上的标签是Ground(鼠标点击地面)
            if (hitInfo.collider.gameObject.CompareTag("Ground"))
            {
                //?.的意思是判断前面的OnMouseClicked是否为空,不为空时执行Invoke将其启动
                OnMouseClicked?.Invoke(hitInfo.point);
                //每次鼠标点击地面,都会将那个点的坐标传回OnMouseClicked这个事件,OnMouseClicked这个事件可以将人物的NavMeshAgent的destination设置到这个点
            }
        }
    }

}

记得要将地面的Tag设置:

设置人物的转向速度、加速、停止距离:

在人物手持不同武器时,执行攻击敌人的指令会有不同的停止距离,例如大剑就会远一些,空手时会更贴近一些。

06:SetCursor 设置鼠标指针

为了不每一个角色、关卡都需要拖拽设置移动方法,需要进行改造:

将mousemanager设置为单例模式

//创建单例模式的mousemanager自身变量
public static mousemanager Instance;

void Awake()
{
    if (Instance != null)
        Destroy(gameObject);//删掉多余的
    Instance = this;
}

因为已经将mousemanager设置为单例模式,现在创建新的脚本后可以直接访问其中的方法

创建event事件

//Class EnentVector3 并非继承于MonoBehaviour,需要序列化
//[System.Serializable]

//继承UnityEvent<Vector3>
//public class EnentVector3 : UnityEvent<Vector3> { }
//用于保存鼠标点击的坐标点,在Unity界面显示
//public EnentVector3 OnMouseClicked;
public event Action<Vector3> OnMouseClicked;

Action是返回值为void的内置委托类型,如果遇到这类委托可以直接使用而无需自己定义

于是 在鼠标点击地面的那部分,触发启用了OnMouseClicked时,所有订阅了这个事件,添加进去的方法都会被执行

目前playercontroller.cs如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class playercontroller : MonoBehaviour
{
    private NavMeshAgent agent;

    //Awake会在游戏执行的最开始调用
    void Awake()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    //用于学习 注册暂时写到start
    void Start()
    {
        //事件添加订阅的方式是+=
        //想要添加订阅,要保证函数的命名方式定义方式与源完全一样,例中是Vector3
        mousemanager.Instance.OnMouseClicked += MoveToTarget;
    }

    //角色移动函数,注册自OnMouseClicked
    public void MoveToTarget(Vector3 target)
    {
        agent.destination = target;
    }
}

在本次更新,OnMouseClicked的作用从unity的拖拽改成了订阅事件,从触发unity内的NavMeshAgent变成了触发所有的订阅事件

记得把playercontroller拖拽到狗子身上

PNG格式图片导入后仍有背景:

将其全选,可直接设置为鼠标的Cursor

因图片质量不高,将其设置为

为图片设置变量;

public Texture2D 点击, 传送, 攻击, 目标, 光标;

使用switch来更改图标:

更改图标使用Cursor.SetCursor(某图片);

SetCursor()方法是将一个Texture2D的图片更改为光标,同时有一个Vector2 hotspot的值用于记录偏移量,因为光标一般只有左上角起作用,设置偏移量以保证如圆圈这种的光标能变得合理。

后面会将光标设置为像素32*32,因此偏移量是16,16

其他光标偏移量为0

if (Physics.Raycast(ray, out hitInfo))
{
    //切换鼠标贴图
    switch (hitInfo.collider.gameObject.tag)
    {
        case "Ground":
            Cursor.SetCursor(目标, new Vector2(16, 16), CursorMode.Auto);
            break;
        case "敌人":
            Cursor.SetCursor(攻击, new Vector2(0,0), CursorMode.Auto);
            break;
        case "传送门":
            Cursor.SetCursor(传送, new Vector2(16, 16), CursorMode.Auto);
            break;
        case "交互":
            Cursor.SetCursor(点击, new Vector2(0, 0), CursorMode.Auto);
            break;
        default:
            Cursor.SetCursor(光标, new Vector2(0, 0), CursorMode.Auto);
            break;
    }
}

07:Cinemachine & Post Processing 摄像机跟踪和后处理

导入包:Cinemachine,添加Virtual Camera。

此时MainCamera会被Virtual Camera操控

发表回复

您的电子邮箱地址不会被公开。