可实现点击物体后自动移动到物体附近,然后弹出对话框进行对话。
基于Unity 简单角色对话UI脚本的编写(新版UI组件)和Unity 关于点击不同物品移动并触发不同事件的结合体,有兴趣可以看一下之前文章。
下边代码为UI界面的公共脚本:
public class DialogueUI : MonoBehaviour
{
private TextMeshProUGUI nameTexe;//获取名称的Text组件
private TextMeshProUGUI descriptionTexe; //获取内容的Text组件
private Button resumeButton;//继续对话的按钮
public List<string> contentlist;//对话列表
private int contentIndex = 0;//对话数组
private void Start()
{
//获取组件
nameTexe = transform.Find("NameText").GetComponent<TextMeshProUGUI>();
descriptionTexe= transform.Find("ContentText").GetComponent<TextMeshProUGUI>();
resumeButton = transform.Find("ResumeButton").GetComponent<Button>();
resumeButton.onClick.AddListener(this.OnContinueButtonClick);
descriptionTexe.text = contentlist[0];
Hide();
}
public void Show()
{
gameObject.SetActive(true);//显示对话框
}
public void Show(string name, string[] content)//调用方法获得对话
{
contentIndex = 0;
nameTexe.text = name;
contentlist=new List<string>();
contentlist.AddRange(content);
descriptionTexe.text = contentlist[0];
Show();
}
public void Hide() //关闭对话
{
gameObject.SetActive(false);
}
private void OnContinueButtonClick()
{
//调用对话列表,如果没有对话,窗口关闭
contentIndex++;
if (contentIndex >= contentlist.Count)
{
Hide();return;
}
descriptionTexe.text = contentlist[contentIndex];
}
}
下边为被点击物体挂载的脚本:
public class ItemObject : InteractionObject
{
public string name;
public string[] contenList;
public DialogueUI dialogueUI;
protected override void Interact()
{
print("我就是个东西!");
dialogueUI.Show(name, contenList);
}
}
然后是Player挂载的触发脚本:
public class PlayerRoutine : MonoBehaviour
{
// Start is called before the first frame update
private NavMeshAgent PlayerAgent;
void Start()
{
PlayerAgent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0)&&EventSystem.current.IsPointerOverGameObject()==false)//点击鼠标左键并且没有点击到IU组件
{
Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);//创建一条射线
RaycastHit hit;
bool isCollide = Physics.Raycast(ray, out hit);
if (isCollide)
{
if (hit.collider.tag == "Ground")//假如点击物体的标签为Ground
{
PlayerAgent.stoppingDistance = 0;//停止距离为0
PlayerAgent.SetDestination(hit.point);//移动到点击位置
}
else if (hit.collider.tag == "NPC") //假如点击物体的标签为NPC
{
hit.collider.GetComponent<InteractionObject>().OnClick(PlayerAgent);//调用InteractionObject中的Onclick方法
}
else if (hit.collider.tag == "Item")
{
hit.collider.GetComponent<InteractionObject>().OnClick(PlayerAgent);
}
}
}
}
}
还有公共管理类脚本:
public class InteractionObject : MonoBehaviour
{
private NavMeshAgent PlayerAgent;
private bool haveinteracted=false;//用于判断方法已经调用
public void OnClick(NavMeshAgent PlayerAgent)
{
this.PlayerAgent = PlayerAgent;
PlayerAgent.stoppingDistance = 2;//寻路停止距离
PlayerAgent.SetDestination(transform.position);//移动到寻路点
haveinteracted = false;
}
private void Update()
{
if (PlayerAgent != null&&haveinteracted==false&&PlayerAgent.pathPending==false)//后边是判断路径是否计算完成
{
if (PlayerAgent.remainingDistance <= 2)//距离目标点的距离是否小于2米
{
Interact();//调用Interact()方法
haveinteracted = true;
}
}
}
protected virtual void Interact() //便于重写
{
print("点到了NPC");
}
}