什么是shader?什么是Material?

首先可以看一下官方文档:着色器 - Unity 手册,好吧我相信也不会有人看它的(不是。
这是一个非常非常浅薄的shader见解,这里我不会讲任何shader graph有关的信息。只讲代码以及渲染思路。

shader渲染管线

在现代渲染管线中,如果使用光栅化,那么一定离不开顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。而在unity中有第三种着色器——表面着色器(Surface Shader),表面着色器是Unity提供的一种高级抽象,简化了光照模型的实现。

这里简单地列出三种着色器来讲解他们的作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// vertex shader
v2f vert(appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex); // 将顶点从模型空间转换到裁剪空间
o.uv = v.uv; // 传递纹理坐标
return o;
}
// fragment shader
fixed4 frag(v2f i) : SV_Target {
fixed4 texColor = tex2D(_MainTex, i.uv); // 采样纹理
return texColor * _Color; // 返回最终颜色
}
// surface shader
void surf(Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex); // 采样纹理
o.Albedo = c.rgb; // 设置漫反射颜色
o.Metallic = _Metallic; // 设置金属度
o.Smoothness = _Glossiness; // 设置光滑度
}

在顶点着色器中,我们需要处理顶点的信息,一般包括顶点位置、纹理坐标。并打包将信息传递给片段着色器,片段着色器是顶点着色器插值的一个中间状态,比如我们需要渲染一条线,那么我们的顶点着色器就是判断点的位置,点的颜色,真正的渲染线上的每一个点由渲染管线插值得到插值后的位置和颜色,并使用片段着色器来计算最后的颜色。所以如果涉及到形变,首先想到修改顶点着色器,因为片段着色器无法修改位置。如果要修改颜色,需要使用片段着色器,最终的计算值由片段着色器来决定。
在一般的渲染管线中我们只需要顶点着色器和片段着色器其实已经足够了,非必要我们一般不使用所谓的surface shader。

什么是Material材质?

刚刚我们讲了shader可以做什么,shader就像一个模板一样,它指出了渲染方式。而材质就是一个shader的实例化,每个材质对应一个shader,可以进行不同类型的参数调整。

shader hello world

我们用一个简单好看的例子来展示shader的力量!
首先我们打开一个Unity项目(随意版本,随意渲染管线,无需PBR)。
首先创建一个标准计算着色器
![[../../../../assets/images/Pasted image 20250115201718.png]]
打开它:
![[../../../../assets/images/QQ_1736943477807.png]]
这里会创建一个简单的反色shader,可以看到里面有两个简单的shader,以及一堆看不懂的东西。不用在意,先来看这两个函数干了什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex); // 转换顶点坐标到相机坐标系
o.uv = v.uv; // 简单地复制uv
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv); // 采样纹理
col.rgb = 1 - col.rgb; // 颜色取反
return col;
}

首先是顶点着色器,它将物体的顶点坐标转换到相机坐标系,然后复制顶点的uv。然后片段着色器我们先使用uv坐标在主材质上进行采样,然后将颜色取反,最后输出颜色。其余部分的代码你可以暂时不了解。
然后在unity中再创建一个材质:
![[../../../../assets/images/Pasted image 20250115202302.png]]
并将你的shader拖动到材质上:
![[../../../../assets/images/QQ_1736943831502.png]]
为什么得到了一个黑不溜秋的东西?因为我们的预览中是没有材质的!所以对材质采样会得到空的结构,我们可以给这个材质附上一个图片来测试我们的shader的效果,点击选中你的材质,然后在检查器中你可以看到纹理:
![[../../../../assets/images/QQ_1736943947838.png]]
点击选择,选择一张你喜欢的图片,然后就可以看到预览效果了!
![[../../../../assets/images/QQ_1736944860459.png]]

hexo设置加密文章(失败)

我们需要使用一个插件来实现,他叫hexo-blog-encrypt - npm,安装它也十分简单:

1
npm install hexo-blog-encrypt

在你的工作目录下安装好后,我们来设置它。

_config.yml

根据官方给出的实例,我们可以知道,encrypt插件可以通过设置tag来加密,比如下面的配置文件:

1
2
3
4
5
6
7
8
9
# Security
encrypt: # hexo-blog-encrypt
abstract: Here's something encrypted, password is required to continue reading.
message: Hey, password is required here.
tags:
- {name: encryptAsDiary, password: passwordA}
- {name: encryptAsTips, password: passwordB}
wrong_pass_message: Oh, this is an invalid password. Check and try again, please.
wrong_hash_message: Oh, these decrypted content cannot be verified, but you can still have a look.

