
1.完成对话系统框架 (1.系统结构见图 (2.使用方法为对ConversationController单例使用OnCall(Staring 对话名) (3.需要自行编辑对话内容,填写AConversation组件的内容即可 果咩,我摸了五天,求职的压力实在是太大了😿😿
188 lines
6.1 KiB
C#
188 lines
6.1 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using DG.Tweening;
|
||
using Sirenix.OdinInspector;
|
||
|
||
/// <summary>
|
||
/// 一次对话,只需在面板设置对话顺序和内容列表,再拖入对话者即可,其他一些暴露参数可不调
|
||
/// </summary>
|
||
public class AConversation : MonoBehaviour
|
||
{
|
||
|
||
[ListDrawerSettings]
|
||
public List<Sprite> contentList;
|
||
[ListDrawerSettings]
|
||
public List<ASpeak.Speaker> speakerList;
|
||
public string conversationName;
|
||
public float timePerSpeak;
|
||
public Sprite P1Background;
|
||
public Sprite P2Background;
|
||
[Header("P1一定是左边的,切记")]
|
||
public Transform P1Pos;
|
||
public Transform P2Pos;
|
||
[Header("对话框到说话者中心的偏移量")]
|
||
public Vector2 offset = new Vector2(1.5f, 1.5f);
|
||
|
||
|
||
|
||
private List<ASpeak> speakList;
|
||
protected ASpeak.Speaker P1;
|
||
protected ASpeak.Speaker P2;
|
||
protected SpriteRenderer P1Renderer;
|
||
protected SpriteRenderer P2Renderer;
|
||
protected Player player;
|
||
protected SpriteRenderer P1ContentRenderer;
|
||
protected SpriteRenderer P2ContentRenderer;
|
||
|
||
void Start()
|
||
{
|
||
speakList = new List<ASpeak>();
|
||
//新增对话框游戏物体,挂在这个游戏物体上
|
||
AddDialog();
|
||
//找到玩家
|
||
player = FindObjectOfType<Player>();
|
||
SetConversation();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对外界唯一接口
|
||
/// </summary>
|
||
public void OnCall()
|
||
{
|
||
|
||
if(speakList.Count == speakerList.Count)
|
||
{
|
||
//移动对话框到相应位置
|
||
MoveDialog();
|
||
//开始对话
|
||
StartCoroutine(Speak());
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("对话顺序和内容列表长度不一致");
|
||
}
|
||
|
||
}
|
||
|
||
protected IEnumerator Speak(){
|
||
yield return new WaitForEndOfFrame();
|
||
//遍历对话列表
|
||
foreach(ASpeak speak in speakList){
|
||
//根据说话者将对话的透明度插值至1
|
||
if(speak.speaker == P1){
|
||
P1Renderer.DOColor(new Color(1,1,1,1),1f);
|
||
P1ContentRenderer.sprite = speak.content;
|
||
P1ContentRenderer.DOColor(new Color(1,1,1,1),1f);
|
||
}
|
||
else{
|
||
P2Renderer.DOColor(new Color(1,1,1,1),1f);
|
||
P2ContentRenderer.sprite = speak.content;
|
||
P2ContentRenderer.DOColor(new Color(1,1,1,1),1f);
|
||
}
|
||
//等待
|
||
yield return new WaitForSeconds(timePerSpeak);
|
||
//根据说话者将对话的透明度插值至0
|
||
if(speak.speaker == P1){
|
||
P1Renderer.DOColor(new Color(1,1,1,0),1f);
|
||
P1ContentRenderer.DOColor(new Color(1,1,1,0),1f);
|
||
}
|
||
else{
|
||
P2Renderer.DOColor(new Color(1,1,1,0),1f);
|
||
P2ContentRenderer.DOColor(new Color(1,1,1,0),1f);
|
||
}
|
||
yield return new WaitForSeconds(1f);
|
||
}
|
||
//都说完以后,触发结束事件
|
||
OnEnd();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在设置对话顺序时使用
|
||
/// </summary>
|
||
/// <param name="speaker"></param>
|
||
protected void AddASpeak(ASpeak.Speaker speaker,Sprite content)
|
||
{
|
||
ASpeak speak = new ASpeak();
|
||
speak.speaker = speaker;
|
||
speak.content = content;
|
||
speakList.Add(speak);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 只需要手动设置说话的顺序,不需要手动设置对话内容
|
||
/// </summary>
|
||
public virtual void SetConversation()
|
||
{
|
||
for(int i = 0; i < speakerList.Count; i++)
|
||
{
|
||
AddASpeak(speakerList[i], contentList[i]);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对话结束时触发,已有内容,会恢复玩家的操作权限
|
||
/// </summary>
|
||
public virtual void OnEnd()
|
||
{
|
||
player.ToMap("Normal");
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 初始化对话框
|
||
/// </summary>
|
||
protected void AddDialog()
|
||
{
|
||
//新增对话框游戏物体,挂在这个游戏物体上
|
||
GameObject P1dialog = new GameObject("P1Dialog");
|
||
P1dialog.transform.SetParent(transform);
|
||
P1dialog.transform.position = new Vector3(0, 0, 0);
|
||
P1dialog.AddComponent<SpriteRenderer>();
|
||
P1Renderer = P1dialog.GetComponent<SpriteRenderer>();
|
||
P1Renderer.sprite = P1Background;
|
||
P1Renderer.sortingLayerName = "UI";
|
||
GameObject P2dialog = new GameObject("P2Dialog");
|
||
P2dialog.transform.SetParent(transform);
|
||
P2dialog.transform.position = new Vector3(0, 0, 0);
|
||
P2dialog.AddComponent<SpriteRenderer>();
|
||
P2Renderer = P2dialog.GetComponent<SpriteRenderer>();
|
||
P2Renderer.sprite = P2Background;
|
||
P2Renderer.sortingLayerName = "UI";
|
||
|
||
//使其二透明度变为0
|
||
P1Renderer.color = new Color(1, 1, 1, 0);
|
||
P2Renderer.color = new Color(1, 1, 1, 0);
|
||
|
||
//新增对话框内容游戏物体,挂在对话框游戏物体上
|
||
GameObject P1Content = new GameObject("P1Content");
|
||
P1Content.transform.SetParent(P1dialog.transform);
|
||
P1Content.transform.localPosition = new Vector3(0, 0, 0);
|
||
P1Content.AddComponent<SpriteRenderer>();
|
||
P1ContentRenderer = P1Content.GetComponent<SpriteRenderer>();
|
||
P1ContentRenderer.sortingLayerName = "UI";
|
||
P1ContentRenderer.sortingOrder = 2;
|
||
|
||
GameObject P2Content = new GameObject("P2Content");
|
||
P2Content.transform.SetParent(P2dialog.transform);
|
||
P2Content.transform.localPosition = new Vector3(0, 0, 0);
|
||
P2Content.AddComponent<SpriteRenderer>();
|
||
P2ContentRenderer = P2Content.GetComponent<SpriteRenderer>();
|
||
P2ContentRenderer.sortingLayerName = "UI";
|
||
P2ContentRenderer.sortingOrder = 2;
|
||
|
||
//使其二透明度变为0
|
||
P1ContentRenderer.color = new Color(1, 1, 1, 0);
|
||
P2ContentRenderer.color = new Color(1, 1, 1, 0);
|
||
}
|
||
|
||
protected void MoveDialog()
|
||
{
|
||
P1Renderer.transform.position = P1Pos.position + new Vector3(offset.x, offset.y, 0);
|
||
P2Renderer.transform.position = P2Pos.position + new Vector3(offset.x * - 1, offset.y, 0);
|
||
}
|
||
|
||
}
|