89 lines
4.3 KiB
C#
89 lines
4.3 KiB
C#
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
|
|
[CreateAssetMenu(menuName = "Communication/Dialog Node")]
|
|
public class DialogNode : ScriptableObject
|
|
{
|
|
[Header("Speaker")]
|
|
public CharacterData Speaker;
|
|
|
|
[Tooltip("비우면 Speaker의 이름 그대로, 채우면 이 이름으로 표시 (예: ???)")]
|
|
public string SpeakerNameOverride;
|
|
|
|
[Tooltip("대사창을 띄울 기준 캐릭터. 비우면 Speaker 옆에 띄움 " +
|
|
"(다른 NPC가 끼어드는 대사를 원래 대화 상대 옆에 표시하고 싶을 때 지정)")]
|
|
public CharacterData HudAnchor;
|
|
|
|
[Header("Content")]
|
|
[TextArea(2,5)] public string TalkText;
|
|
public GestureData Gesture;
|
|
public ExpressionData Expression;
|
|
public AudioClip Voice;
|
|
public float LineDuration; //자동 넘김 시간
|
|
//LineDuration=0 → 플레이어 입력 대기 (수동)
|
|
//Voice 있음 → 클립 길이만큼 대기
|
|
//Voice 없음 → LineDuration 대기
|
|
|
|
|
|
[Header("Presentation")]
|
|
public AudioClip Bgm; // 있으면 이 대사부터 전용 BGM 재생, 비어있으면 기본 BGM으로 복귀
|
|
public GameObject Vfx; // 이 대사 시작 시 화자 위치에서 1회 재생할 이펙트 프리팹
|
|
|
|
[Header("Behavior")]
|
|
public bool LookAtPlayer;
|
|
public bool ForcePlayerLook; // true면 이 대사 시작 시 플레이어(카메라)가 화자를 바라보도록 리그를 회전
|
|
|
|
[Tooltip("켜면 이 대사 시작 시 화자를 아래 Fixed Angle Y(월드 Y각)로 고정 회전한다. " +
|
|
"특정 각도에서만 자연스러운 제스처/애니메이션용. 대화 종료 시 원래 각도로 복원")]
|
|
public bool UseFixedAngle;
|
|
|
|
[Tooltip("UseFixedAngle이 켜졌을 때 화자가 향할 월드 Y 회전(도). 0 = +Z(월드 forward), 90 = +X 방향")]
|
|
public float FixedAngleY;
|
|
public bool WaitForInput; // true면 LineDuration 무시하고 B버튼(OnDialogNext) 입력까지 대기
|
|
public bool StagingOnly; // true면 대화창을 숨기고 연출(회전·제스처·VFX·이벤트·대기)만 수행
|
|
|
|
[Header("Flow")]
|
|
public DialogNode Next; // 선택지 없을 때 자동으로 갈 노드
|
|
public List<DialogChoice> Choices; // 있으면 플레이어 선택 대기
|
|
|
|
[Header("Hidden Branch")]
|
|
[Tooltip("이 대사가 재생되는 동안 특정 행동(제스처)을 하면 Next/선택지 대신 이 노드로 몰래 분기. " +
|
|
"비우면 히든 분기 없음 — 평소엔 존재하지 않는 것처럼 보인다")]
|
|
public DialogNode HiddenBranch;
|
|
|
|
[Tooltip("히든 분기를 여는 제스처 키 (아이템의 DialogGestureItem의 Gesture Key와 일치). " +
|
|
"예: kimchi, bouquet, slap. 비우면 아무 제스처 오브젝트나 발동 가능")]
|
|
public string HiddenGestureKey;
|
|
|
|
[Tooltip("히든 분기를 탔을 때 기록할 선택지 Code (선택지의 Code와 동일한 용도). " +
|
|
"비우면 기록 안 함. 이후 대화 조건(RequiredChoiceCodes)에서 검사 가능")]
|
|
public string HiddenCode;
|
|
|
|
[Header("Affection Branch")]
|
|
[Tooltip("켜면 이 노드는 대사 없이 호감도 조건만 검사해 즉시 라우팅한다: " +
|
|
"조건을 만족하면 AffectionPassBranch로, 아니면 Next로")]
|
|
public bool AffectionCheck;
|
|
|
|
[Tooltip("검사할 호감도 조건들 (캐릭터·연산자·값 + 다음 조건과의 and/or). " +
|
|
"캐릭터를 비우면 대화 주인 NPC. AND가 OR보다 우선. 비어 있으면 무조건 통과")]
|
|
public List<AffectionRequirement> AffectionRequirements = new();
|
|
|
|
[Tooltip("조건을 만족했을 때 갈 노드 (실패하면 Next로)")]
|
|
public DialogNode AffectionPassBranch;
|
|
|
|
[Header("ChoiceQuestion")]
|
|
[TextArea(2,5)] public string ChoiceQuestion;
|
|
|
|
[Header("Event")]
|
|
public string EventKey; // 비어있지 않으면 이 노드가 재생될 때 DialogPlayer가 같은 Key의 이벤트를 호출
|
|
|
|
[Header("Story")]
|
|
[Tooltip("0이 아니면 이 노드 재생 시 화자(비우면 대화 주인 NPC)의 호감도를 이만큼 증감")]
|
|
public int Affection;
|
|
|
|
[Tooltip("0이 아니면 이 노드 재생 시 메인 진행도를 이만큼 증가. " +
|
|
"분기 끝 노드마다 다른 값을 주면 선택지에 따라 진행도를 다르게 줄 수 있다")]
|
|
public int Progress;
|
|
}
|