从上往下可以看到

1
abstract : 

可以设置你的摘要
然后是

1
message : 

可以设置你的提示信息
再就是你的tag了,不同的tag可以设置不同的密码:

1
2
3
tags:
- {name: encryptAsDiary, password: passwordA}
- {name: encryptAsTips, password: passwordB}

最后是两个提示信息,第一个是密码错误的时候的提示信息,第二个我暂时不知道是什么含义:

1
2
wrong_pass_message: Oh, this is an invalid password. Check and try again, please.
wrong_hash_message: Oh, these decrypted content cannot be verified, but you can still have a look.

但是由于奇怪的问题,我的fluid似乎无法正确的展示这个功能,我无法提交我的密码。我可以确定不是我浏览器的问题,因为我能正确的使用官方的demo。作废吧就此。

搭建一个多线程的MineCraft服务器

事实上,准备开始写这篇文章的时候我对MineCraft服务器的搭建一点都不熟悉,甚至还没有动手安装过任何一个插件,只和朋友一起玩过各种Forge或者Fabric服务器。但是我发现我的服务器难以承载我们的游玩,它的单核性能太弱了,我期待我们可以用极地的成本搭建一个至少流畅的服务器。这个成本有多低呢?E5-2680v4,一颗只需100个馒头。那么我们尝试搭建一下。

策略

  • Linux 操作系统
  • MCSM 守护进程
  • Luminol 服务端
  • 插件安装

平台配置说明

我的服务器使用Ubuntu进行搭建,本人对windows一点都不熟悉,希望使用windows搭建的小伙伴可以做参考。

如你们所见,我手里的其实是一台洋垃圾,但是它有不低的睿频和28核56线程,如果Folia调度足够给力的话,我应该也能流畅运行大约150名玩家。

使用MCSM作为守护进程

首先我们到主页MCSManager | 开源免费,分布式,一键部署,支持 Minecraft 和 Steam游戏服务器的控制面板找到相应的下载命令,比如我的linux就是

1
sudo su -c "wget -qO- https://script.mcsmanager.com/setup_cn.sh | bash"

MCSM使用自动安装。然后你需要找到你的机器的ip,如果你是租的服务器,你能连上它说明这个对你来说不是问题。真要查IP的话我只能给你一条指令了,看不懂也实在没办法了。

1
ip addr


我的测试机器没有公网地址,但是你得自己看懂哪个地址才能让你访问到。这里不过多赘述计网的事情。

打开你的MCSM的网络控制地址http://<your server i>:23333。设置管理员账号,能够访问说明你这个一步已经完成了。

下载Luminol服务器

首先来到Luminol的github主页
Luminol
选择想要的游戏版本对应的分支

然后点击Release:

复制需要的版本的游戏文件链接。

来到服务器,创建一个文件夹,并将刚刚复制的链接下载下来,下面是一个示例:

1
2
3
4
5
6
mkdir luminol
cd luminol
wget https://github.com/LuminolMC/Luminol/releases/download/1.21.4-ea34494/luminol-1.21.4-paperclip.jar
apt update
apt install openjdk-21-jre
java -jar luminol-1.21.4-papaerclip.jar

然后会自动下载游戏版本。第一次运行会直接退出,不要害怕和普通的MCServer一样,你需要修改eula的条款。
运行成功之后回到MCSM,创建一个实例,选择当前目录,再设置启动命令为上面命令的最后一条即可。

修复使用RigidBody2D实现击退效果时的叠加问题

在使用RigidBody2D实现击退效果的时候,我的敌人出现了一个奇怪的问题。我不断的攻击,会导致它每次的击退距离变远,我的击退代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
 public void Knockback(Vector3 pos){
if(!canKnokback||isDead) return;
var direction = (transform.position - pos);
kk direction.z = 0;
direction = direction.normalized;
StartCoroutine(KnockbackCoroutine(direction, KnokbackForce));
}
IEnumerator KnockbackCoroutine(Vector3 direction, float force){
m_rigidbody2d.AddForce(direction * force, ForceMode2D.Impulse);
yield return new WaitForSeconds(KnokbackForceDuration);
isHurt = false;
}

起初我怀疑是force的问题,所以我在每次击退前尝试把m_rigidbody2d.totalforce设置为零,后来没有作用。于是我联想到这个问题肯定与我的移动代码有关,这是我的移动代码:

