一、创建NPC角色
1. 创建JambiNPC并同时创建Jambi站立动画
(1)点击第一张图片,按住shift不松,再选中后两张图片,拖到层级面板中
(2)将动画资源文件保存到Animation Clips文件夹中
(3)将动画控制器文件保存到Animators文件夹中
2. 将Jambi添加为预制体
二、编辑NPC属性
1. 修改层级为NPC
(1)添加NPC层级
(2)将Jambi的层级设置为NPC层级
2. 精灵渲染器(Sprite Renderer)
(1)修改锚点为底部
(2)修改渲染层级为1
3. 2D碰撞箱(Box Collider 2D)
(1)添加 Box Collider 2D 组件(避免角色覆盖NPC)
(2)调整碰撞体积大小
三、创建对话框
1. 创建对话框画布
2. 修改对话框画布属性
(1)修改UI缩放模式为World(红色)
(2)修改渲染层级为10(对话框要显示在其他游戏物体上方,因此要大于其他层级)(蓝色)
(3)修改缩放为0.01(绿色)
(4)修改长度宽度,调整到合适的位置(黄色)
3. 添加图像子物体到对话框
4. 编辑图像子物体属性
(1)使图像填充对话框画布
(2)将对话框图片赋值给图像
5. 添加文本子物体到对话框
6. 编辑文本子物体属性
(1)使文本填充对话框画布内边缘,锚点在文本框的四个角
(2)调整字体大小(红色)
(3)使文本左右居中,上下居中(蓝色)
(4)更改文本内容(绿色)
(5)调整字体颜色(黄色)
(6)更改字体样式(粉色)
(7)添加OutLine组件,为字体增加边框
(8)改变字体边框的颜色
(9)最终效果如下图所示
四、添加NPC对话功能(射线检测)
1. 编辑Ruby脚本
(1)判断E键是否按下
public class Ruby : MonoBehaviour
{
void Update()
{
// 对话功能
if(Input.GetKeyDown(KeyCode.E)) { // 当按下E键时
}
}
}
(2)创建一条射线
public class Ruby : MonoBehaviour
{
void Update()
{
// 对话功能
if(Input.GetKeyDown(KeyCode.E)) { // 当按下E键时
// 创建一条射线:起点为角色的位置偏上(Vector2.up为向上的单位向量),方向为角色的朝向, 射线长度为1.5, 发生碰撞的游戏物体层级为NPC层
RaycastHit2D ray = Physics2D.Raycast(rb2d.position+0.2f*Vector2.up, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
// ray碰撞到的物体会存储到ray自身当中
}
}
}
(3)判断射线是否碰撞到物体
public class Ruby : MonoBehaviour
{
void Update()
{
// 对话功能
if(Input.GetKeyDown(KeyCode.E)) { // 当按下E键时
// 创建一条射线:起点为角色的位置偏上(Vector2.up为向上的单位向量),方向为角色的朝向, 射线长度为1.5, 发生碰撞的游戏物体层级为NPC层
RaycastHit2D ray = Physics2D.Raycast(rb2d.position+0.2f*Vector2.up, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
// ray碰撞到的物体会存储到ray自身当中
if(ray.collider != null) { // 若射线碰撞到的物体不为空
}
}
}
}
(4)使用Debug语句测试
public class Ruby : MonoBehaviour
{
void Update()
{
// 对话功能
if(Input.GetKeyDown(KeyCode.E)) { // 当按下E键时
// 创建一条射线:起点为角色的位置偏上(Vector2.up为向上的单位向量),方向为角色的朝向, 射线长度为1.5, 发生碰撞的游戏物体层级为NPC层
RaycastHit2D ray = Physics2D.Raycast(rb2d.position+0.2f*Vector2.up, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
// ray碰撞到的物体会存储到ray自身当中
if(ray.collider != null) { // 若射线碰撞到的物体不为空
Debug.Log("射线碰撞到的物体是:" + ray.collider.gameObject);
}
}
}
}
检测成功:
2. 创建NPCDialog脚本
(1)创建对话框游戏物体
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPCDialog : MonoBehaviour
{
// 创建对话框游戏物体
public GameObject dialogBox;
}
(2)设置初始时对话框为隐藏状态
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPCDialog : MonoBehaviour
{
// 创建对话框游戏物体
public GameObject dialogBox;
void Start()
{
// 设置初始时对话框为隐藏状态
dialogBox.SetActive(false);
}
}
(3)编写displayDialogBox方法,用来显示对话框
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPCDialog : MonoBehaviour
{
// 创建对话框游戏物体
public GameObject dialogBox;
void Start()
{
// 设置初始时对话框为隐藏状态
dialogBox.SetActive(false);
}
public void displayDialogBox()
{
// 设置对话框为显示状态
dialogBox.SetActive(true);
}
}
(4)创建浮点型变量DisplayTime为对话框显示时间,DisplayTimer为对话框显示计时器
public class NPCDialog : MonoBehaviour
{
// 创建对话框游戏物体
public GameObject dialogBox;
// 对话框展示时间
public float displayTime = 4;
public float displayTimer;
void Start()
{
// 设置初始时对话框为隐藏状态
dialogBox.SetActive(false);
}
public void displayDialogBox()
{
// 设置对话框为显示状态
dialogBox.SetActive(true);
}
}
(5)在DisplayDialog方法中设置计时器的值为最长显示时间
public class NPCDialog : MonoBehaviour
{
// 创建对话框游戏物体
public GameObject dialogBox;
// 对话框展示时间
public float displayTime = 4;
public float displayTimer;
void Start()
{
// 设置初始时对话框为隐藏状态
dialogBox.SetActive(false);
}
public void displayDialogBox()
{
// 设置对话框为显示状态
dialogBox.SetActive(true);
// 重置计时器
displayTimer = displayTime;
}
}
(6)编辑Update函数,若对话框为显示状态,则开始计时。当计时器小于0后,设置对话框为隐藏状态
public class NPCDialog : MonoBehaviour
{
// 创建对话框游戏物体
public GameObject dialogBox;
// 对话框展示时间
public float displayTime = 4;
public float displayTimer;
void Start()
{
// 设置初始时对话框为隐藏状态
dialogBox.SetActive(false);
}
private void Update()
{
if(dialogBox.active) {
displayTimer -= Time.deltaTime;
if(displayTimer < 0) {
dialogBox.SetActive(false);
}
}
}
public void displayDialogBox()
{
// 设置对话框为显示状态
dialogBox.SetActive(true);
displayTimer = displayTime;
}
}
3. 修改Ruby脚本
(1)删除Debug语句,创建NPC对话对象为ray碰撞到的物体对话组件
public class Ruby : MonoBehaviour
{
// 对话功能
if(Input.GetKeyDown(KeyCode.E)) { // 当按下E键时
// 创建一条射线:起点为角色的位置偏上(Vector2.up为向上的单位向量),方向为角色的朝向, 射线长度为1.5, 发生碰撞的游戏物体层级为NPC层
RaycastHit2D ray = Physics2D.Raycast(rb2d.position+0.2f*Vector2.up, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
// ray碰撞到的物体会存储到ray自身当中
if(ray.collider != null) { // 若射线碰撞到的物体不为空
// 创建NPC对话对象为ray碰撞到的物体的对话组件
NPCDialog npcDialog = ray.collider.gameObject.GetComponent<NPCDialog>();
}
}
}
}
(2)当对话组件不为空时,设置对话框为显示状态
public class Ruby : MonoBehaviour
{
// 对话功能
if(Input.GetKeyDown(KeyCode.E)) { // 当按下E键时
// 创建一条射线:起点为角色的位置偏上(Vector2.up为向上的单位向量),方向为角色的朝向, 射线长度为1.5, 发生碰撞的游戏物体层级为NPC层
RaycastHit2D ray = Physics2D.Raycast(rb2d.position+0.2f*Vector2.up, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
// ray碰撞到的物体会存储到ray自身当中
if(ray.collider != null) { // 若射线碰撞到的物体不为空
// 创建NPC对话对象为ray碰撞到的物体的对话组件
NPCDialog npcDialog = ray.collider.gameObject.GetComponent<NPCDialog>();
if(npcDialog != null) { // 若对话组件不为空
// 设置对话框为显示状态
npcDialog.displayDialogBox();
}
}
}
}
}
4. 为Jambi添加NPCDialog脚本,并将Dialog游戏物体赋值到Dialog Box中
5. 最终效果如下图所示
(1)初始时:
(2)按下E键后:
(3)经过4秒后:
本章完。感谢阅读!