ADD : 요요 보스 레이드 기능 페이셜 필터 강화 기능 ik 포인트 해결
This commit is contained in:
parent
3929be8974
commit
074c11eb8a
@ -4,12 +4,57 @@ using UnityEngine;
|
||||
[CustomEditor(typeof(OptitrackSkeletonAnimator_Mingle))]
|
||||
public class OptitrackSkeletonAnimatorEditor : Editor
|
||||
{
|
||||
private static readonly string[] k_FilterLabels = { "Off", "Low", "Medium", "High", "Custom" };
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
|
||||
var anim = (OptitrackSkeletonAnimator_Mingle)target;
|
||||
|
||||
// 필터 강도 버튼 나열
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.LabelField("필터 강도", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
for (int i = 0; i < k_FilterLabels.Length; i++)
|
||||
{
|
||||
var strength = (OptitrackSkeletonAnimator_Mingle.FilterStrength)i;
|
||||
bool isSelected = anim.filterStrength == strength;
|
||||
|
||||
var prevBgBtn = GUI.backgroundColor;
|
||||
GUI.backgroundColor = isSelected ? new Color(0.4f, 0.7f, 1f) : Color.white;
|
||||
|
||||
if (GUILayout.Button(k_FilterLabels[i], GUILayout.Height(24)))
|
||||
{
|
||||
Undo.RecordObject(anim, "Change Filter Strength");
|
||||
anim.SetFilterStrength(strength);
|
||||
EditorUtility.SetDirty(anim);
|
||||
}
|
||||
|
||||
GUI.backgroundColor = prevBgBtn;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// Custom일 때 슬라이더 표시
|
||||
if (anim.filterStrength == OptitrackSkeletonAnimator_Mingle.FilterStrength.Custom)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
float minCutoff = EditorGUILayout.Slider("Min Cutoff (Hz)", anim.filterMinCutoff, 0.1f, 10f);
|
||||
float beta = EditorGUILayout.Slider("Beta", anim.filterBeta, 0f, 5f);
|
||||
float maxCutoff = EditorGUILayout.Slider("Max Cutoff (Hz)", anim.filterMaxCutoff, 5f, 120f);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(anim, "Change Filter Custom Values");
|
||||
anim.filterMinCutoff = minCutoff;
|
||||
anim.filterBeta = beta;
|
||||
anim.filterMaxCutoff = maxCutoff;
|
||||
EditorUtility.SetDirty(anim);
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// 연결 상태 배지
|
||||
EditorGUILayout.Space(8);
|
||||
var prevBg = GUI.backgroundColor;
|
||||
|
||||
@ -33,19 +33,53 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour
|
||||
[Tooltip("에디터에서 캡처한 T-포즈 데이터. 비어 있으면 런타임 CacheRestPose()를 사용합니다.")]
|
||||
public OptitrackRestPoseData RestPoseAsset;
|
||||
|
||||
public enum FilterStrength { Off, Low, Medium, High, Custom }
|
||||
|
||||
[Header("본 1€ 필터 (속도 적응형 저역통과)")]
|
||||
[Tooltip("활성화 시 빠른 움직임은 그대로, 정지/느린 움직임의 노이즈를 제거합니다.\n단순 EMA보다 모션 보존이 훨씬 우수합니다.")]
|
||||
public bool enableBoneFilter = true;
|
||||
[Tooltip("최소 차단 주파수 (Hz). 정지 시 노이즈 제거 강도. 낮을수록 강함. 권장: 2~4 Hz")]
|
||||
[Range(0.1f, 10f)]
|
||||
public float filterMinCutoff = 3.0f;
|
||||
[Tooltip("속도 계수. 빠른 동작에서 cutoff 상승 속도. 높을수록 지연 감소. 권장: 0.5~2.0")]
|
||||
[Range(0f, 5f)]
|
||||
public float filterBeta = 1.5f;
|
||||
[Tooltip("최대 차단 주파수 상한 (Hz). 빠른 동작에서도 이 이상 주파수는 항상 제거됩니다.\n" +
|
||||
"MagicaCloth2 지터가 빠른 동작에서 발생하면 낮추세요. 권장: 10~20 Hz")]
|
||||
[Range(5f, 120f)]
|
||||
public float filterMaxCutoff = 15.0f;
|
||||
[HideInInspector]
|
||||
public FilterStrength filterStrength = FilterStrength.Medium;
|
||||
|
||||
[HideInInspector] public float filterMinCutoff = 3.0f;
|
||||
[HideInInspector] public float filterBeta = 1.5f;
|
||||
[HideInInspector] public float filterMaxCutoff = 15.0f;
|
||||
|
||||
// 프리셋별 파라미터 (minCutoff, beta, maxCutoff)
|
||||
private static readonly (float minCutoff, float beta, float maxCutoff)[] k_FilterPresets =
|
||||
{
|
||||
(0f, 0f, 0f), // Off (사용 안 함)
|
||||
(5.0f, 2.0f, 25.0f), // Low
|
||||
(3.0f, 1.5f, 15.0f), // Medium
|
||||
(1.5f, 0.8f, 10.0f), // High
|
||||
(0f, 0f, 0f), // Custom (프리셋 적용 안 함)
|
||||
};
|
||||
|
||||
[HideInInspector] public bool enableBoneFilter = true;
|
||||
|
||||
/// <summary>
|
||||
/// 런타임에서 필터 강도를 변경합니다. StreamDeck/핫키 등에서 호출.
|
||||
/// </summary>
|
||||
public void SetFilterStrength(FilterStrength strength)
|
||||
{
|
||||
filterStrength = strength;
|
||||
if (strength != FilterStrength.Off && strength != FilterStrength.Custom)
|
||||
{
|
||||
var preset = k_FilterPresets[(int)strength];
|
||||
filterMinCutoff = preset.minCutoff;
|
||||
filterBeta = preset.beta;
|
||||
filterMaxCutoff = preset.maxCutoff;
|
||||
}
|
||||
// 프리셋 전환 시 필터 상태 리셋 (이전 값과 불연속 방지)
|
||||
m_filterStates.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 프리셋에서 다음 프리셋으로 순환. 버튼 하나로 Off→Low→Medium→High→Custom→Off...
|
||||
/// </summary>
|
||||
public void CycleFilterStrength()
|
||||
{
|
||||
int next = ((int)filterStrength + 1) % System.Enum.GetValues(typeof(FilterStrength)).Length;
|
||||
SetFilterStrength((FilterStrength)next);
|
||||
}
|
||||
|
||||
private OptitrackSkeletonDefinition m_skeletonDef;
|
||||
private string previousSkeletonName;
|
||||
@ -239,6 +273,9 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
// 필터 활성화 상태 동기화 (프리셋 값은 SetFilterStrength()에서만 적용)
|
||||
enableBoneFilter = filterStrength != FilterStrength.Off;
|
||||
|
||||
// MirrorMode 변경 감지 → 필터 상태 리셋 (불연속 튐 방지)
|
||||
bool currentMirrorMode = StreamingClient != null && StreamingClient.MirrorMode;
|
||||
if (currentMirrorMode != m_lastMirrorMode)
|
||||
|
||||
@ -17,6 +17,9 @@ public class StreamingleFacialReceiverEditor : Editor
|
||||
private VisualElement statusContainer;
|
||||
private VisualElement emaFields;
|
||||
private VisualElement euroFields;
|
||||
private VisualElement medianEuroFields;
|
||||
private VisualElement sharedPortInfo;
|
||||
private Label masterStatusValue;
|
||||
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
@ -40,6 +43,9 @@ public class StreamingleFacialReceiverEditor : Editor
|
||||
portButtonsContainer = root.Q("portButtonsContainer");
|
||||
emaFields = root.Q("emaFields");
|
||||
euroFields = root.Q("euroFields");
|
||||
medianEuroFields = root.Q("medianEuroFields");
|
||||
sharedPortInfo = root.Q("sharedPortInfo");
|
||||
masterStatusValue = root.Q<Label>("masterStatusValue");
|
||||
|
||||
// Auto-find button
|
||||
var autoFindBtn = root.Q<Button>("autoFindBtn");
|
||||
@ -50,7 +56,7 @@ public class StreamingleFacialReceiverEditor : Editor
|
||||
// Build dynamic port buttons
|
||||
RebuildPortButtons();
|
||||
|
||||
// Track filterMode for conditional visibility of EMA/Euro fields
|
||||
// Track filterMode for conditional visibility of filter fields
|
||||
var filterModeProp = serializedObject.FindProperty("filterMode");
|
||||
UpdateFilterModeVisibility(filterModeProp.enumValueIndex);
|
||||
|
||||
@ -59,6 +65,15 @@ public class StreamingleFacialReceiverEditor : Editor
|
||||
UpdateFilterModeVisibility(prop.enumValueIndex);
|
||||
});
|
||||
|
||||
// Track useSharedPort for info visibility
|
||||
var sharedPortProp = serializedObject.FindProperty("useSharedPort");
|
||||
UpdateSharedPortVisibility(sharedPortProp.boolValue);
|
||||
|
||||
root.TrackPropertyValue(sharedPortProp, prop =>
|
||||
{
|
||||
UpdateSharedPortVisibility(prop.boolValue);
|
||||
});
|
||||
|
||||
// Track availablePorts and activePortIndex changes to rebuild port buttons
|
||||
var portsProp = serializedObject.FindProperty("availablePorts");
|
||||
root.TrackPropertyValue(portsProp, _ => RebuildPortButtons());
|
||||
@ -74,11 +89,19 @@ public class StreamingleFacialReceiverEditor : Editor
|
||||
|
||||
private void UpdateFilterModeVisibility(int modeIndex)
|
||||
{
|
||||
// FilterMode: 0=None, 1=EMA, 2=OneEuro
|
||||
// FilterMode: 0=None, 1=EMA, 2=OneEuro, 3=MedianOneEuro
|
||||
if (emaFields != null)
|
||||
emaFields.style.display = modeIndex == 1 ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
if (euroFields != null)
|
||||
euroFields.style.display = modeIndex == 2 ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
if (medianEuroFields != null)
|
||||
medianEuroFields.style.display = modeIndex == 3 ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void UpdateSharedPortVisibility(bool useShared)
|
||||
{
|
||||
if (sharedPortInfo != null)
|
||||
sharedPortInfo.style.display = useShared ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void RebuildPortButtons()
|
||||
@ -189,5 +212,30 @@ public class StreamingleFacialReceiverEditor : Editor
|
||||
statusContainer.AddToClassList("facial-status-container--visible");
|
||||
else if (!isPlaying && statusContainer.ClassListContains("facial-status-container--visible"))
|
||||
statusContainer.RemoveFromClassList("facial-status-container--visible");
|
||||
|
||||
// 마스터 상태 업데이트 (플레이 모드에서만)
|
||||
if (isPlaying && masterStatusValue != null && receiver != null && receiver.useSharedPort)
|
||||
{
|
||||
try
|
||||
{
|
||||
var status = StreamingleFacialUdpMaster.Instance.GetPortStatus();
|
||||
if (status.TryGetValue(receiver.LOCAL_PORT, out int count))
|
||||
{
|
||||
masterStatusValue.text = $"Port {receiver.LOCAL_PORT}: {count} Receiver(s)";
|
||||
}
|
||||
else
|
||||
{
|
||||
masterStatusValue.text = "Not connected";
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
masterStatusValue.text = "---";
|
||||
}
|
||||
}
|
||||
else if (masterStatusValue != null)
|
||||
{
|
||||
masterStatusValue.text = receiver != null && receiver.useSharedPort ? "Play 모드에서 활성화" : "---";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +72,39 @@
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* ---- Shared Port (Master Mode) ---- */
|
||||
|
||||
.facial-shared-port-info {
|
||||
padding: 6px 8px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
background-color: rgba(99, 102, 241, 0.1);
|
||||
border-radius: 4px;
|
||||
border-left-width: 3px;
|
||||
border-left-color: rgba(99, 102, 241, 0.5);
|
||||
}
|
||||
|
||||
.facial-info-text {
|
||||
font-size: 10px;
|
||||
color: #94a3b8;
|
||||
-unity-font-style: italic;
|
||||
white-space: normal;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.facial-master-status-row {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.facial-master-status-value {
|
||||
-unity-font-style: bold;
|
||||
font-size: 11px;
|
||||
color: #a5b4fc;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* ---- Port Hot-Swap ---- */
|
||||
|
||||
.facial-active-port-row {
|
||||
@ -137,6 +170,19 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
#medianEuroFields {
|
||||
padding-left: 16px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.facial-filter-separator-label {
|
||||
font-size: 10px;
|
||||
color: #64748b;
|
||||
-unity-text-align: middle-center;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
/* ---- Facial Intensity ---- */
|
||||
|
||||
.facial-separator {
|
||||
|
||||
@ -21,6 +21,20 @@
|
||||
</ui:Foldout>
|
||||
</ui:VisualElement>
|
||||
|
||||
<!-- Shared Port (Master Mode) -->
|
||||
<ui:VisualElement class="section">
|
||||
<ui:Foldout text="Shared Port (Master Mode)" value="true" class="section-foldout">
|
||||
<uie:PropertyField binding-path="useSharedPort" label="Use Shared Port"/>
|
||||
<ui:VisualElement name="sharedPortInfo" class="facial-shared-port-info">
|
||||
<ui:Label text="같은 포트에 여러 Receiver를 연결하여 동일한 모캡 데이터를 공유 수신합니다." class="facial-info-text"/>
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="masterStatusRow" class="facial-master-status-row">
|
||||
<ui:Label text="Master Status" class="facial-port-label"/>
|
||||
<ui:Label name="masterStatusValue" text="---" class="facial-master-status-value"/>
|
||||
</ui:VisualElement>
|
||||
</ui:Foldout>
|
||||
</ui:VisualElement>
|
||||
|
||||
<!-- Port Hot-Swap (port buttons built dynamically in C#) -->
|
||||
<ui:VisualElement class="section">
|
||||
<ui:Foldout text="Port Hot-Swap" value="true" class="section-foldout">
|
||||
@ -51,6 +65,15 @@
|
||||
<uie:PropertyField binding-path="euroBeta" label="Beta (Speed Coeff)"/>
|
||||
<uie:PropertyField binding-path="euroDCutoff" label="D Cutoff (Hz)"/>
|
||||
</ui:VisualElement>
|
||||
<!-- Median+Euro Filter Fields -->
|
||||
<ui:VisualElement name="medianEuroFields">
|
||||
<uie:PropertyField binding-path="medianWindowSize" label="Median Window Size"/>
|
||||
<ui:Label text="── OneEuro Params ──" class="facial-filter-separator-label"/>
|
||||
<uie:PropertyField binding-path="euroMinCutoff" label="Min Cutoff (Hz)"/>
|
||||
<uie:PropertyField binding-path="euroBeta" label="Beta (Speed Coeff)"/>
|
||||
<uie:PropertyField binding-path="euroDCutoff" label="D Cutoff (Hz)"/>
|
||||
<ui:Label text="Median(스파이크제거) → OneEuro(적응형스무딩)" class="facial-info-text"/>
|
||||
</ui:VisualElement>
|
||||
</ui:Foldout>
|
||||
</ui:VisualElement>
|
||||
|
||||
|
||||
46
Assets/External/StreamingleFacial/FacialFilterUtils.cs
vendored
Normal file
46
Assets/External/StreamingleFacial/FacialFilterUtils.cs
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Median Filter - 임펄스 노이즈(스파이크) 제거에 탁월
|
||||
/// 윈도우 내 중앙값을 출력하여 이상치를 자연스럽게 배제
|
||||
///
|
||||
/// OneEuroFilter 앞에 전처리로 사용하면 (MedianOneEuro 모드)
|
||||
/// 스파이크 제거 + 적응형 스무딩의 조합으로 최고 품질의 필터링 가능
|
||||
///
|
||||
/// windowSize: 홀수 권장 (3=최소 지연, 5=일반, 7+=강한 스파이크 제거)
|
||||
/// </summary>
|
||||
public class MedianFilter
|
||||
{
|
||||
private readonly float[] buffer;
|
||||
private readonly float[] sorted;
|
||||
private int count;
|
||||
private int writeIndex;
|
||||
|
||||
public MedianFilter(int windowSize = 5)
|
||||
{
|
||||
int size = Mathf.Max(3, windowSize | 1); // 홀수로 강제
|
||||
buffer = new float[size];
|
||||
sorted = new float[size];
|
||||
count = 0;
|
||||
writeIndex = 0;
|
||||
}
|
||||
|
||||
public float Filter(float value)
|
||||
{
|
||||
buffer[writeIndex] = value;
|
||||
writeIndex = (writeIndex + 1) % buffer.Length;
|
||||
if (count < buffer.Length) count++;
|
||||
|
||||
// 현재 윈도우를 정렬하여 중앙값 반환
|
||||
System.Array.Copy(buffer, sorted, count);
|
||||
System.Array.Sort(sorted, 0, count);
|
||||
|
||||
return sorted[count / 2];
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
count = 0;
|
||||
writeIndex = 0;
|
||||
}
|
||||
}
|
||||
2
Assets/External/StreamingleFacial/FacialFilterUtils.cs.meta
vendored
Normal file
2
Assets/External/StreamingleFacial/FacialFilterUtils.cs.meta
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c90c541f662e9d489f79aa99fea0162
|
||||
@ -3,6 +3,7 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
@ -21,6 +22,11 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
private string messageString = "";
|
||||
private string lastProcessedMessage = ""; // 이전 메시지 저장용
|
||||
|
||||
// ── 공유 포트 (마스터 모드) ──
|
||||
[Header("Shared Port (Master Mode)")]
|
||||
[Tooltip("활성화 시 UdpMaster를 통해 같은 포트의 데이터를 여러 Receiver가 공유 수신")]
|
||||
public bool useSharedPort = true;
|
||||
|
||||
// 포트 핫스왑 시스템
|
||||
[Header("Port Hot-Swap")]
|
||||
[Tooltip("사용 가능한 아이폰 포트 목록")]
|
||||
@ -31,11 +37,11 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
public int LOCAL_PORT => availablePorts != null && activePortIndex < availablePorts.Length ? availablePorts[activePortIndex] : 49983;
|
||||
|
||||
// 필터 모드 설정
|
||||
public enum FilterMode { None, EMA, OneEuro }
|
||||
public enum FilterMode { None, EMA, OneEuro, MedianOneEuro }
|
||||
|
||||
[Header("Data Filtering")]
|
||||
[Tooltip("필터링 모드: None=필터없음, EMA=기존 스무딩+스파이크, OneEuro=1€ 적응형 필터")]
|
||||
public FilterMode filterMode = FilterMode.OneEuro;
|
||||
[Tooltip("필터링 모드: None=필터없음, EMA=스무딩+스파이크, OneEuro=1€ 적응형, Kalman=칼만필터, MedianOneEuro=메디안+1€ 복합")]
|
||||
public FilterMode filterMode = FilterMode.MedianOneEuro;
|
||||
|
||||
// EMA 필터 설정 (기존 호환)
|
||||
[Header("EMA Filter Settings")]
|
||||
@ -67,16 +73,26 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
[Range(0.1f, 5f)]
|
||||
public float euroDCutoff = 1.0f;
|
||||
|
||||
// Euro 필터 인스턴스 (블렌드쉐이프별)
|
||||
// Median+OneEuro 복합 필터 설정
|
||||
[Header("Median+Euro Filter Settings")]
|
||||
[Tooltip("Median 윈도우 크기 (홀수). 스파이크 제거용. 3=최소 지연, 5=일반, 7+=강한 제거")]
|
||||
[Range(3, 11)]
|
||||
public int medianWindowSize = 5;
|
||||
|
||||
// ── 필터 인스턴스 ──
|
||||
// Euro 필터
|
||||
private Dictionary<string, OneEuroFilter> euroFilters = new Dictionary<string, OneEuroFilter>();
|
||||
private float euroMinCutoffPrev, euroBetaPrev, euroDCutoffPrev;
|
||||
|
||||
// EMA 필터링용 이전 값 저장
|
||||
// EMA 필터링용 이전 값
|
||||
private Dictionary<string, float> prevBlendShapeValues = new Dictionary<string, float>();
|
||||
|
||||
// 연속 스파이크 추적 (같은 방향으로 연속이면 실제 움직임)
|
||||
// 연속 스파이크 추적
|
||||
private Dictionary<string, int> blendShapeSpikeCount = new Dictionary<string, int>();
|
||||
private Dictionary<string, float> blendShapeSpikeDirection = new Dictionary<string, float>();
|
||||
// Median 필터 (MedianOneEuro용)
|
||||
private Dictionary<string, MedianFilter> medianFilters = new Dictionary<string, MedianFilter>();
|
||||
// MedianOneEuro용 Euro 필터 (별도 인스턴스)
|
||||
private Dictionary<string, OneEuroFilter> medianEuroFilters = new Dictionary<string, OneEuroFilter>();
|
||||
private int medianWindowSizePrev;
|
||||
|
||||
// 빠르게 변하는 BlendShape 목록 (눈 깜빡임, 입 등)
|
||||
private static readonly HashSet<string> FastBlendShapes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
@ -153,6 +169,18 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
// 재접속 코루틴 중복 방지
|
||||
private Coroutine reconnectCoroutine;
|
||||
|
||||
// ── 마스터 모드에서 호출되는 메서드 ──
|
||||
/// <summary>
|
||||
/// UdpMaster가 메시지를 분배할 때 호출. 직접 호출하지 마세요.
|
||||
/// </summary>
|
||||
public void SetMessageFromMaster(string msg)
|
||||
{
|
||||
messageString = msg;
|
||||
}
|
||||
|
||||
// Start is called
|
||||
void StartFunction()
|
||||
{
|
||||
@ -165,10 +193,18 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
// BlendShape 인덱스 캐싱 초기화
|
||||
InitializeBlendShapeCache();
|
||||
|
||||
//Recieve udp from iOS
|
||||
if (useSharedPort)
|
||||
{
|
||||
// 마스터 모드: UdpMaster에 등록하여 공유 수신
|
||||
StreamingleFacialUdpMaster.Instance.Register(LOCAL_PORT, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 독립 모드: 자체 UDP 서버 생성
|
||||
CreateUdpServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
@ -248,9 +284,12 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
if (euroFilters != null)
|
||||
{
|
||||
foreach (var filter in euroFilters.Values)
|
||||
{
|
||||
filter.UpdateParams(euroMinCutoff, euroBeta, euroDCutoff);
|
||||
}
|
||||
if (medianEuroFilters != null)
|
||||
{
|
||||
foreach (var filter in medianEuroFilters.Values)
|
||||
filter.UpdateParams(euroMinCutoff, euroBeta, euroDCutoff);
|
||||
}
|
||||
euroMinCutoffPrev = euroMinCutoff;
|
||||
euroBetaPrev = euroBeta;
|
||||
@ -446,6 +485,11 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
Debug.LogError($"[iFacialMocap] 데이터 수신 오류: {e.Message}");
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// UDP 소켓이 닫힌 경우 (정상 종료 시 발생)
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// 스레드 종료 중이면 로그 생략
|
||||
@ -455,7 +499,6 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
}
|
||||
|
||||
// CPU를 양보하는 Sleep 사용 (5ms 대기)
|
||||
// Busy waiting 대신 Thread.Sleep으로 CPU 사용률 감소
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
}
|
||||
@ -488,9 +531,21 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
if (StartFlag == false)
|
||||
{
|
||||
StartFlag = true;
|
||||
|
||||
if (useSharedPort)
|
||||
{
|
||||
// 마스터에서 해제
|
||||
if (StreamingleFacialUdpMaster.Instance != null)
|
||||
{
|
||||
StreamingleFacialUdpMaster.Instance.Unregister(LOCAL_PORT, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StopUDP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void StopUDP()
|
||||
@ -500,21 +555,21 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
|
||||
// UDP 종료
|
||||
if (udp != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
udp.Close();
|
||||
udp.Dispose();
|
||||
}
|
||||
catch (Exception) { }
|
||||
udp = null;
|
||||
}
|
||||
|
||||
// 스레드가 종료될 때까지 대기 (최대 100ms)
|
||||
// 스레드가 종료될 때까지 대기 (최대 300ms)
|
||||
if (thread != null && thread.IsAlive)
|
||||
{
|
||||
thread.Join(100);
|
||||
|
||||
// 그래도 종료되지 않으면 강제 종료
|
||||
if (thread.IsAlive)
|
||||
{
|
||||
thread.Abort();
|
||||
}
|
||||
thread.Join(300);
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,39 +584,62 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
int oldPort = LOCAL_PORT;
|
||||
activePortIndex = portIndex;
|
||||
Debug.Log($"[iFacialMocap] 포트 전환: {availablePorts[portIndex]}");
|
||||
|
||||
if (useSharedPort)
|
||||
{
|
||||
// 마스터 모드: 포트 전환 요청
|
||||
StreamingleFacialUdpMaster.Instance.SwitchPort(oldPort, LOCAL_PORT, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 페이셜 모션 캡처 재접속
|
||||
/// 페이셜 모션 캡처 재접속 (프리징 없는 코루틴 방식)
|
||||
/// </summary>
|
||||
public void Reconnect()
|
||||
{
|
||||
if (reconnectCoroutine != null)
|
||||
{
|
||||
StopCoroutine(reconnectCoroutine);
|
||||
}
|
||||
reconnectCoroutine = StartCoroutine(ReconnectCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator ReconnectCoroutine()
|
||||
{
|
||||
Debug.Log("[iFacialMocap] 재접속 시도 중...");
|
||||
|
||||
try
|
||||
if (useSharedPort)
|
||||
{
|
||||
// 기존 연결 종료
|
||||
// 마스터 모드: 해제 후 재등록
|
||||
StreamingleFacialUdpMaster.Instance.Unregister(LOCAL_PORT, this);
|
||||
yield return null; // 1프레임 대기
|
||||
StreamingleFacialUdpMaster.Instance.Register(LOCAL_PORT, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 독립 모드: UDP 종료 후 코루틴으로 대기 (프리징 없음)
|
||||
StopUDP();
|
||||
|
||||
// 잠시 대기
|
||||
Thread.Sleep(500);
|
||||
// OS가 포트를 해제할 시간을 코루틴으로 대기 (메인 스레드 블로킹 없음)
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
// 플래그 리셋
|
||||
StartFlag = true;
|
||||
|
||||
// 재시작
|
||||
StartFunction();
|
||||
}
|
||||
|
||||
reconnectCoroutine = null;
|
||||
Debug.Log("[iFacialMocap] 재접속 완료");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[iFacialMocap] 재접속 실패: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 프레임레이트 독립적 EMA 계수 계산
|
||||
@ -575,14 +653,21 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BlendShape 값 필터링: filterMode에 따라 EMA 또는 1€ Euro Filter 적용
|
||||
/// BlendShape 값 필터링: filterMode에 따라 적절한 필터 적용
|
||||
/// </summary>
|
||||
float FilterBlendShapeValue(string name, float rawValue)
|
||||
{
|
||||
if (filterMode == FilterMode.OneEuro)
|
||||
switch (filterMode)
|
||||
{
|
||||
case FilterMode.OneEuro:
|
||||
return FilterOneEuro(name, rawValue);
|
||||
|
||||
case FilterMode.MedianOneEuro:
|
||||
return FilterMedianOneEuro(name, rawValue);
|
||||
case FilterMode.EMA:
|
||||
return FilterEMA(name, rawValue);
|
||||
default:
|
||||
return rawValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -610,6 +695,48 @@ public class StreamingleFacialReceiver : MonoBehaviour
|
||||
return Mathf.Clamp(filter.Filter(rawValue, t), 0f, 100f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Median + OneEuro 복합 필터:
|
||||
/// 1단계: Median 필터로 스파이크/이상치 제거
|
||||
/// 2단계: OneEuro 필터로 적응형 스무딩
|
||||
/// → 스파이크에 강하면서도 빠른 움직임에 반응하는 최고 품질 필터링
|
||||
/// </summary>
|
||||
float FilterMedianOneEuro(string name, float rawValue)
|
||||
{
|
||||
// Median 윈도우 크기 변경 감지 → 필터 재생성
|
||||
if (medianWindowSizePrev != medianWindowSize)
|
||||
{
|
||||
medianFilters.Clear();
|
||||
medianWindowSizePrev = medianWindowSize;
|
||||
}
|
||||
|
||||
// 1단계: Median 필터
|
||||
if (!medianFilters.TryGetValue(name, out var medianFilter))
|
||||
{
|
||||
medianFilter = new MedianFilter(medianWindowSize);
|
||||
medianFilters[name] = medianFilter;
|
||||
}
|
||||
float medianValue = medianFilter.Filter(rawValue);
|
||||
|
||||
// 2단계: OneEuro 필터
|
||||
float t = Time.time;
|
||||
if (!medianEuroFilters.TryGetValue(name, out var euroFilter))
|
||||
{
|
||||
euroFilter = new OneEuroFilter(60f, euroMinCutoff, euroBeta, euroDCutoff);
|
||||
medianEuroFilters[name] = euroFilter;
|
||||
euroFilter.Filter(medianValue, t);
|
||||
return medianValue;
|
||||
}
|
||||
|
||||
// 파라미터 변경 감지
|
||||
if (euroMinCutoffPrev != euroMinCutoff || euroBetaPrev != euroBeta || euroDCutoffPrev != euroDCutoff)
|
||||
{
|
||||
SyncEuroParams();
|
||||
}
|
||||
|
||||
return Mathf.Clamp(euroFilter.Filter(medianValue, t), 0f, 100f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EMA 필터: 연속 스파이크 판별 + 카테고리별 임계값 + 프레임독립 EMA (기존 로직)
|
||||
/// </summary>
|
||||
|
||||
249
Assets/External/StreamingleFacial/StreamingleFacialUdpMaster.cs
vendored
Normal file
249
Assets/External/StreamingleFacial/StreamingleFacialUdpMaster.cs
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// 중앙 UDP 수신 매니저. 하나의 포트에서 수신한 데이터를 여러 StreamingleFacialReceiver에 분배.
|
||||
/// 싱글톤으로 동작하며, Receiver가 Register 시 자동 생성됨.
|
||||
///
|
||||
/// 사용법:
|
||||
/// StreamingleFacialReceiver에서 useSharedPort = true로 설정하면
|
||||
/// 자동으로 이 마스터를 통해 UDP 데이터를 공유 수신합니다.
|
||||
/// 같은 포트에 여러 Receiver를 등록하면 동일한 데이터를 모든 Receiver가 받습니다.
|
||||
/// </summary>
|
||||
public class StreamingleFacialUdpMaster : MonoBehaviour
|
||||
{
|
||||
private static StreamingleFacialUdpMaster _instance;
|
||||
public static StreamingleFacialUdpMaster Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
var go = new GameObject("[StreamingleFacialUdpMaster]");
|
||||
go.hideFlags = HideFlags.HideInHierarchy;
|
||||
DontDestroyOnLoad(go);
|
||||
_instance = go.AddComponent<StreamingleFacialUdpMaster>();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private class PortListener
|
||||
{
|
||||
public int port;
|
||||
public UdpClient udp;
|
||||
public Thread thread;
|
||||
public volatile bool isRunning;
|
||||
public volatile string latestMessage = "";
|
||||
public string lastDistributedMessage = "";
|
||||
public readonly HashSet<StreamingleFacialReceiver> receivers = new HashSet<StreamingleFacialReceiver>();
|
||||
public readonly object lockObj = new object();
|
||||
}
|
||||
|
||||
private readonly Dictionary<int, PortListener> listeners = new Dictionary<int, PortListener>();
|
||||
|
||||
/// <summary>
|
||||
/// Receiver를 지정 포트에 등록. 해당 포트의 리스너가 없으면 자동 생성.
|
||||
/// </summary>
|
||||
public void Register(int port, StreamingleFacialReceiver receiver)
|
||||
{
|
||||
if (!listeners.TryGetValue(port, out var listener))
|
||||
{
|
||||
listener = new PortListener { port = port };
|
||||
listeners[port] = listener;
|
||||
StartListener(listener);
|
||||
}
|
||||
|
||||
lock (listener.lockObj)
|
||||
{
|
||||
listener.receivers.Add(receiver);
|
||||
}
|
||||
|
||||
Debug.Log($"[FacialUdpMaster] Port {port} 등록 (총 {listener.receivers.Count}개 Receiver)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Receiver를 지정 포트에서 해제. 해당 포트에 Receiver가 없으면 리스너 종료.
|
||||
/// </summary>
|
||||
public void Unregister(int port, StreamingleFacialReceiver receiver)
|
||||
{
|
||||
if (!listeners.TryGetValue(port, out var listener)) return;
|
||||
|
||||
bool shouldStop = false;
|
||||
lock (listener.lockObj)
|
||||
{
|
||||
listener.receivers.Remove(receiver);
|
||||
shouldStop = listener.receivers.Count == 0;
|
||||
}
|
||||
|
||||
if (shouldStop)
|
||||
{
|
||||
StopListener(listener);
|
||||
listeners.Remove(port);
|
||||
Debug.Log($"[FacialUdpMaster] Port {port} 리스너 종료 (Receiver 없음)");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 포트 변경 시 호출. 기존 포트 해제 → 새 포트 등록.
|
||||
/// </summary>
|
||||
public void SwitchPort(int oldPort, int newPort, StreamingleFacialReceiver receiver)
|
||||
{
|
||||
Unregister(oldPort, receiver);
|
||||
Register(newPort, receiver);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 포트의 리스너를 재시작 (포트 문제 시 복구용)
|
||||
/// </summary>
|
||||
public void RestartPort(int port)
|
||||
{
|
||||
if (!listeners.TryGetValue(port, out var listener)) return;
|
||||
|
||||
StopListener(listener);
|
||||
|
||||
// 리스너 상태 리셋 후 재시작
|
||||
listener.latestMessage = "";
|
||||
listener.lastDistributedMessage = "";
|
||||
StartListener(listener);
|
||||
|
||||
Debug.Log($"[FacialUdpMaster] Port {port} 리스너 재시작");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 등록된 포트와 각 포트의 Receiver 수를 반환 (디버그용)
|
||||
/// </summary>
|
||||
public Dictionary<int, int> GetPortStatus()
|
||||
{
|
||||
var status = new Dictionary<int, int>();
|
||||
foreach (var kvp in listeners)
|
||||
{
|
||||
status[kvp.Key] = kvp.Value.receivers.Count;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private void StartListener(PortListener listener)
|
||||
{
|
||||
try
|
||||
{
|
||||
listener.udp = new UdpClient(listener.port);
|
||||
listener.udp.Client.ReceiveTimeout = 5;
|
||||
listener.isRunning = true;
|
||||
listener.thread = new Thread(() => ListenThread(listener))
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
listener.thread.Start();
|
||||
Debug.Log($"[FacialUdpMaster] Port {listener.port} 수신 시작");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[FacialUdpMaster] Port {listener.port} 시작 실패: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void StopListener(PortListener listener)
|
||||
{
|
||||
listener.isRunning = false;
|
||||
|
||||
try
|
||||
{
|
||||
if (listener.udp != null)
|
||||
{
|
||||
listener.udp.Close();
|
||||
listener.udp.Dispose();
|
||||
listener.udp = null;
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
if (listener.thread != null && listener.thread.IsAlive)
|
||||
{
|
||||
listener.thread.Join(300);
|
||||
listener.thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ListenThread(PortListener listener)
|
||||
{
|
||||
while (listener.isRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
IPEndPoint remoteEP = null;
|
||||
byte[] data = listener.udp.Receive(ref remoteEP);
|
||||
if (data != null && data.Length > 0)
|
||||
{
|
||||
listener.latestMessage = Encoding.ASCII.GetString(data);
|
||||
}
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (!listener.isRunning) break;
|
||||
if (e.SocketErrorCode != SocketError.TimedOut)
|
||||
{
|
||||
Debug.LogError($"[FacialUdpMaster] Port {listener.port} 수신 오류: {e.Message}");
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!listener.isRunning) break;
|
||||
Debug.LogError($"[FacialUdpMaster] Port {listener.port} 오류: {e.Message}");
|
||||
}
|
||||
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
foreach (var kvp in listeners)
|
||||
{
|
||||
var listener = kvp.Value;
|
||||
string msg = listener.latestMessage;
|
||||
|
||||
if (string.IsNullOrEmpty(msg) || msg == listener.lastDistributedMessage)
|
||||
continue;
|
||||
|
||||
listener.lastDistributedMessage = msg;
|
||||
|
||||
lock (listener.lockObj)
|
||||
{
|
||||
foreach (var receiver in listener.receivers)
|
||||
{
|
||||
if (receiver != null && receiver.isActiveAndEnabled)
|
||||
{
|
||||
receiver.SetMessageFromMaster(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
foreach (var kvp in listeners)
|
||||
{
|
||||
StopListener(kvp.Value);
|
||||
}
|
||||
listeners.Clear();
|
||||
|
||||
if (_instance == this)
|
||||
_instance = null;
|
||||
}
|
||||
|
||||
void OnApplicationQuit()
|
||||
{
|
||||
OnDestroy();
|
||||
}
|
||||
}
|
||||
2
Assets/External/StreamingleFacial/StreamingleFacialUdpMaster.cs.meta
vendored
Normal file
2
Assets/External/StreamingleFacial/StreamingleFacialUdpMaster.cs.meta
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f84ad022978ca14bb7fa383b1e86b3d
|
||||
8
Assets/Resources/BossRaidWeb.meta
Normal file
8
Assets/Resources/BossRaidWeb.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 027db6e30adb2054687426649457fbbc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Resources/BossRaidWeb/bossraid_script.txt
(Stored with Git LFS)
Normal file
BIN
Assets/Resources/BossRaidWeb/bossraid_script.txt
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/Resources/BossRaidWeb/bossraid_script.txt.meta
Normal file
7
Assets/Resources/BossRaidWeb/bossraid_script.txt.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a468efa52276a384db63282e727b704b
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Resources/BossRaidWeb/bossraid_style.txt
(Stored with Git LFS)
Normal file
BIN
Assets/Resources/BossRaidWeb/bossraid_style.txt
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/Resources/BossRaidWeb/bossraid_style.txt.meta
Normal file
7
Assets/Resources/BossRaidWeb/bossraid_style.txt.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af43c7dd8dc851f4eaa92ccd2dfa3fa3
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Resources/BossRaidWeb/bossraid_template.txt
(Stored with Git LFS)
Normal file
BIN
Assets/Resources/BossRaidWeb/bossraid_template.txt
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/Resources/BossRaidWeb/bossraid_template.txt.meta
Normal file
7
Assets/Resources/BossRaidWeb/bossraid_template.txt.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f88baa51ad375d946a06b4217d25ddec
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ResourcesData/Etc/Particle/Confetti.meta
Normal file
8
Assets/ResourcesData/Etc/Particle/Confetti.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98485dcc15d43456ba5d755247e30747
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/ResourcesData/Etc/Particle/Confetti/8colors.png
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/Confetti/8colors.png
(Stored with Git LFS)
Normal file
Binary file not shown.
90
Assets/ResourcesData/Etc/Particle/Confetti/8colors.png.meta
Normal file
90
Assets/ResourcesData/Etc/Particle/Confetti/8colors.png.meta
Normal file
@ -0,0 +1,90 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f7f159d7b449401197b9532fd225c70
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
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: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
273
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.cs
Normal file
273
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.cs
Normal file
@ -0,0 +1,273 @@
|
||||
using UnityEngine;
|
||||
using Kayac;
|
||||
|
||||
public class Confetti : MonoBehaviour
|
||||
{
|
||||
[SerializeField] SkinnedInstancingRenderer instanceRenderer;
|
||||
[SerializeField] int pieceCount = 500;
|
||||
[SerializeField] float emitPiecePerSecond = 30f;
|
||||
[SerializeField] bool emissionLooped = true;
|
||||
[SerializeField] float positionRandomizeRadius;
|
||||
[SerializeField] float velocityRandomizeRadius;
|
||||
[SerializeField] float pieceWidth = 1f;
|
||||
[SerializeField] float pieceLength = 1f;
|
||||
[SerializeField] float normalBendRatio = 0.5f;
|
||||
[SerializeField] float resistance = 5f;
|
||||
[SerializeField] Vector3 gravity = new Vector3(0f, -9.81f, 0f);
|
||||
[SerializeField] Vector3 wind = Vector3.zero;
|
||||
[SerializeField] bool autoStart;
|
||||
|
||||
public int PieceCount { get { return pieceCount; } }
|
||||
|
||||
public float PositionRandomizeRadius
|
||||
{
|
||||
get
|
||||
{
|
||||
return positionRandomizeRadius;
|
||||
}
|
||||
set
|
||||
{
|
||||
positionRandomizeRadius = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float VelocityRandomizeRadius
|
||||
{
|
||||
get
|
||||
{
|
||||
return velocityRandomizeRadius;
|
||||
}
|
||||
set
|
||||
{
|
||||
velocityRandomizeRadius = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float PieceWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return pieceWidth;
|
||||
}
|
||||
set
|
||||
{
|
||||
pieceWidth = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float PieceLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return pieceLength;
|
||||
}
|
||||
set
|
||||
{
|
||||
pieceLength = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float NormalBendRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
return normalBendRatio;
|
||||
}
|
||||
set
|
||||
{
|
||||
normalBendRatio = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Resistance
|
||||
{
|
||||
get
|
||||
{
|
||||
return resistance;
|
||||
}
|
||||
set
|
||||
{
|
||||
resistance = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Gravity
|
||||
{
|
||||
get
|
||||
{
|
||||
return gravity;
|
||||
}
|
||||
set
|
||||
{
|
||||
gravity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Wind
|
||||
{
|
||||
get
|
||||
{
|
||||
return wind;
|
||||
}
|
||||
set
|
||||
{
|
||||
wind = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool EmissionLooped
|
||||
{
|
||||
get
|
||||
{
|
||||
return emissionLooped;
|
||||
}
|
||||
set
|
||||
{
|
||||
emissionLooped = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float EmitPiecePerSecond
|
||||
{
|
||||
get
|
||||
{
|
||||
return emitPiecePerSecond;
|
||||
}
|
||||
set
|
||||
{
|
||||
emitPiecePerSecond = value;
|
||||
}
|
||||
}
|
||||
|
||||
Mesh originalMesh;
|
||||
ConfettiPiece[] pieces;
|
||||
int emitIndex;
|
||||
float emitCarry; // 端数持ち越し
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (autoStart)
|
||||
{
|
||||
ManualStart();
|
||||
}
|
||||
}
|
||||
|
||||
public void ManualStart(int pieceCountOverride = 0)
|
||||
{
|
||||
if (pieceCountOverride > 0)
|
||||
{
|
||||
pieceCount = pieceCountOverride;
|
||||
}
|
||||
originalMesh = new Mesh()
|
||||
{
|
||||
name = "original"
|
||||
};
|
||||
MeshGenerator.GenerateQuad(
|
||||
originalMesh,
|
||||
Vector3.zero,
|
||||
new Vector3(1f, 0f, 0f),
|
||||
new Vector3(0f, 0f, 1f),
|
||||
Vector2.zero,
|
||||
Vector2.zero,
|
||||
doubleSided: true);
|
||||
var uvOffsets = new Vector2[pieceCount];
|
||||
for (int i = 0; i < pieceCount; i++)
|
||||
{
|
||||
uvOffsets[i] = new Vector2(Random.Range(0.125f, 1f), 0f);
|
||||
}
|
||||
instanceRenderer.ManualStart(originalMesh, uvOffsets.Length, uvOffsets);
|
||||
// 実際にこの数で作れたとは限らないので確認して上書きする
|
||||
pieceCount = instanceRenderer.Count;
|
||||
pieces = new ConfettiPiece[pieceCount];
|
||||
}
|
||||
|
||||
public void StartEmission()
|
||||
{
|
||||
if (originalMesh == null)
|
||||
{
|
||||
ManualStart();
|
||||
}
|
||||
emitCarry = 0f;
|
||||
for (int i = 0; i < pieces.Length; i++)
|
||||
{
|
||||
pieces[i].Init(
|
||||
Vector3.zero,
|
||||
Vector3.zero,
|
||||
0f,
|
||||
Quaternion.identity,
|
||||
0f,
|
||||
0f);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitPiece(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var q = Quaternion.identity;
|
||||
var qz = Quaternion.AngleAxis(Random.Range(-10f, 10f), new Vector3(0f, 0f, 1f));
|
||||
var qy = Quaternion.AngleAxis(Random.Range(-180f, 180f), new Vector3(0f, 1f, 0f));
|
||||
var qx = Quaternion.AngleAxis(Random.Range(-180f, 180f), new Vector3(1f, 0f, 0f));
|
||||
q *= qz;
|
||||
q *= qy;
|
||||
q *= qx;
|
||||
var position = new Vector3(
|
||||
Random.Range(-positionRandomizeRadius, positionRandomizeRadius),
|
||||
Random.Range(-positionRandomizeRadius, positionRandomizeRadius),
|
||||
Random.Range(-positionRandomizeRadius, positionRandomizeRadius));
|
||||
var velocity = new Vector3(
|
||||
Random.Range(-velocityRandomizeRadius, velocityRandomizeRadius),
|
||||
Random.Range(velocityRandomizeRadius, velocityRandomizeRadius),
|
||||
Random.Range(-velocityRandomizeRadius, velocityRandomizeRadius));
|
||||
var randomizedNormalBendRatio = Random.Range(normalBendRatio * 0.5f, normalBendRatio);
|
||||
pieces[emitIndex].Init(
|
||||
position,
|
||||
velocity,
|
||||
Time.deltaTime,
|
||||
q,
|
||||
pieceLength * 0.5f,
|
||||
randomizedNormalBendRatio);
|
||||
emitIndex++;
|
||||
if (emitIndex >= pieces.Length)
|
||||
{
|
||||
emitIndex = 0;
|
||||
if (!emissionLooped)
|
||||
{
|
||||
emitPiecePerSecond = 0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (pieces == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float dt = Time.deltaTime;
|
||||
if (emitPiecePerSecond > 0f)
|
||||
{
|
||||
var countF = (emitPiecePerSecond * dt) + emitCarry;
|
||||
var countI = (int)countF;
|
||||
EmitPiece(countI);
|
||||
emitCarry = countF - (float)countI;
|
||||
}
|
||||
|
||||
float halfZSize = pieceLength * 0.5f;
|
||||
for (int i = 0; i < pieces.Length; i++)
|
||||
{
|
||||
pieces[i].Update(dt, ref wind, ref gravity, resistance, halfZSize);
|
||||
}
|
||||
|
||||
// 行列反映
|
||||
var poses = instanceRenderer.BeginUpdatePoses();
|
||||
for (int i = 0; i < pieces.Length; i++)
|
||||
{
|
||||
pieces[i].GetTransform(ref poses[i], pieceLength, pieceWidth);
|
||||
}
|
||||
instanceRenderer.EndUpdatePoses();
|
||||
}
|
||||
}
|
||||
11
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.cs.meta
Normal file
11
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8afa2659287b4ab4a056bece52bb6ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
77
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.mat
Normal file
77
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.mat
Normal file
@ -0,0 +1,77 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Confetti
|
||||
m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 2800000, guid: 4f447d9f9c5234f49b436e395e10e9a0, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 4f7f159d7b449401197b9532fd225c70, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d48b83c48ac2c48339a66b0dbdc5aeeb
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/Confetti/Confetti.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 514c7e149f71f456988bc9816d5ef692
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
99
Assets/ResourcesData/Etc/Particle/Confetti/ConfettiPiece.cs
Normal file
99
Assets/ResourcesData/Etc/Particle/Confetti/ConfettiPiece.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using UnityEngine;
|
||||
struct ConfettiPiece
|
||||
{
|
||||
public void Init(
|
||||
Vector3 position,
|
||||
Vector3 velocity,
|
||||
float deltaTime,
|
||||
Quaternion orientation, //Z軸方向に
|
||||
float halfZSize,
|
||||
float normalBendRatio)
|
||||
{
|
||||
this.normalBendRatio = normalBendRatio;
|
||||
this.orientation = orientation;
|
||||
this.position = position;
|
||||
var forward = orientation * new Vector3(0f, 0f, 1f);
|
||||
var t = forward * halfZSize;
|
||||
var dp = velocity * deltaTime;
|
||||
prevPosition0 = position - t;
|
||||
prevPosition1 = position + t;
|
||||
prevPosition0 -= dp;
|
||||
prevPosition1 -= dp;
|
||||
}
|
||||
|
||||
public void Update(
|
||||
float deltaTime,
|
||||
ref Vector3 wind,
|
||||
ref Vector3 gravity,
|
||||
float resistance,
|
||||
float halfZSize)
|
||||
{
|
||||
var forward = orientation * new Vector3(0f, 0f, 1f);
|
||||
var t = forward * halfZSize;
|
||||
var p0 = position - t;
|
||||
var p1 = position + t;
|
||||
// 相対的な風ベクトルを出す
|
||||
var v0 = (p0 - prevPosition0) / deltaTime;
|
||||
var v1 = (p1 - prevPosition1) / deltaTime;
|
||||
var relativeWind0 = wind - v0;
|
||||
var relativeWind1 = wind - v1;
|
||||
// 頂点ごとの法線を生成
|
||||
var n = orientation * new Vector3(0f, 1f, 0f);
|
||||
// 曲げる
|
||||
t = forward * normalBendRatio;
|
||||
var n0 = n + t;
|
||||
var n1 = n - t;
|
||||
// 正規化。n1はn0と同じ長さなので長さを計算して使い回す
|
||||
n0.Normalize();
|
||||
n1.Normalize();
|
||||
// 風ベクトルの法線方向成分を、加速度とする
|
||||
var dot0 = Vector3.Dot(n0, relativeWind0);
|
||||
var dot1 = Vector3.Dot(n1, relativeWind1);
|
||||
if (dot0 < 0)
|
||||
{
|
||||
n0 = -n0;
|
||||
dot0 = -dot0;
|
||||
}
|
||||
if (dot1 < 0)
|
||||
{
|
||||
n1 = -n1;
|
||||
dot1 = -dot1;
|
||||
}
|
||||
var accel0 = n0 * (dot0 * resistance);
|
||||
var accel1 = n1 * (dot1 * resistance);
|
||||
// 重力を追加
|
||||
accel0 += gravity;
|
||||
accel1 += gravity;
|
||||
// 独立に積分
|
||||
var dt2 = deltaTime * deltaTime;
|
||||
var dp0 = p0 - prevPosition0 + (accel0 * dt2);
|
||||
var dp1 = p1 - prevPosition1 + (accel1 * dt2);
|
||||
var nextP0 = p0 + dp0;
|
||||
var nextP1 = p1 + dp1;
|
||||
prevPosition0 = p0;
|
||||
prevPosition1 = p1;
|
||||
p0 = nextP0;
|
||||
p1 = nextP1;
|
||||
// 拘束
|
||||
var newForward = (p1 - p0).normalized;
|
||||
position = (p0 + p1) * 0.5f;
|
||||
// 姿勢更新
|
||||
// forward -> newForwardに向くような、回転軸右ベクタの回転を作用させる
|
||||
var dq = Quaternion.FromToRotation(forward, newForward);
|
||||
orientation = dq * orientation; // dqは時間的に後の回転だから、ベクタから遠い方、つまり前から乗算
|
||||
orientation.Normalize();
|
||||
}
|
||||
|
||||
public void GetTransform(
|
||||
ref Matrix4x4 matrix,
|
||||
float ZSize,
|
||||
float XSize)
|
||||
{
|
||||
matrix.SetTRS(position, orientation, new Vector3(XSize, 1f, ZSize));
|
||||
}
|
||||
public Vector3 position;
|
||||
Vector3 prevPosition0;
|
||||
Vector3 prevPosition1;
|
||||
Quaternion orientation;
|
||||
float normalBendRatio;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfb6fb60322ae4e7e855e73b08d27331
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
2
Assets/ResourcesData/Etc/Particle/JMO Assets.meta
Normal file
2
Assets/ResourcesData/Etc/Particle/JMO Assets.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 976974e4d3018034e87caeb9f51f20f6
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c865e48369a325f4784ecd8444d1ec51
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f348a2fb2f8a7fe4e82fb08818415884
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 715add6d7a2eff443bf0aee3cf26e7fc
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Electric/CFX_ElectricityBall.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Electric/CFX_ElectricityBall.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77ec3c4e07a36814fb3169ecef41b50a
|
||||
labels:
|
||||
- ball
|
||||
- bubble
|
||||
- cartoonfx
|
||||
- electric
|
||||
- particles
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Electric/CFX_ElectricityBall.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c41f95c98750b744bb429ee2fc6a1d70
|
||||
labels:
|
||||
- cartoonfx
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Explosions/CFX_Explosion_B_Smoke+Text.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Explosions/CFX_Explosion_B_Smoke+Text.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46876a2780737ec45a19d62f88e5ce56
|
||||
timeCreated: 1505140479
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Explosions/CFX_Explosion_B_Smoke+Text.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Explosions/CFX_Firework_Trails_Gravity.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Explosions/CFX_Firework_Trails_Gravity.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4adffb0018aeda44e9263f901167af1f
|
||||
timeCreated: 1505138997
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Explosions/CFX_Firework_Trails_Gravity.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45653d11d228e594498b3d9119285e35
|
||||
labels:
|
||||
- cartoonfx
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Hits/CFX_Hit_A Red+RandomText.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Hits/CFX_Hit_A Red+RandomText.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f95ff734540a0d749be6571b6cb5b37f
|
||||
labels:
|
||||
- cartoonfx
|
||||
- hit
|
||||
- particles
|
||||
- text
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Hits/CFX_Hit_A Red+RandomText.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Hits/CFX_Hit_C White.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Hits/CFX_Hit_C White.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f06e78284f831ae469c74624ab5d513b
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- hit
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Hits/CFX_Hit_C White.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f991151302bbc8440bc158a1be7d008d
|
||||
labels:
|
||||
- cartoonfx
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_MagicPoof.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_MagicPoof.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a40b64bf23366dc42a892af2c6ff6140
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- poof
|
||||
- smoke
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_MagicPoof.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Magical_Source.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Magical_Source.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e4577abe56a95f4a91d29a0473cd30c
|
||||
timeCreated: 1505142609
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Magical_Source.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Poof.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Poof.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3156817f64ec68948ad6bb26569b9ef5
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- poof
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Poof.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Tornado.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Tornado.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 352304b7fbe11f445970df6ae36e6227
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- tornado
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Tornado.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Virus.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Virus.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a474af3f4c27be4e9bdce39cfe4315d
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- virus
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX Prefabs/Misc/CFX_Virus.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84d86077ce20b3d408f08f7cc5cfb4ea
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ef0e39c32aae7b4480fbdb6d2efb0a1
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Blood/CFX2_Blood.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Blood/CFX2_Blood.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc98890f6028f444eaa7789bde5e2eeb
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- blood
|
||||
- directional
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Blood/CFX2_Blood.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e71da46ca428824c9e9e4598154d6d3
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Debris Hits/CFX2_RockHit.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Debris Hits/CFX2_RockHit.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a97415c6b57076f41a6621a7b51d63a3
|
||||
timeCreated: 1506674220
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Debris Hits/CFX2_RockHit.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c21f3643835b3b34e897f4b378531f37
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Electric/CFX2_SparksHit_B Sphere.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Electric/CFX2_SparksHit_B Sphere.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4961a16ba01e09547be3e1c9d16d5ad0
|
||||
timeCreated: 1506673851
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Electric/CFX2_SparksHit_B
|
||||
Sphere.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efc53651f7e42d84d86caee3be88073e
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Explosions/CFX2_WWExplosion_C.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Explosions/CFX2_WWExplosion_C.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa8d6482d70a23445b4b2a928ed1b845
|
||||
timeCreated: 1506670975
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Explosions/CFX2_WWExplosion_C.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86fef6e72f4589f428dccc24bd05cf0b
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_BatsCloud.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_BatsCloud.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4f5579fb5da2f646a0c2bee91bdf6b5
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- symbol
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_BatsCloud.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_BrokenHeart.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_BrokenHeart.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcaff8fc36e95584bb27cc3cf7c6cb14
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- toon
|
||||
- symbol
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_BrokenHeart.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_Wandering_Spirits.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_Wandering_Spirits.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daa6cceb1b087d74aad6916dac2805ea
|
||||
timeCreated: 1505487254
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Misc/CFX2_Wandering_Spirits.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fdee0cda8f0d2094fa5ca47abb4ffd95
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupDiamond2.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupDiamond2.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa3fed151f536ee49b583c6a3ac4a2e1
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- pickup
|
||||
- symbol
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupDiamond2.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupHeart.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupHeart.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3af6f68141914ca43ba39b2403757bd0
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- pickup
|
||||
- symbol
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupHeart.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupSmiley2.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupSmiley2.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1bc4a709f24528b40984e62f32e398a0
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- pickup
|
||||
- symbol
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupSmiley2.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupStar.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupStar.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fc06027b01064e4f885fd8dd2929310
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- pickup
|
||||
- symbol
|
||||
- toon
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Pickup Items/CFX2_PickupStar.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8472d517d4584f41ac28b96b812564f
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Skull & Ghosts Effects/CFX2_EnemyDeathSkull.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Skull & Ghosts Effects/CFX2_EnemyDeathSkull.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7867af58a6ec48846ae807eb4022fbaa
|
||||
labels:
|
||||
- cartoonfx
|
||||
- particles
|
||||
- smoke
|
||||
- toon
|
||||
- symbol
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Skull & Ghosts Effects/CFX2_EnemyDeathSkull.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fda99d3a72bd62d44b37eef4da0ac074
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Water/CFX2_Big_Splash (No Collision).prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Water/CFX2_Big_Splash (No Collision).prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77c69ec12208c4c4380d15e30b6f8f68
|
||||
timeCreated: 1507212856
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX2 Prefabs/Water/CFX2_Big_Splash
|
||||
(No Collision).prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9358d72e9ab0589469b7c81a782cb400
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d8820046d052af4583d35be43c7a959
|
||||
DefaultImporter:
|
||||
userData:
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Electric/CFX3_Hit_Electric_A_Ground.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Electric/CFX3_Hit_Electric_A_Ground.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ca16f2a31fb6a548ad8954bed1d321f
|
||||
labels:
|
||||
- CartoonFX
|
||||
- Toon
|
||||
- Particles
|
||||
- Hit
|
||||
- Electric
|
||||
- Ground
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Electric/CFX3_Hit_Electric_A_Ground.prefab
|
||||
uploadId: 545941
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Electric/CFX3_Hit_Electric_C_Air.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Electric/CFX3_Hit_Electric_C_Air.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e243632bb3aff9549abdcfcc2ef0c4f0
|
||||
timeCreated: 1504710934
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Electric/CFX3_Hit_Electric_C_Air.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d15fe19a363a70749ba9f690ab060547
|
||||
DefaultImporter:
|
||||
userData:
|
||||
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Environment/CFX3_Snow_Dense.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Particle/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Environment/CFX3_Snow_Dense.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de07bf378e7247444a0715ad2ff509e3
|
||||
labels:
|
||||
- CartoonFX
|
||||
- Toon
|
||||
- Particles
|
||||
- Snow
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 109565
|
||||
packageName: Cartoon FX Remaster Free
|
||||
packageVersion: R 1.0.2
|
||||
assetPath: Assets/JMO Assets/Cartoon FX (legacy)/CFX3 Prefabs/Environment/CFX3_Snow_Dense.prefab
|
||||
uploadId: 545941
|
||||
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d25cb644a933ed4bad4bc0b015fa1f6
|
||||
DefaultImporter:
|
||||
userData:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user