1
2
3
4
5
6
7
8
9
10
virtual public void FixedUpdate(){
if(!isHurt&&!isDead&&canMove){
Move(m_currentSpeed);
}
}
protected void Move(float currentSpeed){
Vector2 position = m_rigidbody2d.position;
position += m_currentDirection * currentSpeed * Time.fixedDeltaTime;
m_rigidbody2d.MovePosition(position);
}

这个移动代码不会修改刚体的属性,只会进行一个刚体移动。导致我们的刚体速度不会受移动代码影响。而我们的AddForce函数是通过修改刚体的velocity成员来实现的。但是我们的移动代码优先级高于刚体的自动更新,导致这个没有体现出来。但是在敌人被攻击的时候,移动代码暂时停止工作,导致刚体的移动会生效,就会出现敌人每次被攻击才会累计速度。所以我选择在赋予敌人击退的前将它的速度修改为零。这样就修复了这个问题。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void Knockback(Vector3 pos){
if(!canKnokback||isDead) return;
var direction = (transform.position - pos);
direction.z = 0;
direction = direction.normalized;
m_rigidbody2d.velocity = Vector2.zero;
StartCoroutine(KnockbackCoroutine(direction, KnokbackForce));
}
IEnumerator KnockbackCoroutine(Vector3 direction, float force){
m_rigidbody2d.AddForce(direction * force, ForceMode2D.Impulse);
yield return new WaitForSeconds(KnokbackForceDuration);
isHurt = false;
}

解决Unity中的路径报错:DirectoryNotFoundException。

具体报错内容:

1
DirectoryNotFoundException: Could not find a part of the path "C:\Users\zhywyt\Unity\project\<project name>\<file name>".

这个问题是我在使用System.IO.File.WriteAllText(path, json);保存存档的时候发现的。

后来发现是路径中存在了:,这是绝对不允许的。以后碰到这个问题可以先检查文件名是否正确,然后再考虑网上说的路径过长……的原因,我感觉那个大概率是错误的说法。

如何创建一个朝向正确的飞行物?

在游戏的开发过程中,我们总是会需要创建一些飞行物,他们大多都有一些特性:

  • 可碰撞
  • 可旋转
  • 可导航(可选)

这不是件多难的事情,但是有一个点困扰了我许久,就是这个可旋转上,我们要的旋转当然是物体朝着移动方向的正确旋转,这里给出一个模板。分两部分代码,主要是生成子弹的外部调用部分和子弹自己的逻辑部分:

file
1
2
3
4
5
6
Vector3 direction = target.transform.position - transform.position;
direction.z = 0;
direction.Normalize();
var tempBullet = Instantiate(bullet, transform.position, Quaternion.LookRotation(Vector3.forward, direction));
tempBullet.SetActive(true);
tempBullet.GetComponent<EnemyBullet>().SetData(AttackDamage, direction);
file
1
2
3
4
5
6
7
8
9
// FixedUpdate
transform.position += new Vector3(m_direction.x, m_direction.y, 0) * Time.deltaTime * m_speed;

// SetData
public void SetData(int hurt, Vector2 direction)
{
m_hurt = hurt;
m_direction = direction;
}

主要不能错的是这两句:

1
2
3
4
5
6
7
// in file enemy
var tempBullet = Instantiate(bullet, transform.position, Quaternion.LookRotation(Vector3.forward, direction));
tempBullet.SetActive(true);

// in file enemyBullet
transform.position += new Vector3(m_direction.x, m_direction.y, 0) * Time.deltaTime * m_speed;

时间比较紧张,我先休息一下,有时间再来仔细讲解这份代码。

UI的位置无法正确的移动

我希望实现一个攻击的伤害反馈,在我写好伤害显示的脚本之后,我发现了一个奇怪的问题。我的伤害字体的位置与我设置的不一致,我尝试在内存中读取它设置后的位置,竟然和我设置的一样,但是在Unity中显示的不一样。并且只有y轴不同:
内存中的位置
Unity中的位置
我的代码如下:

我觉得我需要阅读一下Rect Postition类的定义了。并且我可以排除是Canvas的问题,我的Canvas是设置在物体上的,并且模式为世界模式。

最后发现是动画里记录了世界坐标的位置,所以每次生成会在世界坐标,导致我一直以为x是对的,没办法做出正确的判断。解决办法很简单,只需要给该物体添加一个父物体就可以了,唯一需要注意的是需要将销毁代码绑定到父物体上。

Hexo+Github搭建静态网站

2024-12-05 16:10
实际上,现在你所看到的博客是我使用hexo+Fliud主题加自己的服务器搭建起来的,那为什么又来搭建博客了?

