Compare commits
4 Commits
main
...
CatsRhythm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19c26533f8 | ||
|
|
fab54e162e | ||
|
|
e8086180a0 | ||
| b0aede20f2 |
Binary file not shown.
177
Assets/02_Scripts/Data/Rhythm/MidiChartParser.cs
Normal file
177
Assets/02_Scripts/Data/Rhythm/MidiChartParser.cs
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// 표준 MIDI 파일(.mid)을 파싱해 Note 리스트로 변환하는 미니 파서.
|
||||||
|
// 단일 템포 가정. Note-On(velocity>0) 이벤트만 사용한다.
|
||||||
|
public static class MidiChartParser
|
||||||
|
{
|
||||||
|
// data: .mid 원본 바이트 / offset: 곡 시작 보정(초)
|
||||||
|
// bpmOverride: 0이면 MIDI 내장 템포 사용, >0이면 이 BPM으로 강제
|
||||||
|
// lanePitches: 비우면 모든 노트를 레인 0으로, 채우면 해당 음높이만 레인으로 매핑
|
||||||
|
public static List<Note> Parse(byte[] data, float offset, float bpmOverride, List<int> lanePitches)
|
||||||
|
{
|
||||||
|
var notes = new List<Note>();
|
||||||
|
if (data == null || data.Length < 14)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[MidiChartParser] MIDI 데이터가 비었거나 너무 짧습니다.");
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int p = 0;
|
||||||
|
|
||||||
|
// ---- 헤더 청크 (MThd) ----
|
||||||
|
if (!MatchId(data, p, 'M', 'T', 'h', 'd'))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[MidiChartParser] MThd 헤더가 아닙니다. (TextAsset이 .mid가 맞는지 확인)");
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
p += 4;
|
||||||
|
ReadUInt32(data, ref p); // 헤더 길이(=6), 사용 안 함
|
||||||
|
ReadUInt16(data, ref p); // 포맷
|
||||||
|
int trackCount = ReadUInt16(data, ref p);
|
||||||
|
int division = ReadUInt16(data, ref p);
|
||||||
|
|
||||||
|
if ((division & 0x8000) != 0)
|
||||||
|
Debug.LogWarning("[MidiChartParser] SMPTE 타임코드는 미지원입니다. PPQN으로 가정합니다.");
|
||||||
|
int ticksPerQuarter = division & 0x7FFF;
|
||||||
|
if (ticksPerQuarter <= 0) ticksPerQuarter = 480;
|
||||||
|
|
||||||
|
// (절대틱, 음높이) 수집 + 첫 템포
|
||||||
|
var rawNotes = new List<(int tick, int pitch)>();
|
||||||
|
int tempoMicros = -1; // 4분음표당 마이크로초 (미발견 시 -1)
|
||||||
|
|
||||||
|
// ---- 트랙 청크들 (MTrk) ----
|
||||||
|
for (int t = 0; t < trackCount && p + 8 <= data.Length; t++)
|
||||||
|
{
|
||||||
|
if (!MatchId(data, p, 'M', 'T', 'r', 'k'))
|
||||||
|
break;
|
||||||
|
p += 4;
|
||||||
|
long len = ReadUInt32(data, ref p);
|
||||||
|
int trackEnd = p + (int)len;
|
||||||
|
if (trackEnd > data.Length) trackEnd = data.Length;
|
||||||
|
|
||||||
|
int absTicks = 0;
|
||||||
|
int runningStatus = 0;
|
||||||
|
|
||||||
|
while (p < trackEnd)
|
||||||
|
{
|
||||||
|
absTicks += ReadVarLen(data, ref p);
|
||||||
|
|
||||||
|
int status = data[p];
|
||||||
|
if (status < 0x80)
|
||||||
|
{
|
||||||
|
status = runningStatus; // 러닝 스테이터스: 상태 바이트 생략
|
||||||
|
if (status == 0) { p = trackEnd; break; } // 손상된 데이터 방어
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
runningStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 0xFF) // 메타 이벤트
|
||||||
|
{
|
||||||
|
int metaType = data[p++];
|
||||||
|
int mlen = ReadVarLen(data, ref p);
|
||||||
|
if (metaType == 0x51 && mlen == 3 && tempoMicros < 0)
|
||||||
|
tempoMicros = (data[p] << 16) | (data[p + 1] << 8) | data[p + 2];
|
||||||
|
p += mlen;
|
||||||
|
runningStatus = 0;
|
||||||
|
}
|
||||||
|
else if (status == 0xF0 || status == 0xF7) // SysEx
|
||||||
|
{
|
||||||
|
int slen = ReadVarLen(data, ref p);
|
||||||
|
p += slen;
|
||||||
|
runningStatus = 0;
|
||||||
|
}
|
||||||
|
else // 채널 메시지
|
||||||
|
{
|
||||||
|
int type = status & 0xF0;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0x90: // Note-On
|
||||||
|
int pitch = data[p++];
|
||||||
|
int velocity = data[p++];
|
||||||
|
if (velocity > 0) rawNotes.Add((absTicks, pitch));
|
||||||
|
break;
|
||||||
|
case 0x80: // Note-Off
|
||||||
|
case 0xA0: // 폴리 애프터터치
|
||||||
|
case 0xB0: // 컨트롤 체인지
|
||||||
|
case 0xE0: // 피치 벤드
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case 0xC0: // 프로그램 체인지
|
||||||
|
case 0xD0: // 채널 애프터터치
|
||||||
|
p += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
p = trackEnd; // 알 수 없는 상태 → 트랙 종료(무한루프 방지)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = trackEnd; // 트랙 경계 보정
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 틱 → 초 변환 ----
|
||||||
|
double usPerQuarter = bpmOverride > 0f
|
||||||
|
? 60000000.0 / bpmOverride
|
||||||
|
: (tempoMicros > 0 ? tempoMicros : 500000.0); // 기본 120 BPM
|
||||||
|
double secPerTick = usPerQuarter / 1000000.0 / ticksPerQuarter;
|
||||||
|
|
||||||
|
bool useLanes = lanePitches != null && lanePitches.Count > 0;
|
||||||
|
|
||||||
|
foreach (var raw in rawNotes)
|
||||||
|
{
|
||||||
|
int lane = 0;
|
||||||
|
if (useLanes)
|
||||||
|
{
|
||||||
|
lane = lanePitches.IndexOf(raw.pitch);
|
||||||
|
if (lane < 0) continue; // 레인에 매핑 안 된 음높이는 무시
|
||||||
|
}
|
||||||
|
|
||||||
|
notes.Add(new Note
|
||||||
|
{
|
||||||
|
Time = offset + (float)(raw.tick * secPerTick),
|
||||||
|
Lane = lane
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
notes.Sort((a, b) => a.Time.CompareTo(b.Time));
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 바이트 읽기 헬퍼 (MIDI는 빅엔디안) ----
|
||||||
|
|
||||||
|
private static bool MatchId(byte[] d, int p, char a, char b, char c, char e)
|
||||||
|
=> p + 4 <= d.Length && d[p] == a && d[p + 1] == b && d[p + 2] == c && d[p + 3] == e;
|
||||||
|
|
||||||
|
private static uint ReadUInt32(byte[] d, ref int p)
|
||||||
|
{
|
||||||
|
uint v = (uint)((d[p] << 24) | (d[p + 1] << 16) | (d[p + 2] << 8) | d[p + 3]);
|
||||||
|
p += 4;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ReadUInt16(byte[] d, ref int p)
|
||||||
|
{
|
||||||
|
int v = (d[p] << 8) | d[p + 1];
|
||||||
|
p += 2;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 가변 길이 수치(Variable-Length Quantity)
|
||||||
|
private static int ReadVarLen(byte[] d, ref int p)
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
byte b;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
b = d[p++];
|
||||||
|
value = (value << 7) | (b & 0x7F);
|
||||||
|
}
|
||||||
|
while ((b & 0x80) != 0 && p < d.Length);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Data/Rhythm/MidiChartParser.cs.meta
Normal file
2
Assets/02_Scripts/Data/Rhythm/MidiChartParser.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4930b4a6230ad694da5ca148280f1d07
|
||||||
@@ -3,22 +3,28 @@
|
|||||||
|
|
||||||
public class Note
|
public class Note
|
||||||
{
|
{
|
||||||
[HideInInspector] public float Time;
|
[HideInInspector] public float Time; // 판정 시각(초)
|
||||||
|
[HideInInspector] public int Lane; // 레인 인덱스 (단일 레인이면 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
[CreateAssetMenu(fileName = "RhythmChart", menuName = "CatsRoom/RhythmChart")]
|
[CreateAssetMenu(fileName = "RhythmChart", menuName = "CatsRoom/RhythmChart")]
|
||||||
public class RhythmChart : ScriptableObject
|
public class RhythmChart : ScriptableObject
|
||||||
{
|
{
|
||||||
public AudioClip SongClip; // 노래 파일
|
public AudioClip SongClip; // 노래 파일
|
||||||
public float Bpm; // 분당 박자
|
public TextAsset MidiFile; // FL Studio에서 내보낸 .mid (확장자를 .bytes로 임포트)
|
||||||
public float Offset; // 첫 박자 시작 시각
|
public float Offset; // 곡 시작과 MIDI 0틱 사이 보정(초)
|
||||||
public int NoteCount; // 노트 개수 (또는 곡 길이로 자동)
|
public float BpmOverride; // 0이면 MIDI 내장 템포 사용, >0이면 이 BPM으로 강제
|
||||||
public List<Note> GenerateNotes() // BPM·offset으로 시간 목록 자동 생성
|
public List<int> LanePitches = new(); // 비우면 모든 노트를 레인 0으로. 채우면 (index=레인) 매핑
|
||||||
|
|
||||||
|
// MIDI를 파싱해 노트 시간 목록 생성
|
||||||
|
public List<Note> GenerateNotes()
|
||||||
{
|
{
|
||||||
List<Note> notes = new List<Note>();
|
if (MidiFile == null)
|
||||||
float interval = 60f / Bpm;
|
{
|
||||||
for (int i = 0; i < NoteCount; i++)
|
Debug.LogWarning($"[RhythmChart] {name}: MidiFile이 비어 있습니다.");
|
||||||
notes.Add(new Note { Time = Offset + interval * i });
|
return new List<Note>();
|
||||||
return notes;
|
}
|
||||||
|
|
||||||
|
return MidiChartParser.Parse(MidiFile.bytes, Offset, BpmOverride, LanePitches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,39 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Hovl;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
public enum Result { Perfect, Good, Miss }
|
public enum Result { Perfect, Good, Bad, Miss }
|
||||||
public class RhythmManager : MonoBehaviour
|
public class RhythmManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private AudioSource _audioSource;
|
[SerializeField] private AudioSource _audioSource;
|
||||||
[SerializeField] private RhythmChart _currentChart;
|
[SerializeField] private RhythmChart _currentChart;
|
||||||
[SerializeField] private RhythmNoteSpawner _spawner;
|
[SerializeField] private RhythmNoteSpawner _spawner;
|
||||||
[SerializeField] private float _leadTime = 2f; // 노트가 생성돼 판정선까지 흐르는 시간(초)
|
[SerializeField] private float _leadTime = 2f; // 노트가 생성돼 판정선까지 흐르는 시간(초)
|
||||||
|
|
||||||
|
[Header("판정 윈도우 (초, 절대 시간차 기준)")]
|
||||||
|
[SerializeField] private float _perfectWindow = 0.05f;
|
||||||
|
[SerializeField] private float _goodWindow = 0.10f;
|
||||||
|
[SerializeField] private float _badWindow = 0.15f; // 이 밖이면 입력 무시(헛침)
|
||||||
|
|
||||||
|
[SerializeField] private GameObject StartButtonObj;
|
||||||
|
|
||||||
public float SongTime => _audioSource.time; // 모든 타이밍의 기준
|
public float SongTime => _audioSource.time; // 모든 타이밍의 기준
|
||||||
|
|
||||||
private List<Note> SongNoteList;
|
private List<Note> SongNoteList;
|
||||||
private int _nextNoteIndex; // 다음에 소환할 노트 인덱스
|
private int _nextNoteIndex; // 다음에 소환할 노트 인덱스
|
||||||
private bool _isPlaying; //곡이 재생 중인지 (종료 감지용)
|
private bool _isPlaying; //곡이 재생 중인지 (종료 감지용)
|
||||||
private Func<float> _songTimeProvider; // 노트에 넘길 시간 제공자 (매 스폰마다 람다 재생성 방지용 캐시)
|
private Func<float> _songTimeProvider; // 노트에 넘길 시간 제공자 (매 스폰마다 람다 재생성 방지용 캐시)
|
||||||
|
private readonly List<RhythmNoteInstance> _activeNotes = new(); // 화면에 떠 있는(아직 처리 안 된) 노트들
|
||||||
|
|
||||||
|
// 점수 상태 (HUD가 읽음). 누적 로직은 RhythmScore가 전담
|
||||||
|
public RhythmScore Score { get; } = new();
|
||||||
|
|
||||||
|
public event Action OnSongStarted; // 곡 시작 (ScoreHud 표시 / ResultHud 숨김)
|
||||||
|
public event Action<Result> OnJudged; // 노트 하나가 판정될 때마다 (HUD 연출용)
|
||||||
|
public event Action<RhythmScore> OnScoreChanged; // 점수/콤보가 바뀔 때 (실시간 HUD)
|
||||||
|
public event Action<RhythmScore> OnSongFinished; // 곡이 끝났을 때 (결과창)
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
@@ -35,7 +54,13 @@ private void Update()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isPlaying) SpawnDueNotes();
|
if (!_isPlaying) return;
|
||||||
|
|
||||||
|
SpawnDueNotes();
|
||||||
|
|
||||||
|
// 테스트용: 스페이스로 판정 (실제 VR에서는 컨트롤러/콜라이더 입력으로 교체)
|
||||||
|
if (Keyboard.current != null && Keyboard.current.spaceKey.wasPressedThisFrame)
|
||||||
|
OnPlayerInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SongTime 기준으로 소환할 때가 된 노트들을 순서대로 생성
|
// SongTime 기준으로 소환할 때가 된 노트들을 순서대로 생성
|
||||||
@@ -47,7 +72,8 @@ private void SpawnDueNotes()
|
|||||||
{
|
{
|
||||||
Note note = SongNoteList[_nextNoteIndex];
|
Note note = SongNoteList[_nextNoteIndex];
|
||||||
// spawnTime은 실제 프레임 시각이 아니라 이론값(note.Time - _leadTime)으로 줘야 보간이 정확
|
// spawnTime은 실제 프레임 시각이 아니라 이론값(note.Time - _leadTime)으로 줘야 보간이 정확
|
||||||
_spawner.SpawnNote(note, note.Time - _leadTime, _songTimeProvider, OnNoteMissed);
|
RhythmNoteInstance instance = _spawner.SpawnNote(note, note.Time - _leadTime, _songTimeProvider, OnNoteMissed);
|
||||||
|
_activeNotes.Add(instance);
|
||||||
_nextNoteIndex++;
|
_nextNoteIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,6 +88,12 @@ public void StartSong()
|
|||||||
{
|
{
|
||||||
SongNoteList = _currentChart.GenerateNotes();
|
SongNoteList = _currentChart.GenerateNotes();
|
||||||
_nextNoteIndex = 0;
|
_nextNoteIndex = 0;
|
||||||
|
_activeNotes.Clear();
|
||||||
|
|
||||||
|
Score.Reset();
|
||||||
|
OnSongStarted?.Invoke(); // ScoreHud 표시 / ResultHud 숨김
|
||||||
|
OnScoreChanged?.Invoke(Score); // HUD 초기화(0점)
|
||||||
|
StartButtonObj.SetActive(false);
|
||||||
|
|
||||||
_audioSource.Play();
|
_audioSource.Play();
|
||||||
_isPlaying = true;
|
_isPlaying = true;
|
||||||
@@ -73,25 +105,72 @@ public void StartSong()
|
|||||||
// 곡 정지 + 주변음 복구
|
// 곡 정지 + 주변음 복구
|
||||||
public void StopSong()
|
public void StopSong()
|
||||||
{
|
{
|
||||||
|
if (!_isPlaying) return; // 중복 호출 방지(결과창 두 번 뜨는 것 차단)
|
||||||
|
|
||||||
_audioSource.Stop();
|
_audioSource.Stop();
|
||||||
_isPlaying = false;
|
_isPlaying = false;
|
||||||
|
|
||||||
if (SoundManager.Instance != null) SoundManager.Instance.ExitMinigameMode();
|
if (SoundManager.Instance != null) SoundManager.Instance.ExitMinigameMode();
|
||||||
|
|
||||||
|
OnSongFinished?.Invoke(Score); // 결과창 표시
|
||||||
}
|
}
|
||||||
|
|
||||||
// 노트가 판정선을 지나쳐 스스로 Miss 처리될 때 호출
|
// 노트가 판정선을 지나쳐 스스로 Miss 처리될 때 호출 (노트는 이미 자기 파괴됨)
|
||||||
private void OnNoteMissed(RhythmNoteInstance note)
|
private void OnNoteMissed(RhythmNoteInstance note)
|
||||||
{
|
{
|
||||||
// TODO: 점수/콤보 시스템 연결 시 Miss 반영
|
_activeNotes.Remove(note);
|
||||||
|
ApplyJudge(Result.Miss);
|
||||||
|
Debug.Log("[Rhythm] Miss (지나침)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnPlayerInput()
|
public void OnPlayerInput()
|
||||||
{
|
{
|
||||||
|
if (!_isPlaying || _activeNotes.Count == 0) return;
|
||||||
|
|
||||||
|
// 판정선에 가장 가까운(시간차 최소) 노트 탐색
|
||||||
|
RhythmNoteInstance target = null;
|
||||||
|
float bestDiff = float.MaxValue;
|
||||||
|
foreach (RhythmNoteInstance note in _activeNotes)
|
||||||
|
{
|
||||||
|
float diff = Mathf.Abs(SongTime - note.HitTime);
|
||||||
|
if (diff < bestDiff)
|
||||||
|
{
|
||||||
|
bestDiff = diff;
|
||||||
|
target = note;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result result = Judge(bestDiff);
|
||||||
|
if (result == Result.Miss) return; // 히트 범위 밖이면 입력 무시 (노트 소비 안 함)
|
||||||
|
|
||||||
|
// 성공 판정 → 히트 이펙트 + 노트 소비
|
||||||
|
if (result == Result.Perfect || result == Result.Good)
|
||||||
|
{
|
||||||
|
// 이펙트는 노트에서 분리돼 따로 재생되므로 노트를 바로 파괴해도 됨
|
||||||
|
if (target.TryGetComponent(out RhythmProjectile projectile))
|
||||||
|
projectile.Detonate();
|
||||||
|
}
|
||||||
|
_activeNotes.Remove(target);
|
||||||
|
Destroy(target.gameObject);
|
||||||
|
|
||||||
|
ApplyJudge(result);
|
||||||
|
Debug.Log($"[Rhythm] {result} (diff {bestDiff:F3}s)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 판정 결과를 점수에 반영하고 이벤트로 알림
|
||||||
|
private void ApplyJudge(Result result)
|
||||||
|
{
|
||||||
|
Score.Apply(result);
|
||||||
|
OnJudged?.Invoke(result);
|
||||||
|
OnScoreChanged?.Invoke(Score);
|
||||||
|
}
|
||||||
|
|
||||||
|
// diff = 절대 시간차(초). 윈도우 안이면 Perfect/Good/Bad, 밖이면 Miss(입력 무시)
|
||||||
public Result Judge(float diff)
|
public Result Judge(float diff)
|
||||||
{
|
{
|
||||||
|
if (diff <= _perfectWindow) return Result.Perfect;
|
||||||
|
if (diff <= _goodWindow) return Result.Good;
|
||||||
|
if (diff <= _badWindow) return Result.Bad;
|
||||||
return Result.Miss;
|
return Result.Miss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
public class RoomMoveButton : MonoBehaviour
|
public class RoomMoveButton : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("이 버튼을 눌렀을 때 이동할 방 번호 입력")]
|
[Header("이 버튼을 눌렀을 때 이동할 방 번호 입력")]
|
||||||
[SerializeField] private int targetRoomNumber;
|
[SerializeField] private int targetRoomNumber;
|
||||||
|
|
||||||
public void OnClickMoveRoom()
|
public void OnClickMoveRoom()
|
||||||
{
|
{
|
||||||
if (RoomRouteManager.Instance == null)
|
if (RoomRouteManager.Instance == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("RoomRouteManager가 없습니다.");
|
Debug.LogError("RoomRouteManager가 없습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,50 +19,50 @@ private void Update()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// C키: 방문 안 한 방 중 랜덤 후보 뽑기
|
// C키: 방문 안 한 방 중 랜덤 후보 뽑기
|
||||||
if (Keyboard.current.cKey.wasPressedThisFrame)
|
if (Keyboard.current.cKey.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
currentChoices = RoomRouteManager.Instance.GetRandomNextRooms();
|
currentChoices = RoomRouteManager.Instance.GetRandomNextRooms();
|
||||||
|
|
||||||
Debug.Log($"현재 선택 가능한 후보 개수: {currentChoices.Count}");
|
Debug.Log($"현재 선택 가능한 후보 개수: {currentChoices.Count}");
|
||||||
|
|
||||||
for (int i = 0; i < currentChoices.Count; i++)
|
for (int i = 0; i < currentChoices.Count; i++)
|
||||||
{
|
{
|
||||||
Debug.Log($"{i + 1}번 선택지 → 방 번호: {currentChoices[i].roomNumber}, 씬 이름: {currentChoices[i].sceneName}");
|
Debug.Log($"{i + 1}번 선택지 → 방 번호: {currentChoices[i].roomNumber}, 씬 이름: {currentChoices[i].sceneName}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1키: 첫 번째 후보 선택
|
// 1키: 첫 번째 후보 선택
|
||||||
if (Keyboard.current.digit1Key.wasPressedThisFrame)
|
if (Keyboard.current.digit1Key.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
MoveToChoice(0);
|
MoveToChoice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2키: 두 번째 후보 선택
|
// 2키: 두 번째 후보 선택
|
||||||
if (Keyboard.current.digit2Key.wasPressedThisFrame)
|
if (Keyboard.current.digit2Key.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
MoveToChoice(1);
|
MoveToChoice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// T키: 방문 상태 확인
|
// T키: 방문 상태 확인
|
||||||
if (Keyboard.current.tKey.wasPressedThisFrame)
|
if (Keyboard.current.tKey.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
Debug.Log($"방문한 방 개수: {RoomRouteManager.Instance.VisitedRoomCount} / {RoomRouteManager.Instance.TotalRoomCount}");
|
Debug.Log($"방문한 방 개수: {RoomRouteManager.Instance.VisitedRoomCount} / {RoomRouteManager.Instance.TotalRoomCount}");
|
||||||
Debug.Log($"현재 방 번호: {RoomRouteManager.Instance.CurrentRoomNumber}");
|
Debug.Log($"현재 방 번호: {RoomRouteManager.Instance.CurrentRoomNumber}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// X키: 테스트용 방문 기록 초기화
|
// X키: 테스트용 방문 기록 초기화
|
||||||
if (Keyboard.current.xKey.wasPressedThisFrame)
|
if (Keyboard.current.xKey.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
Debug.Log("방문 기록 초기화");
|
Debug.Log("방문 기록 초기화");
|
||||||
currentChoices.Clear();
|
currentChoices.Clear();
|
||||||
RoomRouteManager.Instance.ResetVisitedRooms();
|
RoomRouteManager.Instance.ResetVisitedRooms();
|
||||||
}
|
}
|
||||||
|
|
||||||
// F키: 모든 방 방문 후 마지막 씬 이동 테스트
|
// F키: 모든 방 방문 후 마지막 씬 이동 테스트
|
||||||
if (Keyboard.current.fKey.wasPressedThisFrame)
|
if (Keyboard.current.fKey.wasPressedThisFrame)
|
||||||
{
|
{
|
||||||
Debug.Log("마지막 씬 이동 테스트");
|
Debug.Log("마지막 씬 이동 테스트");
|
||||||
RoomRouteManager.Instance.MoveToFinalScene();
|
RoomRouteManager.Instance.MoveToFinalScene();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,19 +71,19 @@ private void MoveToChoice(int index)
|
|||||||
{
|
{
|
||||||
if (currentChoices == null || currentChoices.Count == 0)
|
if (currentChoices == null || currentChoices.Count == 0)
|
||||||
{
|
{
|
||||||
Debug.LogWarning("먼저 C키를 눌러 랜덤 후보를 뽑아야 합니다.");
|
Debug.LogWarning("먼저 C키를 눌러 랜덤 후보를 뽑아야 합니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0 || index >= currentChoices.Count)
|
if (index < 0 || index >= currentChoices.Count)
|
||||||
{
|
{
|
||||||
Debug.LogWarning("해당 번호의 선택지가 없습니다.");
|
Debug.LogWarning("해당 번호의 선택지가 없습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int targetRoomNumber = currentChoices[index].roomNumber;
|
int targetRoomNumber = currentChoices[index].roomNumber;
|
||||||
|
|
||||||
Debug.Log($"{index + 1}번 선택지 선택 → 방 {targetRoomNumber} 이동");
|
Debug.Log($"{index + 1}번 선택지 선택 → 방 {targetRoomNumber} 이동");
|
||||||
|
|
||||||
currentChoices.Clear();
|
currentChoices.Clear();
|
||||||
|
|
||||||
|
|||||||
@@ -8,23 +8,23 @@ public class RoomRouteManager : MonoBehaviour
|
|||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class RoomData
|
public class RoomData
|
||||||
{
|
{
|
||||||
[Header("방 번호 입력")]
|
[Header("방 번호 입력")]
|
||||||
public int roomNumber;
|
public int roomNumber;
|
||||||
|
|
||||||
[Header("이 방에 해당하는 Scene 이름 입력")]
|
[Header("이 방에 해당하는 Scene 이름 입력")]
|
||||||
public string sceneName;
|
public string sceneName;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Header("전체 방 정보 입력")]
|
[Header("전체 방 정보 입력")]
|
||||||
[SerializeField] private List<RoomData> rooms = new List<RoomData>();
|
[SerializeField] private List<RoomData> rooms = new List<RoomData>();
|
||||||
|
|
||||||
[Header("시작 방 번호 입력")]
|
[Header("시작 방 번호 입력")]
|
||||||
[SerializeField] private int startRoomNumber;
|
[SerializeField] private int startRoomNumber;
|
||||||
|
|
||||||
[Header("랜덤 선택지 개수")]
|
[Header("랜덤 선택지 개수")]
|
||||||
[SerializeField] private int randomChoiceCount = 2;
|
[SerializeField] private int randomChoiceCount = 2;
|
||||||
|
|
||||||
[Header("모든 방 방문 후 이동할 마지막 Scene 이름")]
|
[Header("모든 방 방문 후 이동할 마지막 Scene 이름")]
|
||||||
[SerializeField] private string finalSceneName;
|
[SerializeField] private string finalSceneName;
|
||||||
|
|
||||||
private int _currentRoomNumber;
|
private int _currentRoomNumber;
|
||||||
@@ -54,7 +54,7 @@ private void Awake()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 방문하지 않은 방 전체 반환
|
// 방문하지 않은 방 전체 반환
|
||||||
public List<RoomData> GetUnvisitedRooms()
|
public List<RoomData> GetUnvisitedRooms()
|
||||||
{
|
{
|
||||||
List<RoomData> result = new List<RoomData>();
|
List<RoomData> result = new List<RoomData>();
|
||||||
@@ -70,7 +70,7 @@ public List<RoomData> GetUnvisitedRooms()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 대화 선택지에 보여줄 랜덤 방 목록 반환
|
// 대화 선택지에 보여줄 랜덤 방 목록 반환
|
||||||
public List<RoomData> GetRandomNextRooms()
|
public List<RoomData> GetRandomNextRooms()
|
||||||
{
|
{
|
||||||
List<RoomData> unvisitedRooms = GetUnvisitedRooms();
|
List<RoomData> unvisitedRooms = GetUnvisitedRooms();
|
||||||
@@ -89,18 +89,18 @@ public List<RoomData> GetRandomNextRooms()
|
|||||||
return randomRooms;
|
return randomRooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 버튼이나 대화 선택지에서 호출
|
// 버튼이나 대화 선택지에서 호출
|
||||||
public void MoveToRoom(int roomNumber)
|
public void MoveToRoom(int roomNumber)
|
||||||
{
|
{
|
||||||
if (SceneLoadManager.Instance == null)
|
if (SceneLoadManager.Instance == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SceneLoadManager.Instance.IsChangingScene)
|
if (SceneLoadManager.Instance.IsChangingScene)
|
||||||
{
|
{
|
||||||
Debug.Log("이미 씬 이동 중입니다.");
|
Debug.Log("이미 씬 이동 중입니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,19 +108,19 @@ public void MoveToRoom(int roomNumber)
|
|||||||
|
|
||||||
if (targetRoom == null)
|
if (targetRoom == null)
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"방 정보를 찾을 수 없습니다. 방 번호: {roomNumber}");
|
Debug.LogWarning($"방 정보를 찾을 수 없습니다. 방 번호: {roomNumber}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_visitedRooms.Contains(roomNumber))
|
if (_visitedRooms.Contains(roomNumber))
|
||||||
{
|
{
|
||||||
Debug.Log($"이미 방문한 방입니다. 방 번호: {roomNumber}");
|
Debug.Log($"이미 방문한 방입니다. 방 번호: {roomNumber}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(targetRoom.sceneName))
|
if (string.IsNullOrEmpty(targetRoom.sceneName))
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"방 {roomNumber}의 Scene 이름이 비어있습니다.");
|
Debug.LogWarning($"방 {roomNumber}의 Scene 이름이 비어있습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,14 +130,14 @@ public void MoveToRoom(int roomNumber)
|
|||||||
SceneLoadManager.Instance.RequestSceneChange(targetRoom.sceneName);
|
SceneLoadManager.Instance.RequestSceneChange(targetRoom.sceneName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 랜덤 방 하나로 바로 이동하고 싶을 때 사용
|
// 랜덤 방 하나로 바로 이동하고 싶을 때 사용
|
||||||
public void MoveToRandomRoom()
|
public void MoveToRandomRoom()
|
||||||
{
|
{
|
||||||
List<RoomData> unvisitedRooms = GetUnvisitedRooms();
|
List<RoomData> unvisitedRooms = GetUnvisitedRooms();
|
||||||
|
|
||||||
if (unvisitedRooms.Count <= 0)
|
if (unvisitedRooms.Count <= 0)
|
||||||
{
|
{
|
||||||
Debug.Log("방문하지 않은 방이 없습니다.");
|
Debug.Log("방문하지 않은 방이 없습니다.");
|
||||||
|
|
||||||
if (IsAllRoomsVisited())
|
if (IsAllRoomsVisited())
|
||||||
{
|
{
|
||||||
@@ -162,25 +162,25 @@ public void MoveToFinalScene()
|
|||||||
{
|
{
|
||||||
if (!IsAllRoomsVisited())
|
if (!IsAllRoomsVisited())
|
||||||
{
|
{
|
||||||
Debug.Log("아직 모든 방을 방문하지 않았습니다.");
|
Debug.Log("아직 모든 방을 방문하지 않았습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SceneLoadManager.Instance == null)
|
if (SceneLoadManager.Instance == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SceneLoadManager.Instance.IsChangingScene)
|
if (SceneLoadManager.Instance.IsChangingScene)
|
||||||
{
|
{
|
||||||
Debug.Log("이미 씬 이동 중입니다.");
|
Debug.Log("이미 씬 이동 중입니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(finalSceneName))
|
if (string.IsNullOrEmpty(finalSceneName))
|
||||||
{
|
{
|
||||||
Debug.LogWarning("마지막 Scene 이름이 비어있습니다.");
|
Debug.LogWarning("마지막 Scene 이름이 비어있습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
public class RhythmNoteInstance : MonoBehaviour
|
public class RhythmNoteInstance : MonoBehaviour
|
||||||
{
|
{
|
||||||
public float HitTime; // 이 노트의 도달 시각
|
[HideInInspector] public float HitTime; // 이 노트의 도달 시각
|
||||||
|
|
||||||
[SerializeField] private float _missWindow = 0.15f; // 판정선을 이만큼 지나면 자동 Miss
|
[SerializeField] private float _missWindow = 0.15f; // 판정선을 이만큼 지나면 자동 Miss
|
||||||
|
|
||||||
|
|||||||
37
Assets/02_Scripts/Rhythm/RhythmProjectile.cs
Normal file
37
Assets/02_Scripts/Rhythm/RhythmProjectile.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Hovl;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// Hovl의 HS_ProjectileMover(에셋)를 "수정하지 않고" 히트 이펙트를 코드로 터뜨리기 위한 서브클래스.
|
||||||
|
// 핵심: protected 멤버(hit/hitPS/projectilePS/collided)는 '파생 클래스'에서는 접근 가능하다.
|
||||||
|
// 그래서 에셋 원본은 그대로 두고, 충돌(Collision) 없이 판정 성공 시 Detonate()로 이펙트만 재생한다.
|
||||||
|
public class RhythmProjectile : HS_ProjectileMover
|
||||||
|
{
|
||||||
|
// 판정 성공 시 호출. 노트가 곧 Destroy되어도 이펙트가 보이도록 노트에서 분리 후 재생.
|
||||||
|
public void Detonate()
|
||||||
|
{
|
||||||
|
if (collided) return;
|
||||||
|
collided = true;
|
||||||
|
|
||||||
|
// 날아가는 동안의 트레일 파티클은 정지
|
||||||
|
if (projectilePS != null)
|
||||||
|
projectilePS.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
|
||||||
|
|
||||||
|
// 히트 이펙트 컨테이너(없으면 파티클 본체)를 노트에서 떼어내 현재 위치에서 재생
|
||||||
|
GameObject fx = hit != null ? hit : (hitPS != null ? hitPS.gameObject : null);
|
||||||
|
if (fx == null) return;
|
||||||
|
|
||||||
|
fx.transform.SetParent(null, true);
|
||||||
|
fx.transform.position = transform.position;
|
||||||
|
fx.SetActive(true);
|
||||||
|
|
||||||
|
if (hitPS != null)
|
||||||
|
{
|
||||||
|
hitPS.Clear(true);
|
||||||
|
hitPS.Play(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 재생이 끝나면 분리한 이펙트도 정리
|
||||||
|
float life = hitPS != null ? hitPS.main.duration + hitPS.main.startLifetime.constantMax : 2f;
|
||||||
|
Destroy(fx, life);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Rhythm/RhythmProjectile.cs.meta
Normal file
2
Assets/02_Scripts/Rhythm/RhythmProjectile.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9840334459414e240b44e1b0cfe4ebb2
|
||||||
59
Assets/02_Scripts/Rhythm/RhythmScore.cs
Normal file
59
Assets/02_Scripts/Rhythm/RhythmScore.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// 리듬게임 점수/콤보/판정수 누적 (Unity 비의존 순수 로직 - 테스트하기 쉬움)
|
||||||
|
public class RhythmScore
|
||||||
|
{
|
||||||
|
// 판정별 기본 점수
|
||||||
|
private const int PerfectPoint = 100;
|
||||||
|
private const int GoodPoint = 50;
|
||||||
|
private const int BadPoint = 10;
|
||||||
|
|
||||||
|
public int Score { get; private set; }
|
||||||
|
public int Combo { get; private set; }
|
||||||
|
public int MaxCombo { get; private set; }
|
||||||
|
|
||||||
|
public int PerfectCount { get; private set; }
|
||||||
|
public int GoodCount { get; private set; }
|
||||||
|
public int BadCount { get; private set; }
|
||||||
|
public int MissCount { get; private set; }
|
||||||
|
|
||||||
|
public int TotalJudged => PerfectCount + GoodCount + BadCount + MissCount;
|
||||||
|
|
||||||
|
// 판정 하나를 점수에 반영
|
||||||
|
public void Apply(Result result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case Result.Perfect:
|
||||||
|
PerfectCount++;
|
||||||
|
Combo++;
|
||||||
|
Score += PerfectPoint + Combo; // 콤보가 쌓일수록 보너스 (연속 보상)
|
||||||
|
break;
|
||||||
|
case Result.Good:
|
||||||
|
GoodCount++;
|
||||||
|
Combo++;
|
||||||
|
Score += GoodPoint + Combo;
|
||||||
|
break;
|
||||||
|
case Result.Bad:
|
||||||
|
BadCount++;
|
||||||
|
Combo = 0; // 콤보 끊김
|
||||||
|
Score += BadPoint;
|
||||||
|
break;
|
||||||
|
case Result.Miss:
|
||||||
|
MissCount++;
|
||||||
|
Combo = 0; // 콤보 끊김
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Combo > MaxCombo) MaxCombo = Combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
Score = 0;
|
||||||
|
Combo = 0;
|
||||||
|
MaxCombo = 0;
|
||||||
|
PerfectCount = 0;
|
||||||
|
GoodCount = 0;
|
||||||
|
BadCount = 0;
|
||||||
|
MissCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Rhythm/RhythmScore.cs.meta
Normal file
2
Assets/02_Scripts/Rhythm/RhythmScore.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: adfd55d5980f58940ad4cb735db42f89
|
||||||
50
Assets/02_Scripts/UI/RhythmResultHud.cs
Normal file
50
Assets/02_Scripts/UI/RhythmResultHud.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// 곡 종료 후 결과창. 총점/판정수/정확도/등급/최대콤보를 표시한다.
|
||||||
|
public class RhythmResultHud : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private RhythmManager _manager;
|
||||||
|
[SerializeField] private GameObject _root; // 결과창 루트
|
||||||
|
[SerializeField] private TMP_Text _scoreText;
|
||||||
|
[SerializeField] private TMP_Text _maxComboText;
|
||||||
|
[SerializeField] private TMP_Text _countText; // Perfect/Good/Bad/Miss 모아서 표시
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (_root != null) _root.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
if (_manager == null) return;
|
||||||
|
_manager.OnSongStarted += Hide;
|
||||||
|
_manager.OnSongFinished += Show;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
if (_manager == null) return;
|
||||||
|
_manager.OnSongStarted -= Hide;
|
||||||
|
_manager.OnSongFinished -= Show;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Hide()
|
||||||
|
{
|
||||||
|
if (_root != null) _root.SetActive(false); // 곡 시작/재시작 시 이전 결과창 숨김
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Show(RhythmScore score)
|
||||||
|
{
|
||||||
|
if (_scoreText != null) _scoreText.text = $"{score.Score:N0}";
|
||||||
|
if (_maxComboText != null) _maxComboText.text = $"{score.MaxCombo}";
|
||||||
|
if (_countText != null)
|
||||||
|
_countText.text =
|
||||||
|
$"Perfect {score.PerfectCount}\n" +
|
||||||
|
$"Good {score.GoodCount}\n" +
|
||||||
|
$"Bad {score.BadCount}\n" +
|
||||||
|
$"Miss {score.MissCount}";
|
||||||
|
|
||||||
|
if (_root != null) _root.SetActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/UI/RhythmResultHud.cs.meta
Normal file
2
Assets/02_Scripts/UI/RhythmResultHud.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b187e420986956a4ba9407759ed4050f
|
||||||
56
Assets/02_Scripts/UI/RhythmScoreHud.cs
Normal file
56
Assets/02_Scripts/UI/RhythmScoreHud.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// 플레이 중 실시간 점수/콤보 HUD. RhythmManager 이벤트만 구독하고 표시만 한다.
|
||||||
|
public class RhythmScoreHud : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private RhythmManager _manager;
|
||||||
|
[SerializeField] private GameObject _root; // HUD 루트 (곡 시작/종료에 켜고 끔)
|
||||||
|
[SerializeField] private TMP_Text _scoreText;
|
||||||
|
[SerializeField] private TMP_Text _comboText;
|
||||||
|
[SerializeField] private TMP_Text _judgeText; // Perfect/Good 등 최근 판정 표시(선택)
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (_root != null) _root.SetActive(false); // 곡 시작 전엔 숨김
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
if (_manager == null) return;
|
||||||
|
_manager.OnSongStarted += HandleSongStarted;
|
||||||
|
_manager.OnScoreChanged += HandleScoreChanged;
|
||||||
|
_manager.OnJudged += HandleJudged;
|
||||||
|
_manager.OnSongFinished += HandleSongFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
if (_manager == null) return;
|
||||||
|
_manager.OnSongStarted -= HandleSongStarted;
|
||||||
|
_manager.OnScoreChanged -= HandleScoreChanged;
|
||||||
|
_manager.OnJudged -= HandleJudged;
|
||||||
|
_manager.OnSongFinished -= HandleSongFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSongStarted()
|
||||||
|
{
|
||||||
|
if (_root != null) _root.SetActive(true); // 곡 시작 시 실시간 HUD 표시
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleScoreChanged(RhythmScore score)
|
||||||
|
{
|
||||||
|
if (_scoreText != null) _scoreText.text = $"SCORE {score.Score:N0}";
|
||||||
|
if (_comboText != null) _comboText.text = score.Combo > 0 ? $"{score.Combo}" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleJudged(Result result)
|
||||||
|
{
|
||||||
|
if (_judgeText != null) _judgeText.text = result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSongFinished(RhythmScore score)
|
||||||
|
{
|
||||||
|
if (_root != null) _root.SetActive(false); // 곡 끝나면 실시간 HUD는 숨김(결과창이 대신 뜸)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/UI/RhythmScoreHud.cs.meta
Normal file
2
Assets/02_Scripts/UI/RhythmScoreHud.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2d2c41822c633294a986c6803818303d
|
||||||
BIN
Assets/04_Models/Note/Prefabs/MusicNote.prefab
LFS
Normal file
BIN
Assets/04_Models/Note/Prefabs/MusicNote.prefab
LFS
Normal file
Binary file not shown.
8
Assets/04_Models/Note/Prefabs/MusicNote.prefab.meta
Normal file
8
Assets/04_Models/Note/Prefabs/MusicNote.prefab.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 016b7abd765146448b6113c33897f846
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/04_Models/Note/Prefabs/MusicNoteFlash.prefab
LFS
Normal file
BIN
Assets/04_Models/Note/Prefabs/MusicNoteFlash.prefab
LFS
Normal file
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 2f3e152888fa71247b0e4c40ea069d7d
|
guid: f17aaa526f39cef4a854fe7ea551e938
|
||||||
PrefabImporter:
|
PrefabImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
BIN
Assets/04_Models/Note/Prefabs/MusicNoteHit.prefab
LFS
Normal file
BIN
Assets/04_Models/Note/Prefabs/MusicNoteHit.prefab
LFS
Normal file
Binary file not shown.
7
Assets/04_Models/Note/Prefabs/MusicNoteHit.prefab.meta
Normal file
7
Assets/04_Models/Note/Prefabs/MusicNoteHit.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 754edce0f04b6f9439e9e265191c3194
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
Binary file not shown.
8
Assets/Hovl Studio.meta
Normal file
8
Assets/Hovl Studio.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1d081f5f40e505846a88e3fb578e2401
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Hovl Studio/AAA Projectiles Vol 1.meta
Normal file
8
Assets/Hovl Studio/AAA Projectiles Vol 1.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c262a4075a2ef114dad9068b20acf5fb
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c91658c11d664e34790852bb0af3d3e2
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 50ccb9ddb39784c4aad13fc3898fbdb9
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,139 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 859e8a749e01ae7468b1b3ab458011ff
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 11
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: WebGL
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/2DSceneGround.png
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 50611382ffa50c54a944ab4b11b5f311
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 25800000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/LightingData.asset
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e620f791dd3aad0468c5433f169817c6
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 0
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 3
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/Lightmap-0_comp_dir.png
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bedbfe6fe9ff7914aad490bf2e9e3283
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 3
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 0
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 6
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/Lightmap-0_comp_light.exr
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fa6be30dfbe92314c8d176a8eec4257b
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 0
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 3
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/Lightmap-1_comp_dir.png
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 231f20cb5603bff409380ec0b03baf96
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 3
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 0
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 6
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/Lightmap-1_comp_light.exr
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ef821dfa7c9bf544aa760c25c610cb6b
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 0
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 3
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/Lightmap-2_comp_dir.png
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 35c320ad9e9dc0d40bfa81b6cd7e2e8d
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 3
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 0
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 6
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/Lightmap-2_comp_light.exr
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,92 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eea823e4f8384c043ac514026f3ac126
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName:
|
||||||
|
8900000: generatedCubemap
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 5
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 1
|
||||||
|
seamlessCubemap: 1
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 2
|
||||||
|
aniso: 0
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 2
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 100
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/ReflectionProbe-0.exr
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 353e4ca07ddad704b8539591387bee38
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo files/SceneSmoke.prefab
|
||||||
|
uploadId: 883376
|
||||||
BIN
Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo projectiles 2D.unity
LFS
Normal file
BIN
Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo projectiles 2D.unity
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d6851c279dc96cc469706280632c676c
|
||||||
|
timeCreated: 1536001560
|
||||||
|
licenseType: Store
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo projectiles
|
||||||
|
2D.unity
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fbaf00a0124cb34408e401d2c9e82d44
|
||||||
|
timeCreated: 1536001560
|
||||||
|
licenseType: Store
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo projectiles
|
||||||
|
simple spawning.unity
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d77992b5fd5ef82498c6286aa500bdd6
|
||||||
|
timeCreated: 1536001560
|
||||||
|
licenseType: Store
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Demo projectiles(Full
|
||||||
|
particles).unity
|
||||||
|
uploadId: 883376
|
||||||
145
Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Readme.txt
Normal file
145
Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Readme.txt
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
Asset Creator - Vladyslav Horobets (Hovl).
|
||||||
|
All that is in the folder "AAA Projectiles" can be used in commerce, even demo scene files.
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
If you want to use post-effects like in the demo video:
|
||||||
|
https://youtu.be/hZSZ2Q8MF3k
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
1) Shaders
|
||||||
|
1.1)The "Use depth" on the material from the custom shaders is the Soft Particle Factor.
|
||||||
|
1.2)Use "Center glow"[MaterialToggle] only with particle system. This option is used to darken the main texture with a white texture (white is visible, black is invisible).
|
||||||
|
If you turn on this feature, you need to use "Custom vertex stream" (Uv0.Custom.xy) in tab "Render". And don't forget to use "Custom data" parameters in your PS.
|
||||||
|
1.3)The distortion shader only works with standard rendering. Delete (if exist) distortion particles from effects if you use LWRP or HDRP!
|
||||||
|
1.4)You can change the cutoff in all shaders (except Add_CenterGlow and Blend_CenterGlow ) using (Uv0.Custom.xy) in particle system.
|
||||||
|
|
||||||
|
2)Light.
|
||||||
|
2.1)You can disable light in the main effect component (delete light and disable light in PS).
|
||||||
|
Light strongly loads the game if you don't use light probes or something else.
|
||||||
|
|
||||||
|
3)Scripts
|
||||||
|
HS_ProjectileMover — Documentation
|
||||||
|
|
||||||
|
Description
|
||||||
|
HS_ProjectileMover controls the movement, collision behavior, and visual effects of projectile objects.
|
||||||
|
It handles projectile speed, hit effects, particle systems, detached VFX elements, and supports both destruction and pooling workflows.
|
||||||
|
|
||||||
|
The script is designed for VFX projectiles used in spells, bullets, energy blasts, or similar effects.
|
||||||
|
|
||||||
|
Main Features:
|
||||||
|
|
||||||
|
Moves projectile forward using Rigidbody velocity
|
||||||
|
Spawns hit effects on collision
|
||||||
|
Supports pooled projectiles (reuse instead of destroy)
|
||||||
|
Handles particle systems properly on impact
|
||||||
|
Allows detached particle effects to continue playing after collision
|
||||||
|
Automatically restores detached objects when projectile is reused
|
||||||
|
|
||||||
|
Key Parameters:
|
||||||
|
|
||||||
|
Speed -
|
||||||
|
Controls the forward velocity of the projectile.
|
||||||
|
Hit Offset -
|
||||||
|
Moves the hit effect slightly away from the surface normal to avoid clipping.
|
||||||
|
Use Fire Point Rotation -
|
||||||
|
If enabled, the hit effect rotation will match the fire point orientation.
|
||||||
|
Rotation Offset -
|
||||||
|
Optional rotation override applied to the hit effect.
|
||||||
|
Hit -
|
||||||
|
GameObject used as the hit effect container.
|
||||||
|
Hit PS -
|
||||||
|
Particle system played when the projectile collides.
|
||||||
|
Flash -
|
||||||
|
Optional muzzle flash object that detaches on spawn.
|
||||||
|
Projectile PS -
|
||||||
|
Main projectile particle system.
|
||||||
|
Detached -
|
||||||
|
Array of objects that contain particle systems (such as trails or smoke).
|
||||||
|
These objects detach on impact so their particles can finish playing naturally.
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
RB -
|
||||||
|
Rigidbody used for projectile movement.
|
||||||
|
Col -
|
||||||
|
Collider used for collision detection.
|
||||||
|
Light Source -
|
||||||
|
Optional light attached to the projectile.
|
||||||
|
|
||||||
|
Lifetime Settings
|
||||||
|
|
||||||
|
Not Destroy
|
||||||
|
If enabled, the projectile will be disabled instead of destroyed.
|
||||||
|
This allows it to be reused with an object pool.
|
||||||
|
|
||||||
|
Life Time
|
||||||
|
Maximum lifetime of the projectile if it does not hit anything.
|
||||||
|
|
||||||
|
Detached Life Time
|
||||||
|
How long detached particle objects remain alive after impact.
|
||||||
|
|
||||||
|
Collision Behavior
|
||||||
|
|
||||||
|
When the projectile collides:
|
||||||
|
|
||||||
|
Rigidbody movement is stopped
|
||||||
|
Light and collider are disabled
|
||||||
|
Projectile particle emission stops
|
||||||
|
Hit effect is positioned and played
|
||||||
|
Detached objects are unparented
|
||||||
|
Detached particle systems stop emitting but existing particles finish their lifetime
|
||||||
|
|
||||||
|
If Not Destroy is enabled:
|
||||||
|
The projectile will be disabled after the hit effect finishes
|
||||||
|
Detached objects will be restored when the projectile is reused
|
||||||
|
|
||||||
|
If Not Destroy is disabled:
|
||||||
|
The projectile will be destroyed after the hit effect duration
|
||||||
|
Detached objects will be destroyed after Detached Life Time
|
||||||
|
|
||||||
|
Detached Objects Logic:
|
||||||
|
Detached objects must be child objects of the projectile.
|
||||||
|
Each detached object can contain multiple particle systems.
|
||||||
|
|
||||||
|
On collision:
|
||||||
|
The object is unparented
|
||||||
|
Emission stops
|
||||||
|
Existing particles finish their lifetime
|
||||||
|
If pooling is enabled, the objects are restored to their original parent when the projectile is reactivated.
|
||||||
|
|
||||||
|
Typical Use Case:
|
||||||
|
Projectile Prefab Structure Example
|
||||||
|
|
||||||
|
Projectile
|
||||||
|
├── Mesh
|
||||||
|
├── Collider
|
||||||
|
├── Rigidbody
|
||||||
|
├── Projectile_PS
|
||||||
|
├── Flash
|
||||||
|
└── Detached_Trail
|
||||||
|
├── Smoke
|
||||||
|
└── Sparks
|
||||||
|
|
||||||
|
Pooling Support
|
||||||
|
|
||||||
|
When using an object pool:
|
||||||
|
|
||||||
|
Set:
|
||||||
|
Not Destroy = true
|
||||||
|
The projectile will be disabled instead of destroyed and can be reused safely.
|
||||||
|
Detached particle objects will automatically return to their original positions when the projectile is activated again.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Detached objects should only contain particle systems.
|
||||||
|
Ensure Rigidbody and Collider references are assigned.
|
||||||
|
Projectile should face forward in the Z direction for correct movement.
|
||||||
|
|
||||||
|
|
||||||
|
4)Quality
|
||||||
|
4.1) For better sparks quality enable "Anisotropic textures: Forced On" in quality settings.
|
||||||
|
|
||||||
|
SUPPORT ASSET FOR BiRP, URP or HDRP is here --> Tools > RP changer for Hovl Studio Assets
|
||||||
|
|
||||||
|
Contact me if you have any questions.
|
||||||
|
My email: hovlstudio1@gmail.com
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9037c8e5bfd08444291e6100663e92b8
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Demo scenes/Readme.txt
|
||||||
|
uploadId: 883376
|
||||||
8
Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs.meta
Normal file
8
Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 101b1b40990f0e2488f0ed1b0c84d92e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1a3f2842eceda1d4db93e93468d2e1ec
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ccc22a316744f104eb233bd6122a3ec3
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Dragon
|
||||||
|
punch flash.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a311f5de96916bf44bcb1dae61840939
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
1 nature arrow.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f2f9845677ab3f49be1179d6bd15b78
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
10 blue laser.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d2bf40a98ef3560439f0badec6115db3
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
11 orange arrow.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 55b36a9461ee12b4b9ed1546b95e8ba4
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
12 slime.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 284aa8115675f03488377d544e50cbf5
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
13 red laser.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 058c6c6f7bee2fc45a91fbdb528a9035
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
14 blue rapid.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dfb11343e1f738848a39590c5e36c883
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
15 pink crystal.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f326479f7cef0794d95f29731f4bbdb3
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
16 fire.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6c45d61ea68f82b4eb2c7f1ff7fdcb81
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
17 nova violet.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: df8bef245b1373047a1e1320f5ed6ac2
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
18 nova orange.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2ad5c1a0f3dfb2a479c897ce5c0c6d82
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
19 circle bomb.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5b0ac738fb141244d96b28bbd07be221
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
2 electro.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0254f8e683e300c4eb1b598011e9b7c8
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
22 cute star.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d629efdae70f475409893aa79aeafd1e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
23 cube.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 918bed4b1a6905d4aaa25af94c2caa31
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
24 green explosion.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d6042f989cc140942a980eadd962e2db
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
25 orange explosion.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 25f0a817a944f794d8af1e1ea326f16c
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
26 blue crystal.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28538e5931854494fbe4d98d2d4cd548
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
27 heart.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f82a1a892a042c1438f8f4704a37e11b
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
AssetOrigin:
|
||||||
|
serializedVersion: 1
|
||||||
|
productId: 315729
|
||||||
|
packageName: BIG Projectiles bundle
|
||||||
|
packageVersion: 3.1
|
||||||
|
assetPath: Assets/Hovl Studio/AAA Projectiles Vol 1/Prefabs/Flash and hits/Flash
|
||||||
|
3 black fire.prefab
|
||||||
|
uploadId: 883376
|
||||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user