目录
创建任务数据
接受任务
创建任务 UI 面板
创建所需要的变量
对话所需的信息
对话的UI面板设置
创建对话&任务的 NPC
显示主对话窗口的内容
创建选项内容
奖励物品的显示
检测和更新任务进度
创建任务数据
- 创建任务基本变量
- 创建 QuestRequire 用来追踪我们要完成的任务目标
- 在 DialoguePiece 中加入 Quest 并设置一个新对话可以接受任务
• [CreateAssetMenu(fileName ="New Quest",menuName ="Quest/Quest Data")]
• public class QuestData_SO : ScriptableObject
• {
• [System.Serializable]
• public class QuestRequire
• {
• public string name;
• public int requireAmount;
• public int currentAmount;
• }
•
•
• public string questName;
• [TextArea]
• public string description;
•
• //需要三种任务完成的状态,npc才会有不同的反应
• public bool isStarted;
• public bool isComplete;
• public bool isFinised;
•
• public List questRequires = new List();
•
• }
此处在这里将变量改的名字相同:
在对话一栏中加入任务,这样方便根据对话来接受任务
然后设置对话:
DondestroyOnLoad的物体不能是子物体,因此:不能放在别人的子集
public class QuestManager : Singleton
{
public class QuestTask
{
public QuestData_SO questData;
public bool IsStarted {
get { return questData.isStarted; }
set { questData.isStarted = value; }
}
public bool IsComplete
{
get { return questData.isComplete; }
set { questData.isComplete = value; }
}
public bool IsFinished
{
get { return questData.isFinished; }
set { questData.isFinished = value; }
}
public List tasks = new List();
}
}
上面是QuestManager的一些物品信息,除此之外,还加入一个判断是否在列表中的用法,使用的是lamad表达式
思路很简单,做出选择后,判断选项中是否含有任务,然后判断玩家是否选择了接任务的选项,如果含有,则判断该任务是否在列表中了,如果不在列表中,则将该任务实例化,并且加入到QuestManager的单例的List中。
这样即可实现对话后加任务的思路。
除此之外,我们接取任务后还希望设置任务的状态为开始状态:
但是直接修改并没有用,这只是修改的临时变量的值。
因此需要在QuestManager中根据任务的数据来查找管理器的链表中对应的任务
随后在此处设定开始:
创建任务 UI 面板创建canvas:
创建一个panel附上图片,然后为实现任务左侧的滚动栏:
然后将滚动的栏删掉变成这样,(删除滑动条后记得调整viewport大小)
设定vertical group:
添加奖励:
添加item slot:
以及item tooltip
创建所需要的变量 对话所需的信息首先需要一个对话信息:
数据如下:含有当前对话的id、头像、文本以及选项
[CreateAssetMenu(fileName ="New Dialogue",menuName ="Dialogue/Dialogue Data")]
public class DialougeData_SO : ScriptableObject
{
public List dialoguePieces = new List();
}
[System.Serializable]
public class DialoguePiece {
public string ID;
public Sprite image;
public string text;
public List options = new List();
}
选项的SO:
[System.Serializable]
public class DialogueOption
{
public string text;
public string targetID;
public bool takeQuest;
}
此时unity对话SO如下:
逻辑:在Dialogue Data中有若干个piece,每个piece中有若干个ID、Text、Image和Quest,还包含有List
如果有Option,我们就通过获取其Target ID。
创建一个面板:
设定Panel
添加vertical layout Group:
添加对话框还有按钮并设定其位置:
再添加一个头像:
在这种情况下, 如果有button有text的话,布局就会比较乱,因此此处将头像图片放在Main Text下,并且锚点放在左边,这样锚点就是在对话框的左边了。
接下来还需要给Dialogue Panel添加verticalLayoutGroup,这样子物体才可以使用content size filter。
此时头像的图片是以文字为基准点,所以就在对话框的外面了:
这样可以使得按钮在比较靠右的位置。
为了使其能在竖直方向上拉伸:
然后在DialoguePanel和Main Text中都添加content Size Fitter
这样就可以根据文本数量的多少改变框的大小。
问题在于字少的时候,头像会超出位置。
设定一个最小高度即可:
记得给文字设定居中:
给Button设定如下选项:
接下来为选择面板添加Button:
将按钮拉长,并选择居于右部,就会发现此时Button位于右边。
选择text,改变其对话框长度:
多复制几个按钮,并将面板透明度设置为0:
创建对话&任务的 NPC- Assets Store 中添加其他素材图中素材:点击跳转
- 导入素材后,要将你的场景素材升级到URP
- 拖拽素材包中的 Prefab 文件夹中的人物放在场景中
- 添加基本的必要组件
- 自己单独创建 Animator Controller 只添加一个 Idle 动画即可
- 修改 Tag 及 Layer
- 将这个人物保存成 Original Prefab 在你的文件夹中
首先要记得给NPC 添加 DialogueController 脚本 出发启动对话
public class DialogueUI : Singleton
{
[Header("Basic Elements")]
public Image icon;
public Text mainText;
public Button nextButton;
public GameObject dialoguePanel;
[Header("Data")]
public DialougeData_SO currentData;
int currentIndex = 0;
public void UpdateDialogueData(DialougeData_SO data)
{
currentData = data;
currentIndex = 0;
}
}
在对话控制里更新数据
进行赋值
把那些栏拖拽到里面
这样即可实现点击进入下一行对话,没有对话时面板消失。
将Button作为预制体:
创建OptionUI:
为了实现对话,需要获取选项的Panel及脚本:
接下来实现选项的销毁与创建:
这样即可实现生成选项:
接下来实现点击选项的事件:
我们希望根据选项的下一步的ID实现跳转:
需要在optionUI里声明:
然后在选项中更新:
接下来添加点击时实现的事件:
并且加入Onclick事件
获取了ID之后,然后就通过ID去对话的List中去获取该对话信息:
实现打字的效果:下载DOTween插件。
这样即可实现打字效果
但是此处还有一个问题,在于当next按钮消失时布局会发生改变。
还有currentIndex的顺序++,这个和选项无关
- 创建 QuestNameButton 添加在 任务名字按钮 上
- 创建 QuestRequirement 添加在 Requirement 上
- 设置好以上两个类的变量并且拿到赋值
- QuestUI 中创建所有的需要控制的变量 / 坐标 / Prefab
在QuestCanvas添加脚本并赋值:
给button创建一个脚本
为需求添加脚本
添加需求
添加奖励
奖励物品的显示代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ShowTooltip : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
private ItemUI currentItemUI;
void Awake()
{
currentItemUI = GetComponent();
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("mouse in slot");
QuestUI.Instance.tooltip.gameObject.SetActive(true);
QuestUI.Instance.tooltip.SetupTooltip(currentItemUI.currentItemData);
}
public void OnPointerExit(PointerEventData eventData)
{
QuestUI.Instance.tooltip.gameObject.SetActive(false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class QuestUI : Singleton
{
[Header("Elements")]
public GameObject quesPanel;
public ItemToolTip tooltip;
bool isOpen;
[Header("Quest Name")]
public RectTransform questListTransform;
public QuestNameButton questNameButton;
[Header("Text Content")]
public Text quesContentText;
[Header("Requirement")]
public RectTransform requireTransform;
public QuestRequirement requirement;
[Header("Reward Panel")]
public RectTransform rewardTransform;
public ItemUI rewardUI;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
isOpen = !isOpen;
quesPanel.SetActive(isOpen);
quesContentText.text = string.Empty;
SetupQuestList();
}
if (!isOpen)
tooltip.gameObject.SetActive(false);
}
public void SetupQuestList()
{
//清除原来已有的任务
foreach(Transform item in questListTransform)
{
Destroy(item.gameObject);
}
foreach(Transform item in rewardTransform)
{
Destroy(item.gameObject);
}
foreach (Transform item in requireTransform)
{
Destroy(item.gameObject);
}
//遍历列表中的list,接取任务
foreach(var task in QuestManager.Instance.tasks)
{
var newTask = Instantiate(questNameButton, questListTransform);
newTask.SetupNameButton(task.questData);
//newTask.questContentText = quesContentText;
}
}
public void SetupRequireList(QuestData_SO questData)
{
quesContentText.text = questData.description;
//将涉及到QuestNameButton中的三处questContentText关闭,不使用在里面传东西然后赋值的形式了,改为在此处直接修改
foreach (Transform item in requireTransform)
{
Destroy(item.gameObject);
}
foreach(var require in questData.questRequires)
{
var q = Instantiate(requirement, requireTransform);
q.SetupRequirement(require.name, require.requireAmount, require.currentAmount);
}
}
public void SetupRewardItem(ItemData_SO itemData,int amount)
{
var item = Instantiate(rewardUI, rewardTransform);
item.SetupItemUI(itemData, amount);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class QuestNameButton : MonoBehaviour
{
public Text questNameText;
public QuestData_SO currentData;
//public Text questContentText;
public void SetupNameButton(QuestData_SO quesData)
{
currentData = quesData;
if (quesData.isComplete)
questNameText.text = quesData.questName + "(完成)";
else
questNameText.text = quesData.questName;
}
private void Awake()
{
GetComponent
检测和更新任务进度
检查背包中的物品数量和任务所需的物品数量是否相同。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)