2024-12-08 13:36
更新windows版本安装教程。

收到朱老师的要求(运动队教练),需要搭建学校运动队(定向越野队)的主页,于是想着长久为好的情况,选择了使用github来搭建,这样也方便队友们维护它。之后再写一篇博客维护交大家怎么用好了。这里顺便记录一下我们搭建Hexo的程过程,并学习一下GitHub Page的使用。

我任何时候都只推荐使用Linux来搭建类似的网站。

Hexo

Linux

安装Node.Js和Npm

hexo需要一些前置环境,由于它是基于Node.Js的,我们第一步就需要安装Node.Js。

1
2
sudo apt update
sudo apt install nodejs npm

测试:

1
2
node --version
npm --version

npm的安装时间可能有些久,如果网络不好请换源(STFW “ustc apt”)。这是我写这篇博客的时候的版本(2024-12-05 16:30):

1
2
3
root@HDUDX:~# node --version && npm --version
v18.19.1
9.2.0

是的,我测试的时候使用的是root用户,请不要模仿我,除非你有信心修好自己的机器。

安装Hexo

根据Hexo提供的命令:

1
npm install -g hexo-cli

我自然是全局安装,因为我使用的是容器开发。如果你介意全局安装你可以参考官网的局部安装,对后续不会产生影响。

测试Hexo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@HDUDX:~# hexo --version
hexo-cli: 4.3.2
os: linux 6.8.4-2-pve Ubuntu 22.04 LTS 22.04 (Jammy Jellyfish)
node: 18.19.1
acorn: 8.8.1
ada: 2.7.2
ares: 1.27.0
base64: 0.5.0
brotli: 1.0.9
cjs_module_lexer: 1.2.3
cldr: 44.1
icu: 74.2
llhttp: 6.1.0
modules: 109
napi: 9
nghttp2: 1.59.0
openssl: 3.0.13
simdutf: 3.2.18
tz: 2022a
unicode: 15.1
uv: 1.48.0
uvwasi: 0.0.19
v8: 10.2.154.26-node.28
zlib: 1.3

Windows(失败)

安装 Node.Js

Site Unreachable

选择安装程序安装:

安装你想要的版本,最好选择最新的LTS版本,下载好后运行安装即可。

1
npm.cmd --version

安装Hexo

1
npm.cmd install hexo-cli -g

这一步我等了很久,失败乐,Windows还是别用了。我受不了了。

创建第一个站点!

使用以下指令来创建一个站点,它会在当前文件夹下生成同名文件夹:

1
hexo init <Your site name>

Nodejs比较慢,你可以尝试代理或者其他方式来加速。成功了像这样:

然后进入站点,安装依赖:

1
2
cd <Your site name>
npm install

项目里会有这么一些东西,我稍微介绍一下,之后可以自行深入了解:

  • _config.landscape.yml
    • 我们的初始主题叫landscape,这是主题的配置文件
  • _config.yml
    • 这是hexo的配置文件
  • node_modules
    • 这是node.js的包
  • source
    • 这是您的md文件,会以page的形式组织,特殊的_posts是您的所有博客文件
  • themes
    • 这是主题文件夹,下载的主题放在里面
  • public
    • 这个文件夹你可能还没有,这是生成的前端文件,主要是html和css

本地部署测试

1
2
3
4
// 生成命令,将你的md文件编译成前端文件
hexo g
// 启动服务命令,启动apache,在你的4000端口开发服务
hexo s

你可以访问本地的http://localhost:4000,使用Ctrl + C中止它,这不是我们的目的。

Github

申请Github组织

相信你自己的Page肯定已经部署了其他服务了,对于组织类型的站点,我们可以使用组织的子域名来做。

找到组织页面,创建一个新的组织,名字依据你们组织来定,我为杭电定向队创建:

创建同名项目

我们暂时跳过加入成员的过程,在组织下创建一个同名项目:


需要注意的是你的仓库名设置为<组织名>.github.io,这与你的page类似。然后设置为公开的。

Hexo + Github

远程插件

我们需要一个插件来帮我们一键同步到github仓库中,我们安装这个插件:

1
npm install hexo-deployer-git --save

然后我们修改以下_congig.yml文件,使用你自己熟悉的文本编辑器打开它:

1
vim _config.yml

找到# Deployment项,它应该在最底部,修改信息:

1
2
3
4
5
6
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: 'git'
repository: <Your project url>
branch: master

创建我们的ssh-key

使用以下命令创建key,并一路回车。

1
root@HDUDX:~/hdudx# ssh-keygen

你的key会生成在~/.ssh/下,找到pubkey。你可以使用你喜欢的方式查看它:

1
cat ~/.ssh/id_rsa.pub

打开DeployKey并设置

找到你的组织的设置->DeployKeys->Enable->Save

我们打开这个,就不需要将机器的ssh key放在我们的用户信用名单中,而可以对单个项目进行配置,这非常好。打开之后找到我们的项目的设置:

将我们机器的公钥填入,并勾选允许写访问

一键部署

然后我们回到机器,尝试运行部署指令:

1
hexo d

如果出现这样的问题:

请检查你的key是否设置正确,正确的运行结果类似这样:

然后检查我们的仓库时候已经有了文件:

此时你迫不及待地打开专属你的网址,可能出现404,不要沮丧,打开你的项目设置,找到Pages,选择正确的分支和文件夹,并保存。不出意外的话在1分钟后就会得到正确的结果了!可以尝试访问我们的网站:杭州电子科技大学定向队

主题选择

首先去官网找主题Themes | Hexo(PS:主题来自社区,Hexo不保证其安全性)。

推荐主题

GitHub - Yue-plus/hexo-theme-arknights: 明日方舟罗德岛阵营的 Hexo 主题,支持数学公式、Valine&Gitalk&Waline评论系统、Mermaid图表

GitHub - xaoxuu/hexo-theme-stellar: 内置文档系统的简约商务风Hexo主题,支持大量的标签组件和动态数据组件。

2024-12-05 18:21
快照,看看我两个多小时的成果:

源码/前端分家

我们使用hexo d实现的其实只是将我们的public里的文件上传到github上,但是我们的Markdown文件其实无法保存在云端,这个时候就有一个天才站出来了,说:我们用两个分支,分别存储源码和前端不就好了吗?于是这个解决办法就这样孕育而生了:

伤病遇体测有感

伤病遇体测有感

晴空刚正好,
千米路不遥;
一路领跑不惧畏,
三分零五不觉累。

此番故地游,
蹒跚道旁走;
五分散步犹嫌赘,
七分彳亍痛仍最。

噫嘘唏!叹伤痛何时退?!

——zhywyt

Unity2D场景交互设计

触发器设计

对于存在剧情以及玩家交互的触发器,我们一定存在一个任务作为导向,所以我将这类存在任务的触发器作为了一个抽象类Warnner封装,并设计了三个特殊的预制体与之相搭配使用。所有的触发物只有设置了Intertag才能被全局索引到。

触发器分类依据

我将触发器分为了四类:

  • 直接触发物 Direct
    • 无需碰撞检测,进入场景即尝试触发。
  • 碰撞触发物 Trigger
    • 只检测碰撞,碰撞发生即尝试触发。
  • 主动触发物 Active
    • 检测碰撞并等待玩家交互,碰撞后等待玩家交互,碰撞结束停止监听。
  • 基本触发物 Inter
    • 无交互,可以设置是否初始激活、可以被当前场景索引

直接触发物

WarnnerType : DirectInteration
需要配置的内容有:

TaskId DelSelf
任务ID 触发后是否deActive自己

特殊的,直接触发物,无需配置碰撞体积,只需要放在对应场景即可。会在玩家加载场景后不断检测触发,除非有 DelSelf 为 true 或者RejectKey是GiveKey的子集。

碰撞触发物

WarnnerType : TriggerInteraction
相比直接触发物,需要配置一个Collider2D的碰撞体,并设置为Trigger,我为设置了一个Box Collider2D的预制体,如果需要可以设置为其他碰撞体(Box、Circle、Capsule),不会影响脚本效果。需要配置的内容有:

TaskId DelSelf WarnIfTheKeyIsNotEnough Collider2D碰撞体(Trigger)
任务ID 触发后是否deActive自己 是否在检查物不足的时候提醒玩家 请务必设置为Trigger

主动触发物

WarnnerType : ActiveInteraction
主动触发物是最复杂的触发物,需要配置一个Collider2D的碰撞体,并设置为Trigger,同时可以为该触发物配置一个Question子物体,会在玩家进入碰撞范围的时候将该物体激活,并播放动画(默认动画)。需要配置内容:

TaskId DelSelf WarnIfTheKeyIsNotEnough Question子物体 Collider2D碰撞体(Trigger)
任务ID 触发后是否deActive自己 是否在检查物不足的时候提醒玩家 可选(提醒物)使用名字索引 请务必设置为Trigger

基本触发物

使用脚本Inter
基本由于我发现部分触发物不存在任务,并且想要实现场景逻辑需要一部分可索引但是不需要任务的物体(被任务触发物调用),所以我编写了一个基类当作基本触发物,只有触发物id是否在起始投放属性,并且可以被全局索引到,可以满足关卡的编辑,比如我们的藤曼、大门等等。基本触发物只需要设置触发物id即可,系统会从数据库中读取另外一个属性。需要配置内容:

InterId
触发物Id

特别注意的是,这里配置的不是任务ID,而是触发物ID。

触发物补充说明

Unity的场景加载会重置场景中的所有的信息,也就是说触发物状态也会重置,会导致如果以当前策划表格进行编写的话会出现大量重复的剧情播放,所以需要策划老师辛苦将只需要单次播放的任务或者触发物使用check&reject系统隔离开,比如只触发一次就拒绝本任务发放给玩家的物品。

例子

这是目前的所有触发器预制体,我会介绍每一个预制体的使用方法以及对场景的设计思考。
目前的四大预制体
我会以一个具体的例子来使用到所有的触发器,以便后续使用。

场景说明

我们简单地布置这样一个场景:

  • 进入场景播放一段CG
  • 场景内存在一个必须触发的物体,且需要玩家发现并交互(非碰撞需求)
  • 场景内存在一个需要玩家碰撞触发的物体
  • 一个影响玩家移动区域的障碍触发物

这里就对应了我们的四种触发器,进入场景直接播放CG我们可以使用直接触发器来实现,需要玩家寻找的触发器我们可以使用主动触发器来实现,需要碰撞直接触发的物体,我们使用碰撞触发器来实现,而最后一个只影响玩家移动的“障碍物”,但是需要为剧情服务的时候,我们可以使用基本触发物来实现。

直接触发物实例

我们直接放置一个直接触发物在场景中,无需为它设置渲染。并为它配置任务ID即可。
直接触发物的配置信息

主动触发物实例

对于第二个主动触发器,使用主动触发器预制体,默认配置了一个圆形碰撞体:
主动触发物的配置信息
可以点击编辑碰撞体按钮来调整触发物的响应区域。
主动触发物的碰撞体也是它的可响应区域
如果需要其他类型的碰撞体,可以先删掉这个碰撞体
移除组件的方法
然后添加一个新的碰撞体,在检查器(Unity的物品检查器)的最下方找到添加组件,搜索Collider 2D选择想要的类型添加,并设置为触发器:
可以添加的碰撞体类型
主动触发物的碰撞体需要设置为触发器
然后检查触Warnner脚本中的发器类型、设置任务ID,特别的,这里可以勾选是否提醒、是否deActive自己(触发后)。
主动触发物的配置信息
最后是可选的Question物体,默认的主动触发物是配置了一个子物体的,但是默认是未激活的,如果想要预览它,可以勾选激活,这样就能看到该物体了。
Question子物体默认是不激活的
在选中Question的情况下,你可以找到动画窗口,创建新的动画。动画请保存在\Assets\Animation\warnning\下。
创建动画的方法

碰撞触发物实例

碰撞触发物体很多时候都不需要渲染,比如我们的门、检查物等等。但是我们还是需要一个碰撞体来检测玩家的进入:
加入一个碰撞触发物,默认是没有渲染的,但是我们在编辑器中可以看到它的碰撞体:
碰撞触发物的碰撞体
这个绿色的框是它的碰撞体积,同理,碰撞触发物也可以更换碰撞体,更换方式和主动触发物相同。
碰撞触发物的各种配置
配置也和主动触发物类似。

基本触发物实例

基本触发物体比较简单,一般设置为静态物体,不允许移动,并将碰撞体的“触发物”选项取消。(默认的预制体已经配置好了这些)
基本触发物的各种配置信息
基本触发器的碰撞体设置为非触发器
然后可以只需要设置Inter Id即可。

预制体说明

Unity中的预制体是一种类似于基类的存在,从项目窗口中将预制体拖入场景,就会生成一个预制体变体,所有的预制体变体会随着基础预制体的改变而改变,但是基类不会反向改变,在层级窗口中,蓝色的是指预制体变体,每个变体的右边会有一个小箭头,点击就可以修改该预制体变体对应的预制体,你可以在这里修改该预制体,并影响所有的预制体变体。创建预制体的方式就是将层级窗口的物体拖入项目窗口。
层级窗口中的预制体

|