2026.06.25 Fishing scene
This commit is contained in:
8
Assets/My project/Fishing Scripts/Prefabs.meta
Normal file
8
Assets/My project/Fishing Scripts/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e1f71c106e40544a96417f581abeec7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/My project/Fishing Scripts/Prefabs/14.glb
Normal file
BIN
Assets/My project/Fishing Scripts/Prefabs/14.glb
Normal file
Binary file not shown.
28
Assets/My project/Fishing Scripts/Prefabs/14.glb.meta
Normal file
28
Assets/My project/Fishing Scripts/Prefabs/14.glb.meta
Normal file
@@ -0,0 +1,28 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b205275e9229b8b40bcfb446b9fa4cb4
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
|
||||
editorImportSettings:
|
||||
generateSecondaryUVSet: 0
|
||||
importSettings:
|
||||
nodeNameMethod: 1
|
||||
animationMethod: 2
|
||||
generateMipMaps: 1
|
||||
texturesReadable: 0
|
||||
defaultMinFilterMode: 9729
|
||||
defaultMagFilterMode: 9729
|
||||
anisotropicFilterLevel: 1
|
||||
instantiationSettings:
|
||||
mask: -1
|
||||
layer: 0
|
||||
skinUpdateWhenOffscreen: 1
|
||||
lightIntensityFactor: 1
|
||||
sceneObjectCreation: 2
|
||||
assetDependencies: []
|
||||
reportItems: []
|
||||
BIN
Assets/My project/Fishing Scripts/Prefabs/FishingSystemPrefab.prefab
LFS
Normal file
BIN
Assets/My project/Fishing Scripts/Prefabs/FishingSystemPrefab.prefab
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9d8394fffa0b5b4e81c71ad0000f45a
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
@@ -11,12 +12,29 @@ public enum ResultType
|
||||
Miss
|
||||
}
|
||||
|
||||
[Header("Auto Bind")]
|
||||
[Tooltip("현재 만든 Prefab 구조 기준으로 비어 있는 참조를 자동 연결합니다.")]
|
||||
[SerializeField] private bool autoBindMissingReferences = true;
|
||||
|
||||
[Header("References")]
|
||||
[Tooltip("낚시 UI 전체 루트입니다. UI를 자동으로 켜고 끄고 싶을 때만 연결하세요.")]
|
||||
[SerializeField] private GameObject uiRoot;
|
||||
|
||||
[SerializeField] private FishingGaugeUI ui;
|
||||
[SerializeField] private FishingRewardSystem rewardSystem;
|
||||
[SerializeField] private FishingHapticManager haptic;
|
||||
[SerializeField] private RotateUI centerIconRotate;
|
||||
|
||||
[Header("XR Controller Input")]
|
||||
[Tooltip("낚시 판정을 실행할 컨트롤러 입력입니다. 예: XRI Right Interaction / Select")]
|
||||
[SerializeField] private InputActionReference submitAction;
|
||||
|
||||
[Tooltip("낚시를 다시 시작할 컨트롤러 입력입니다. 필요 없으면 비워둬도 됩니다.")]
|
||||
[SerializeField] private InputActionReference resetAction;
|
||||
|
||||
[Tooltip("씬에 Input Action Manager가 없거나 액션이 자동 활성화되지 않으면 켜두세요.")]
|
||||
[SerializeField] private bool enableInputActionsManually = true;
|
||||
|
||||
[Header("Pointer")]
|
||||
[SerializeField] private float pointerAngle;
|
||||
[SerializeField] private float pointerSpeed = 180f;
|
||||
@@ -30,29 +48,97 @@ public enum ResultType
|
||||
[SerializeField] private float maxZoneSize = 120f;
|
||||
[SerializeField] private float zoneCenter;
|
||||
|
||||
[Header("Rules")]
|
||||
[Header("Catch Rules")]
|
||||
[Tooltip("아이템 1개를 낚기 위해 필요한 성공 횟수입니다.")]
|
||||
[SerializeField] private int requiredSuccesses = 3;
|
||||
|
||||
[Tooltip("아이템 1개를 낚는 동안 허용되는 실패 횟수입니다. 초과하면 낚싯줄이 끊어진 것으로 처리합니다.")]
|
||||
[SerializeField] private int allowedFails = 3;
|
||||
|
||||
[Header("Pond Cleanup Rules")]
|
||||
[Tooltip("연못을 맑게 만들기 위해 필요한 쓰레기성 아이템 수입니다. 쓰레기, 병, 봉지가 여기에 포함됩니다.")]
|
||||
[SerializeField] private int requiredCleanupItems = 3;
|
||||
|
||||
[Tooltip("연못이 맑아진 뒤 다음 성공 낚시에서 기억의 조각을 확정으로 낚습니다.")]
|
||||
[SerializeField] private bool guaranteeMemoryPieceAfterCleaned = true;
|
||||
|
||||
[Tooltip("StartFishing을 호출할 때 쓰레기 수거/연못 상태를 초기화합니다.")]
|
||||
[SerializeField] private bool resetPondStateOnStart = true;
|
||||
|
||||
[Header("Round Settings")]
|
||||
[SerializeField] private float nextRoundDelay = 0.35f;
|
||||
[SerializeField] private float nextCatchDelay = 2.0f;
|
||||
[SerializeField] private bool randomDirectionEachRound = true;
|
||||
[SerializeField] private bool resetDifficultyEachCatch = true;
|
||||
[SerializeField] private bool startOnAwake = true;
|
||||
|
||||
[Header("Final Result Settings")]
|
||||
[Tooltip("최종 결과를 잠깐 보여준 뒤 uiRoot를 자동으로 끕니다. uiRoot가 비어 있으면 동작하지 않습니다.")]
|
||||
[SerializeField] private bool hideUIRootAfterFinalResult = false;
|
||||
|
||||
[SerializeField] private float finalResultShowTime = 1.5f;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
private int successCount;
|
||||
private int failCount;
|
||||
private int cleanupItemCount;
|
||||
private int totalCaughtItems;
|
||||
|
||||
// 임시 낚시 세션 카운트입니다. 나중에 공용 인벤토리와 연결할 때는 저장용으로 쓰지 말고 UI 표시용으로만 쓰세요.
|
||||
private int sessionFishCount;
|
||||
private int sessionTrashCount;
|
||||
private int sessionMemoryPieceCount;
|
||||
private int sessionCompassCount;
|
||||
|
||||
private bool clockwise = true;
|
||||
private bool activeGame;
|
||||
private bool inputLocked;
|
||||
private bool pondCleaned;
|
||||
private bool memoryPieceCollected;
|
||||
|
||||
private bool submitActionWasEnabled;
|
||||
private bool resetActionWasEnabled;
|
||||
|
||||
private Coroutine nextRoundRoutine;
|
||||
private Coroutine nextCatchRoutine;
|
||||
private Coroutine finalResultRoutine;
|
||||
|
||||
public bool IsActiveGame => activeGame;
|
||||
public bool IsPondCleaned => pondCleaned;
|
||||
public bool IsMemoryPieceCollected => memoryPieceCollected;
|
||||
public int SuccessCount => successCount;
|
||||
public int FailCount => failCount;
|
||||
public int CleanupItemCount => cleanupItemCount;
|
||||
public int RequiredCleanupItems => requiredCleanupItems;
|
||||
public int TotalCaughtItems => totalCaughtItems;
|
||||
public int SessionFishCount => sessionFishCount;
|
||||
public int SessionTrashCount => sessionTrashCount;
|
||||
public int SessionMemoryPieceCount => sessionMemoryPieceCount;
|
||||
public int SessionCompassCount => sessionCompassCount;
|
||||
|
||||
public event Action<FishingItemType, int> ItemCaught;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
RegisterInputAction(submitAction, OnSubmitAction, ref submitActionWasEnabled);
|
||||
RegisterInputAction(resetAction, OnResetAction, ref resetActionWasEnabled);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
UnregisterInputAction(submitAction, OnSubmitAction, submitActionWasEnabled);
|
||||
UnregisterInputAction(resetAction, OnResetAction, resetActionWasEnabled);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (autoBindMissingReferences)
|
||||
AutoBindMissingReferences();
|
||||
|
||||
ValidateRuntimeSettings();
|
||||
|
||||
if (startOnAwake)
|
||||
{
|
||||
StartFishing();
|
||||
@@ -74,13 +160,137 @@ private void Update()
|
||||
RotatePointer();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
ValidateRuntimeSettings();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[ContextMenu("Auto Bind Fishing References")]
|
||||
public void AutoBindMissingReferences()
|
||||
{
|
||||
Transform searchRoot = GetSearchRoot();
|
||||
|
||||
if (uiRoot == null)
|
||||
{
|
||||
Transform canvasTransform = FindTransformRecursive(searchRoot, "FishingCanvas");
|
||||
if (canvasTransform != null)
|
||||
uiRoot = canvasTransform.gameObject;
|
||||
}
|
||||
|
||||
if (ui == null)
|
||||
ui = searchRoot != null ? searchRoot.GetComponentInChildren<FishingGaugeUI>(true) : GetComponentInChildren<FishingGaugeUI>(true);
|
||||
|
||||
if (rewardSystem == null)
|
||||
rewardSystem = searchRoot != null ? searchRoot.GetComponentInChildren<FishingRewardSystem>(true) : GetComponentInChildren<FishingRewardSystem>(true);
|
||||
|
||||
if (haptic == null)
|
||||
haptic = searchRoot != null ? searchRoot.GetComponentInChildren<FishingHapticManager>(true) : GetComponentInChildren<FishingHapticManager>(true);
|
||||
|
||||
if (centerIconRotate == null)
|
||||
{
|
||||
Transform centerIconTransform = FindTransformRecursive(searchRoot, "CenterIcon");
|
||||
if (centerIconTransform != null)
|
||||
centerIconRotate = centerIconTransform.GetComponent<RotateUI>();
|
||||
|
||||
if (centerIconRotate == null && searchRoot != null)
|
||||
centerIconRotate = searchRoot.GetComponentInChildren<RotateUI>(true);
|
||||
}
|
||||
}
|
||||
|
||||
private Transform GetSearchRoot()
|
||||
{
|
||||
Transform current = transform;
|
||||
|
||||
while (current.parent != null)
|
||||
current = current.parent;
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
private Transform FindTransformRecursive(Transform current, string targetName)
|
||||
{
|
||||
if (current == null || string.IsNullOrEmpty(targetName))
|
||||
return null;
|
||||
|
||||
if (NormalizeName(current.name) == NormalizeName(targetName))
|
||||
return current;
|
||||
|
||||
for (int i = 0; i < current.childCount; i++)
|
||||
{
|
||||
Transform found = FindTransformRecursive(current.GetChild(i), targetName);
|
||||
if (found != null)
|
||||
return found;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string NormalizeName(string value)
|
||||
{
|
||||
return value.Replace(" ", string.Empty)
|
||||
.Replace("_", string.Empty)
|
||||
.Replace("-", string.Empty)
|
||||
.ToLowerInvariant();
|
||||
}
|
||||
|
||||
private void RegisterInputAction(InputActionReference actionReference, System.Action<InputAction.CallbackContext> callback, ref bool wasEnabled)
|
||||
{
|
||||
if (actionReference == null || actionReference.action == null)
|
||||
return;
|
||||
|
||||
wasEnabled = actionReference.action.enabled;
|
||||
actionReference.action.performed += callback;
|
||||
|
||||
if (enableInputActionsManually && !wasEnabled)
|
||||
actionReference.action.Enable();
|
||||
}
|
||||
|
||||
private void UnregisterInputAction(InputActionReference actionReference, System.Action<InputAction.CallbackContext> callback, bool wasEnabled)
|
||||
{
|
||||
if (actionReference == null || actionReference.action == null)
|
||||
return;
|
||||
|
||||
actionReference.action.performed -= callback;
|
||||
|
||||
if (enableInputActionsManually && !wasEnabled)
|
||||
actionReference.action.Disable();
|
||||
}
|
||||
|
||||
private void ValidateRuntimeSettings()
|
||||
{
|
||||
requiredSuccesses = Mathf.Max(1, requiredSuccesses);
|
||||
allowedFails = Mathf.Max(1, allowedFails);
|
||||
requiredCleanupItems = Mathf.Max(1, requiredCleanupItems);
|
||||
|
||||
minSpeed = Mathf.Max(1f, minSpeed);
|
||||
maxSpeed = Mathf.Max(minSpeed, maxSpeed);
|
||||
pointerSpeed = Mathf.Clamp(pointerSpeed, minSpeed, maxSpeed);
|
||||
|
||||
minZoneSize = Mathf.Clamp(minZoneSize, 1f, 360f);
|
||||
maxZoneSize = Mathf.Clamp(maxZoneSize, minZoneSize, 360f);
|
||||
startZoneSize = Mathf.Clamp(startZoneSize, minZoneSize, maxZoneSize);
|
||||
zoneSize = Mathf.Clamp(zoneSize, minZoneSize, maxZoneSize);
|
||||
|
||||
nextRoundDelay = Mathf.Max(0f, nextRoundDelay);
|
||||
nextCatchDelay = Mathf.Max(0f, nextCatchDelay);
|
||||
finalResultShowTime = Mathf.Max(0f, finalResultShowTime);
|
||||
|
||||
pointerAngle = Normalize(pointerAngle);
|
||||
zoneCenter = Normalize(zoneCenter);
|
||||
cleanupItemCount = Mathf.Max(0, cleanupItemCount);
|
||||
totalCaughtItems = Mathf.Max(0, totalCaughtItems);
|
||||
}
|
||||
|
||||
private void InitializeIdleUI()
|
||||
{
|
||||
if (ui != null)
|
||||
{
|
||||
ui.HideRoundResult();
|
||||
ui.HideFinalResult();
|
||||
ui.InitializeFishingUI();
|
||||
ui.UpdateCounter(0, requiredSuccesses, 0, allowedFails);
|
||||
ui.UpdateFishingProgress(cleanupItemCount, requiredCleanupItems, pondCleaned, memoryPieceCollected, totalCaughtItems);
|
||||
ui.UpdateInventoryUI(sessionFishCount, sessionTrashCount, sessionMemoryPieceCount, sessionCompassCount);
|
||||
ui.SetPointerRotation(0f);
|
||||
ui.SetZone(0f, startZoneSize);
|
||||
}
|
||||
@@ -91,30 +301,73 @@ private void InitializeIdleUI()
|
||||
|
||||
public void StartFishing()
|
||||
{
|
||||
if (nextRoundRoutine != null)
|
||||
{
|
||||
StopCoroutine(nextRoundRoutine);
|
||||
nextRoundRoutine = null;
|
||||
}
|
||||
ValidateRuntimeSettings();
|
||||
StopRunningRoutines();
|
||||
|
||||
successCount = 0;
|
||||
failCount = 0;
|
||||
if (uiRoot != null)
|
||||
uiRoot.SetActive(true);
|
||||
|
||||
pointerAngle = 0f;
|
||||
pointerSpeed = minSpeed;
|
||||
zoneSize = startZoneSize;
|
||||
|
||||
activeGame = true;
|
||||
inputLocked = false;
|
||||
|
||||
clockwise = Random.value > 0.5f;
|
||||
if (resetPondStateOnStart)
|
||||
ResetPondState();
|
||||
|
||||
if (ui != null)
|
||||
ui.InitializeFishingUI();
|
||||
|
||||
StartNewCatchAttempt();
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("기묘한 낚시터 시작");
|
||||
}
|
||||
|
||||
public void StopFishing(bool hideUI = false)
|
||||
{
|
||||
StopRunningRoutines();
|
||||
|
||||
activeGame = false;
|
||||
inputLocked = true;
|
||||
|
||||
if (centerIconRotate != null)
|
||||
centerIconRotate.StopRotate();
|
||||
|
||||
if (hideUI && uiRoot != null)
|
||||
uiRoot.SetActive(false);
|
||||
}
|
||||
|
||||
public void ResetFishing()
|
||||
{
|
||||
StartFishing();
|
||||
}
|
||||
|
||||
public void ResetPondState()
|
||||
{
|
||||
successCount = 0;
|
||||
failCount = 0;
|
||||
cleanupItemCount = 0;
|
||||
totalCaughtItems = 0;
|
||||
sessionFishCount = 0;
|
||||
sessionTrashCount = 0;
|
||||
sessionMemoryPieceCount = 0;
|
||||
sessionCompassCount = 0;
|
||||
pondCleaned = false;
|
||||
memoryPieceCollected = false;
|
||||
}
|
||||
|
||||
private void StartNewCatchAttempt()
|
||||
{
|
||||
successCount = 0;
|
||||
failCount = 0;
|
||||
inputLocked = false;
|
||||
activeGame = true;
|
||||
|
||||
if (resetDifficultyEachCatch)
|
||||
{
|
||||
ui.HideRoundResult();
|
||||
ui.HideFinalResult();
|
||||
pointerAngle = 0f;
|
||||
pointerSpeed = minSpeed;
|
||||
zoneSize = startZoneSize;
|
||||
}
|
||||
|
||||
clockwise = UnityEngine.Random.value > 0.5f;
|
||||
|
||||
if (centerIconRotate != null)
|
||||
{
|
||||
centerIconRotate.ResetRotation();
|
||||
@@ -123,9 +376,27 @@ public void StartFishing()
|
||||
|
||||
RandomizeZone();
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 시작");
|
||||
private void StopRunningRoutines()
|
||||
{
|
||||
if (nextRoundRoutine != null)
|
||||
{
|
||||
StopCoroutine(nextRoundRoutine);
|
||||
nextRoundRoutine = null;
|
||||
}
|
||||
|
||||
if (nextCatchRoutine != null)
|
||||
{
|
||||
StopCoroutine(nextCatchRoutine);
|
||||
nextCatchRoutine = null;
|
||||
}
|
||||
|
||||
if (finalResultRoutine != null)
|
||||
{
|
||||
StopCoroutine(finalResultRoutine);
|
||||
finalResultRoutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotatePointer()
|
||||
@@ -149,8 +420,17 @@ public void SubmitAttempt()
|
||||
|
||||
inputLocked = true;
|
||||
|
||||
if (ui != null)
|
||||
ui.HideControllerGuide();
|
||||
|
||||
ResultType result = EvaluateResult();
|
||||
|
||||
if (ui != null)
|
||||
{
|
||||
ui.ShowResultForType(result);
|
||||
ui.FlashFeedbackForType(result);
|
||||
}
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case ResultType.Perfect:
|
||||
@@ -168,7 +448,7 @@ public void SubmitAttempt()
|
||||
|
||||
if (successCount >= requiredSuccesses)
|
||||
{
|
||||
FishingSuccess();
|
||||
CatchItemSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -207,11 +487,8 @@ private void OnPerfect()
|
||||
if (haptic != null)
|
||||
haptic.Perfect();
|
||||
|
||||
if (ui != null)
|
||||
ui.ShowResult("완벽!");
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 판정: Perfect");
|
||||
Debug.Log("낚시 판정: Perfect");
|
||||
|
||||
ClampDifficulty();
|
||||
UpdateUI();
|
||||
@@ -227,11 +504,8 @@ private void OnGood()
|
||||
if (haptic != null)
|
||||
haptic.Good();
|
||||
|
||||
if (ui != null)
|
||||
ui.ShowResult("성공!");
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 판정: Good");
|
||||
Debug.Log("낚시 판정: Good");
|
||||
|
||||
ClampDifficulty();
|
||||
UpdateUI();
|
||||
@@ -247,11 +521,8 @@ private void OnMiss()
|
||||
if (haptic != null)
|
||||
haptic.Miss();
|
||||
|
||||
if (ui != null)
|
||||
ui.ShowResult("실패!");
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 판정: Miss");
|
||||
Debug.Log("낚시 판정: Miss");
|
||||
|
||||
ClampDifficulty();
|
||||
UpdateUI();
|
||||
@@ -262,10 +533,13 @@ private IEnumerator NextRoundRoutine()
|
||||
yield return new WaitForSeconds(nextRoundDelay);
|
||||
|
||||
if (!activeGame)
|
||||
{
|
||||
nextRoundRoutine = null;
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (randomDirectionEachRound)
|
||||
clockwise = Random.value > 0.5f;
|
||||
clockwise = UnityEngine.Random.value > 0.5f;
|
||||
|
||||
RandomizeZone();
|
||||
UpdateUI();
|
||||
@@ -274,6 +548,122 @@ private IEnumerator NextRoundRoutine()
|
||||
nextRoundRoutine = null;
|
||||
}
|
||||
|
||||
private void CatchItemSuccess()
|
||||
{
|
||||
activeGame = false;
|
||||
inputLocked = true;
|
||||
|
||||
if (centerIconRotate != null)
|
||||
centerIconRotate.StopRotate();
|
||||
|
||||
bool forceMemoryPiece = pondCleaned && guaranteeMemoryPieceAfterCleaned && !memoryPieceCollected;
|
||||
|
||||
FishingRewardSystem.CatchResult catchResult;
|
||||
|
||||
if (rewardSystem != null)
|
||||
catchResult = rewardSystem.RollCatch(pondCleaned, forceMemoryPiece);
|
||||
else
|
||||
catchResult = new FishingRewardSystem.CatchResult(FishingItemType.Fish, "생선", false, false);
|
||||
|
||||
ApplyCatchResult(catchResult);
|
||||
}
|
||||
|
||||
private void ApplyCatchResult(FishingRewardSystem.CatchResult catchResult)
|
||||
{
|
||||
totalCaughtItems++;
|
||||
|
||||
AddToSessionCounts(catchResult.ItemType);
|
||||
ItemCaught?.Invoke(catchResult.ItemType, 1);
|
||||
|
||||
bool pondJustCleaned = false;
|
||||
string extraHint = string.Empty;
|
||||
|
||||
if (catchResult.CountsAsCleanupItem)
|
||||
{
|
||||
cleanupItemCount = Mathf.Min(cleanupItemCount + 1, requiredCleanupItems);
|
||||
extraHint = $"연못 정화 {cleanupItemCount}/{requiredCleanupItems}";
|
||||
|
||||
if (!pondCleaned && cleanupItemCount >= requiredCleanupItems)
|
||||
{
|
||||
pondCleaned = true;
|
||||
pondJustCleaned = true;
|
||||
extraHint = "연못이 맑아졌다. 기억의 조각이 모습을 드러낸다.";
|
||||
}
|
||||
}
|
||||
|
||||
if (catchResult.IsMemoryPiece)
|
||||
{
|
||||
memoryPieceCollected = true;
|
||||
extraHint = "잃어버린 기억의 일부다.";
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
|
||||
if (ui != null)
|
||||
{
|
||||
ui.HighlightSlotForItem(catchResult.ItemType);
|
||||
|
||||
if (!catchResult.IsMemoryPiece)
|
||||
ui.ShowCaughtItem(catchResult.ItemType, catchResult.DisplayName, catchResult.CountsAsCleanupItem, extraHint);
|
||||
|
||||
if (pondJustCleaned)
|
||||
ui.ShowNotice("연못이 맑아졌다!\n기억의 조각이 모습을 드러냈다!");
|
||||
|
||||
// 기억의 조각 획득은 FinalResultPanel에서 크게 보여줍니다.
|
||||
// NoticePanel까지 동시에 띄우면 ShowFinalResult에서 바로 숨겨져 연출이 겹칠 수 있습니다.
|
||||
}
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log($"{catchResult.DisplayName}을(를) 낚았다!");
|
||||
|
||||
if (catchResult.IsMemoryPiece)
|
||||
{
|
||||
FishingSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
nextCatchRoutine = StartCoroutine(NextCatchRoutine());
|
||||
}
|
||||
|
||||
private IEnumerator NextCatchRoutine()
|
||||
{
|
||||
yield return new WaitForSeconds(nextCatchDelay);
|
||||
|
||||
if (memoryPieceCollected)
|
||||
{
|
||||
nextCatchRoutine = null;
|
||||
yield break;
|
||||
}
|
||||
|
||||
StartNewCatchAttempt();
|
||||
nextCatchRoutine = null;
|
||||
}
|
||||
|
||||
|
||||
private void AddToSessionCounts(FishingItemType itemType)
|
||||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case FishingItemType.Fish:
|
||||
sessionFishCount++;
|
||||
break;
|
||||
|
||||
case FishingItemType.Trash:
|
||||
case FishingItemType.Bottle:
|
||||
case FishingItemType.PlasticBag:
|
||||
sessionTrashCount++;
|
||||
break;
|
||||
|
||||
case FishingItemType.MemoryPiece:
|
||||
sessionMemoryPieceCount++;
|
||||
break;
|
||||
|
||||
case FishingItemType.OldCompass:
|
||||
sessionCompassCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClampDifficulty()
|
||||
{
|
||||
zoneSize = Mathf.Clamp(zoneSize, minZoneSize, maxZoneSize);
|
||||
@@ -282,7 +672,7 @@ private void ClampDifficulty()
|
||||
|
||||
private void RandomizeZone()
|
||||
{
|
||||
zoneCenter = Random.Range(0f, 360f);
|
||||
zoneCenter = UnityEngine.Random.Range(0f, 360f);
|
||||
}
|
||||
|
||||
private void UpdateUI()
|
||||
@@ -292,6 +682,8 @@ private void UpdateUI()
|
||||
|
||||
ui.SetZone(zoneCenter, zoneSize);
|
||||
ui.UpdateCounter(successCount, requiredSuccesses, failCount, allowedFails);
|
||||
ui.UpdateFishingProgress(cleanupItemCount, requiredCleanupItems, pondCleaned, memoryPieceCollected, totalCaughtItems);
|
||||
ui.UpdateInventoryUI(sessionFishCount, sessionTrashCount, sessionMemoryPieceCount, sessionCompassCount);
|
||||
}
|
||||
|
||||
private void FishingSuccess()
|
||||
@@ -302,14 +694,15 @@ private void FishingSuccess()
|
||||
if (centerIconRotate != null)
|
||||
centerIconRotate.StopRotate();
|
||||
|
||||
if (ui != null)
|
||||
ui.ShowFinalResult("낚시 성공!");
|
||||
UpdateUI();
|
||||
|
||||
if (rewardSystem != null)
|
||||
rewardSystem.GiveReward();
|
||||
if (ui != null)
|
||||
ui.ShowFinalResult("기억의 조각 획득!\n기묘한 낚시터 클리어!");
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 최종 성공");
|
||||
Debug.Log("기묘한 낚시터 클리어");
|
||||
|
||||
BeginFinalResultRoutineIfNeeded();
|
||||
}
|
||||
|
||||
private void FishingFail()
|
||||
@@ -321,15 +714,33 @@ private void FishingFail()
|
||||
centerIconRotate.StopRotate();
|
||||
|
||||
if (ui != null)
|
||||
ui.ShowFinalResult("낚시 실패!");
|
||||
ui.ShowFinalResult("낚싯줄이 끊어졌다!\n다시 천천히 낚아보자.");
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 최종 실패");
|
||||
Debug.Log("낚시 실패: 낚싯줄 끊어짐");
|
||||
|
||||
BeginFinalResultRoutineIfNeeded();
|
||||
}
|
||||
|
||||
public void ResetFishing()
|
||||
private void BeginFinalResultRoutineIfNeeded()
|
||||
{
|
||||
StartFishing();
|
||||
if (!hideUIRootAfterFinalResult || uiRoot == null)
|
||||
return;
|
||||
|
||||
if (finalResultRoutine != null)
|
||||
StopCoroutine(finalResultRoutine);
|
||||
|
||||
finalResultRoutine = StartCoroutine(HideUIRootAfterFinalResultRoutine());
|
||||
}
|
||||
|
||||
private IEnumerator HideUIRootAfterFinalResultRoutine()
|
||||
{
|
||||
yield return new WaitForSeconds(finalResultShowTime);
|
||||
|
||||
if (uiRoot != null)
|
||||
uiRoot.SetActive(false);
|
||||
|
||||
finalResultRoutine = null;
|
||||
}
|
||||
|
||||
private float Normalize(float angle)
|
||||
@@ -342,17 +753,13 @@ private float Normalize(float angle)
|
||||
return angle;
|
||||
}
|
||||
|
||||
// XR Input Action의 Select / Trigger 버튼에 연결
|
||||
public void OnSubmit(InputValue value)
|
||||
private void OnSubmitAction(InputAction.CallbackContext context)
|
||||
{
|
||||
if (value.isPressed)
|
||||
SubmitAttempt();
|
||||
SubmitAttempt();
|
||||
}
|
||||
|
||||
// Reset 버튼에 연결 가능
|
||||
public void OnReset(InputValue value)
|
||||
private void OnResetAction(InputAction.CallbackContext context)
|
||||
{
|
||||
if (value.isPressed)
|
||||
ResetFishing();
|
||||
ResetFishing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ public class FishingHapticManager : MonoBehaviour
|
||||
|
||||
[Header("Haptic Settings")]
|
||||
[SerializeField] private bool useHaptic = true;
|
||||
[SerializeField] private bool showHapticDebugLog = false;
|
||||
|
||||
[SerializeField] private float perfectAmplitude = 1f;
|
||||
[SerializeField] private float perfectDuration = 0.2f;
|
||||
@@ -18,6 +19,19 @@ public class FishingHapticManager : MonoBehaviour
|
||||
[SerializeField] private float missAmplitude = 0.2f;
|
||||
[SerializeField] private float missDuration = 0.05f;
|
||||
|
||||
public XRNode TargetHand => targetHand;
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
perfectAmplitude = Mathf.Clamp01(perfectAmplitude);
|
||||
goodAmplitude = Mathf.Clamp01(goodAmplitude);
|
||||
missAmplitude = Mathf.Clamp01(missAmplitude);
|
||||
|
||||
perfectDuration = Mathf.Max(0f, perfectDuration);
|
||||
goodDuration = Mathf.Max(0f, goodDuration);
|
||||
missDuration = Mathf.Max(0f, missDuration);
|
||||
}
|
||||
|
||||
private void SendHaptic(float amplitude, float duration)
|
||||
{
|
||||
if (!useHaptic)
|
||||
@@ -26,15 +40,46 @@ private void SendHaptic(float amplitude, float duration)
|
||||
InputDevice device = InputDevices.GetDeviceAtXRNode(targetHand);
|
||||
|
||||
if (!device.isValid)
|
||||
return;
|
||||
|
||||
if (device.TryGetHapticCapabilities(out HapticCapabilities capabilities))
|
||||
{
|
||||
if (!capabilities.supportsImpulse)
|
||||
return;
|
||||
LogHapticWarning("Haptic device not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
device.SendHapticImpulse(0u, Mathf.Clamp01(amplitude), duration);
|
||||
if (!device.TryGetHapticCapabilities(out HapticCapabilities capabilities))
|
||||
{
|
||||
LogHapticWarning("Haptic capabilities not available.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!capabilities.supportsImpulse)
|
||||
{
|
||||
LogHapticWarning("Haptic impulse is not supported on this device.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (capabilities.numChannels < 1)
|
||||
{
|
||||
LogHapticWarning("Haptic channel count is zero.");
|
||||
return;
|
||||
}
|
||||
|
||||
device.SendHapticImpulse(0u, Mathf.Clamp01(amplitude), Mathf.Max(0f, duration));
|
||||
}
|
||||
|
||||
private void LogHapticWarning(string message)
|
||||
{
|
||||
if (showHapticDebugLog)
|
||||
Debug.LogWarning($"[FishingHapticManager] {message}", this);
|
||||
}
|
||||
|
||||
public void SetTargetHand(XRNode hand)
|
||||
{
|
||||
targetHand = hand;
|
||||
}
|
||||
|
||||
public void SetUseHaptic(bool value)
|
||||
{
|
||||
useHaptic = value;
|
||||
}
|
||||
|
||||
public void Perfect()
|
||||
@@ -51,4 +96,4 @@ public void Miss()
|
||||
{
|
||||
SendHaptic(missAmplitude, missDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
178
Assets/My project/Fishing Scripts/UI/FishingInventory.cs
Normal file
178
Assets/My project/Fishing Scripts/UI/FishingInventory.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class FishingInventory : MonoBehaviour
|
||||
{
|
||||
[Header("Item Counts")]
|
||||
[SerializeField] private int fishCount;
|
||||
[SerializeField] private int rottenFishCount;
|
||||
[SerializeField] private int trashCount;
|
||||
[SerializeField] private int bottleCount;
|
||||
[SerializeField] private int plasticBagCount;
|
||||
[SerializeField] private int jellyfishPowderCount;
|
||||
[SerializeField] private int oldCompassCount;
|
||||
[SerializeField] private int memoryPieceCount;
|
||||
|
||||
public int FishCount => fishCount;
|
||||
public int RottenFishCount => rottenFishCount;
|
||||
public int TrashCount => trashCount;
|
||||
public int BottleCount => bottleCount;
|
||||
public int PlasticBagCount => plasticBagCount;
|
||||
public int JellyfishPowderCount => jellyfishPowderCount;
|
||||
public int OldCompassCount => oldCompassCount;
|
||||
public int MemoryPieceCount => memoryPieceCount;
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
ClampCounts();
|
||||
}
|
||||
|
||||
private void ClampCounts()
|
||||
{
|
||||
fishCount = Mathf.Max(0, fishCount);
|
||||
rottenFishCount = Mathf.Max(0, rottenFishCount);
|
||||
trashCount = Mathf.Max(0, trashCount);
|
||||
bottleCount = Mathf.Max(0, bottleCount);
|
||||
plasticBagCount = Mathf.Max(0, plasticBagCount);
|
||||
jellyfishPowderCount = Mathf.Max(0, jellyfishPowderCount);
|
||||
oldCompassCount = Mathf.Max(0, oldCompassCount);
|
||||
memoryPieceCount = Mathf.Max(0, memoryPieceCount);
|
||||
}
|
||||
|
||||
public void AddItem(FishingItemType itemType, int amount = 1)
|
||||
{
|
||||
if (itemType == FishingItemType.None || amount <= 0)
|
||||
return;
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
case FishingItemType.Fish:
|
||||
fishCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.RottenFish:
|
||||
rottenFishCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.Trash:
|
||||
trashCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.Bottle:
|
||||
bottleCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.PlasticBag:
|
||||
plasticBagCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.JellyfishPowder:
|
||||
jellyfishPowderCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.OldCompass:
|
||||
oldCompassCount += amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.MemoryPiece:
|
||||
memoryPieceCount += amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasItem(FishingItemType itemType, int amount = 1)
|
||||
{
|
||||
if (itemType == FishingItemType.None || amount <= 0)
|
||||
return false;
|
||||
|
||||
return GetItemCount(itemType) >= amount;
|
||||
}
|
||||
|
||||
public bool ConsumeItem(FishingItemType itemType, int amount = 1)
|
||||
{
|
||||
if (!HasItem(itemType, amount))
|
||||
return false;
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
case FishingItemType.Fish:
|
||||
fishCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.RottenFish:
|
||||
rottenFishCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.Trash:
|
||||
trashCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.Bottle:
|
||||
bottleCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.PlasticBag:
|
||||
plasticBagCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.JellyfishPowder:
|
||||
jellyfishPowderCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.OldCompass:
|
||||
oldCompassCount -= amount;
|
||||
break;
|
||||
|
||||
case FishingItemType.MemoryPiece:
|
||||
memoryPieceCount -= amount;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int GetItemCount(FishingItemType itemType)
|
||||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case FishingItemType.Fish:
|
||||
return fishCount;
|
||||
|
||||
case FishingItemType.RottenFish:
|
||||
return rottenFishCount;
|
||||
|
||||
case FishingItemType.Trash:
|
||||
return trashCount;
|
||||
|
||||
case FishingItemType.Bottle:
|
||||
return bottleCount;
|
||||
|
||||
case FishingItemType.PlasticBag:
|
||||
return plasticBagCount;
|
||||
|
||||
case FishingItemType.JellyfishPowder:
|
||||
return jellyfishPowderCount;
|
||||
|
||||
case FishingItemType.OldCompass:
|
||||
return oldCompassCount;
|
||||
|
||||
case FishingItemType.MemoryPiece:
|
||||
return memoryPieceCount;
|
||||
|
||||
case FishingItemType.None:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetInventory()
|
||||
{
|
||||
fishCount = 0;
|
||||
rottenFishCount = 0;
|
||||
trashCount = 0;
|
||||
bottleCount = 0;
|
||||
plasticBagCount = 0;
|
||||
jellyfishPowderCount = 0;
|
||||
oldCompassCount = 0;
|
||||
memoryPieceCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df5f5119d6ecc8746a4ee16c9f1b50cd
|
||||
12
Assets/My project/Fishing Scripts/UI/FishingItemType.cs
Normal file
12
Assets/My project/Fishing Scripts/UI/FishingItemType.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
public enum FishingItemType
|
||||
{
|
||||
None,
|
||||
Fish,
|
||||
RottenFish,
|
||||
Trash,
|
||||
Bottle,
|
||||
PlasticBag,
|
||||
JellyfishPowder,
|
||||
OldCompass,
|
||||
MemoryPiece
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6365b670fd7854c4bb6024c911f30c5c
|
||||
350
Assets/My project/Fishing Scripts/UI/FishingModelLineFollower.cs
Normal file
350
Assets/My project/Fishing Scripts/UI/FishingModelLineFollower.cs
Normal file
@@ -0,0 +1,350 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 모델 낚시줄을 두 포인트 사이에 맞춰 배치/회전/길이 스케일하는 스크립트입니다.
|
||||
/// 권장 사용 방식:
|
||||
/// - StretchLineRoot 빈 오브젝트에 이 스크립트를 붙입니다.
|
||||
/// - StretchLineRoot 자식으로 '늘어나는 중간 줄 모델'만 넣습니다.
|
||||
/// - RodFixedLinePart, BobberFixedLinePart, Bobber/Hook은 StretchLineRoot 안에 넣지 않습니다.
|
||||
/// - 낚시찌는 BobberLineStartPoint의 자식으로 넣어 줄 끝점에 고정합니다.
|
||||
/// </summary>
|
||||
public class FishingModelLineFollower : MonoBehaviour
|
||||
{
|
||||
public enum LineUseMode
|
||||
{
|
||||
WholeModelLine,
|
||||
StretchSegmentOnly
|
||||
}
|
||||
|
||||
public enum LineAxis
|
||||
{
|
||||
LocalX,
|
||||
LocalY,
|
||||
LocalZ
|
||||
}
|
||||
|
||||
public enum PivotMode
|
||||
{
|
||||
Center,
|
||||
Start,
|
||||
End
|
||||
}
|
||||
|
||||
[Header("Mode")]
|
||||
[Tooltip("WholeModelLine: 전체 줄 모델을 두 포인트 사이에 맞춤 / StretchSegmentOnly: 분리된 중간 줄 조각만 늘리는 권장 모드")]
|
||||
[SerializeField] private LineUseMode lineUseMode = LineUseMode.StretchSegmentOnly;
|
||||
|
||||
[Header("Line Targets")]
|
||||
[Tooltip("늘어나는 줄의 시작점입니다. StretchSegmentOnly에서는 RodLineEndPoint를 연결하세요.")]
|
||||
[SerializeField] private Transform rodTipPoint;
|
||||
|
||||
[Tooltip("늘어나는 줄의 끝점입니다. StretchSegmentOnly에서는 BobberLineStartPoint를 연결하세요.")]
|
||||
[SerializeField] private Transform bobberPoint;
|
||||
|
||||
[Header("Stretch Settings")]
|
||||
[Tooltip("모델 줄의 길이 방향 축입니다. 보통 LocalY부터 테스트하세요.")]
|
||||
[SerializeField] private LineAxis lineAxis = LineAxis.LocalY;
|
||||
|
||||
[Tooltip("모델 줄의 원본 길이입니다. 줄이 너무 길게 늘어나면 값을 키우고, 너무 짧으면 값을 줄이세요.")]
|
||||
[Min(0.0001f)]
|
||||
[SerializeField] private float originalLength = 1f;
|
||||
|
||||
[Tooltip("두 포인트가 너무 가까울 때 사용할 최소 길이입니다.")]
|
||||
[Min(0.0001f)]
|
||||
[SerializeField] private float minLength = 0.03f;
|
||||
|
||||
[Tooltip("줄 두께 배율입니다. 1이면 원본 두께를 유지합니다.")]
|
||||
[Min(0.0001f)]
|
||||
[SerializeField] private float thicknessScale = 1f;
|
||||
|
||||
[Tooltip("모델 줄의 앞뒤 방향이 거꾸로 보일 때 켜세요. 포인트 연결은 바꾸지 않는 것을 추천합니다.")]
|
||||
[SerializeField] private bool reverseVisualDirection;
|
||||
|
||||
[Tooltip("대부분 Center를 권장합니다. 모델 Pivot이 시작점/끝점에 있으면 Start 또는 End를 테스트하세요.")]
|
||||
[SerializeField] private PivotMode pivotMode = PivotMode.Center;
|
||||
|
||||
[Header("Visual Mesh Correction")]
|
||||
[Tooltip("실제 Mesh 자식입니다. 비워두면 첫 번째 Renderer가 있는 자식을 자동으로 찾습니다. 위치 보정은 Root가 아니라 이 Visual에 적용하세요.")]
|
||||
[SerializeField] private Transform visualRoot;
|
||||
|
||||
[Tooltip("Visual Mesh의 로컬 위치 보정값입니다. 줄이 살짝 위/옆으로 떠 있을 때 작은 값으로만 보정하세요.")]
|
||||
[SerializeField] private Vector3 visualLocalPositionOffset;
|
||||
|
||||
[Tooltip("Visual Mesh의 로컬 회전 보정값입니다. 모델 자체가 90도 틀어져 있을 때 사용하세요.")]
|
||||
[SerializeField] private Vector3 visualLocalRotationOffsetEuler;
|
||||
|
||||
[Header("Root Rotation Correction")]
|
||||
[Tooltip("루트 회전 보정값입니다. 가능하면 0,0,0으로 두고 Line Axis / Reverse Visual Direction / Visual Rotation Offset으로 먼저 맞추세요.")]
|
||||
[SerializeField] private Vector3 rootRotationOffsetEuler;
|
||||
|
||||
[Header("Visibility / Update")]
|
||||
[SerializeField] private bool hideWhenMissingTarget = true;
|
||||
[SerializeField] private bool hideWhenTooShort = false;
|
||||
[SerializeField] private bool updateInLateUpdate = true;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool drawDebugLine = true;
|
||||
[SerializeField] private Color debugLineColor = Color.cyan;
|
||||
|
||||
private Vector3 initialLocalScale = Vector3.one;
|
||||
private Vector3 visualInitialLocalPosition;
|
||||
private Quaternion visualInitialLocalRotation = Quaternion.identity;
|
||||
private bool initialized;
|
||||
|
||||
public LineUseMode CurrentLineUseMode => lineUseMode;
|
||||
public Transform RodTipPoint => rodTipPoint;
|
||||
public Transform BobberPoint => bobberPoint;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
lineUseMode = LineUseMode.StretchSegmentOnly;
|
||||
lineAxis = LineAxis.LocalY;
|
||||
originalLength = 1f;
|
||||
minLength = 0.03f;
|
||||
thicknessScale = 1f;
|
||||
pivotMode = PivotMode.Center;
|
||||
updateInLateUpdate = true;
|
||||
drawDebugLine = true;
|
||||
TryAutoFindVisualRoot();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!updateInLateUpdate)
|
||||
UpdateLine();
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (updateInLateUpdate)
|
||||
UpdateLine();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
originalLength = Mathf.Max(0.0001f, originalLength);
|
||||
minLength = Mathf.Max(0.0001f, minLength);
|
||||
thicknessScale = Mathf.Max(0.0001f, thicknessScale);
|
||||
|
||||
if (!Application.isPlaying)
|
||||
TryAutoFindVisualRoot();
|
||||
}
|
||||
|
||||
private void InitializeIfNeeded()
|
||||
{
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
initialLocalScale = transform.localScale;
|
||||
|
||||
if (visualRoot == null)
|
||||
TryAutoFindVisualRoot();
|
||||
|
||||
if (visualRoot != null)
|
||||
{
|
||||
visualInitialLocalPosition = visualRoot.localPosition;
|
||||
visualInitialLocalRotation = visualRoot.localRotation;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private void UpdateLine()
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
if (rodTipPoint == null || bobberPoint == null)
|
||||
{
|
||||
SetVisible(!hideWhenMissingTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 start = rodTipPoint.position;
|
||||
Vector3 end = bobberPoint.position;
|
||||
Vector3 segment = end - start;
|
||||
float distance = segment.magnitude;
|
||||
|
||||
if (distance < minLength)
|
||||
{
|
||||
if (hideWhenTooShort)
|
||||
{
|
||||
SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
distance = minLength;
|
||||
}
|
||||
|
||||
Vector3 direction = segment.sqrMagnitude > 0.000001f ? segment.normalized : transform.forward;
|
||||
Vector3 visualDirection = reverseVisualDirection ? -direction : direction;
|
||||
|
||||
SetVisible(true);
|
||||
|
||||
transform.position = GetRootPosition(start, end);
|
||||
transform.rotation = Quaternion.FromToRotation(GetAxisVector(lineAxis), visualDirection) * Quaternion.Euler(rootRotationOffsetEuler);
|
||||
transform.localScale = GetScaledVector(distance);
|
||||
|
||||
ApplyVisualCorrection();
|
||||
|
||||
if (drawDebugLine)
|
||||
Debug.DrawLine(start, end, debugLineColor);
|
||||
}
|
||||
|
||||
private Vector3 GetRootPosition(Vector3 start, Vector3 end)
|
||||
{
|
||||
switch (pivotMode)
|
||||
{
|
||||
case PivotMode.Start:
|
||||
return start;
|
||||
case PivotMode.End:
|
||||
return end;
|
||||
case PivotMode.Center:
|
||||
default:
|
||||
return (start + end) * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetScaledVector(float targetLength)
|
||||
{
|
||||
float lengthScale = targetLength / Mathf.Max(0.0001f, originalLength);
|
||||
|
||||
Vector3 scale = initialLocalScale;
|
||||
|
||||
switch (lineAxis)
|
||||
{
|
||||
case LineAxis.LocalX:
|
||||
scale.x = initialLocalScale.x * lengthScale;
|
||||
scale.y = initialLocalScale.y * thicknessScale;
|
||||
scale.z = initialLocalScale.z * thicknessScale;
|
||||
break;
|
||||
|
||||
case LineAxis.LocalY:
|
||||
scale.x = initialLocalScale.x * thicknessScale;
|
||||
scale.y = initialLocalScale.y * lengthScale;
|
||||
scale.z = initialLocalScale.z * thicknessScale;
|
||||
break;
|
||||
|
||||
case LineAxis.LocalZ:
|
||||
scale.x = initialLocalScale.x * thicknessScale;
|
||||
scale.y = initialLocalScale.y * thicknessScale;
|
||||
scale.z = initialLocalScale.z * lengthScale;
|
||||
break;
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
private static Vector3 GetAxisVector(LineAxis axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case LineAxis.LocalX:
|
||||
return Vector3.right;
|
||||
case LineAxis.LocalY:
|
||||
return Vector3.up;
|
||||
case LineAxis.LocalZ:
|
||||
return Vector3.forward;
|
||||
default:
|
||||
return Vector3.up;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyVisualCorrection()
|
||||
{
|
||||
if (visualRoot == null)
|
||||
return;
|
||||
|
||||
visualRoot.localPosition = visualInitialLocalPosition + visualLocalPositionOffset;
|
||||
visualRoot.localRotation = visualInitialLocalRotation * Quaternion.Euler(visualLocalRotationOffsetEuler);
|
||||
}
|
||||
|
||||
private void SetVisible(bool visible)
|
||||
{
|
||||
if (visualRoot != null)
|
||||
{
|
||||
SetRenderersVisible(visualRoot, visible);
|
||||
return;
|
||||
}
|
||||
|
||||
SetRenderersVisible(transform, visible);
|
||||
}
|
||||
|
||||
private void SetRenderersVisible(Transform target, bool visible)
|
||||
{
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
Renderer[] renderers = target.GetComponentsInChildren<Renderer>(true);
|
||||
for (int i = 0; i < renderers.Length; i++)
|
||||
renderers[i].enabled = visible;
|
||||
}
|
||||
|
||||
private void TryAutoFindVisualRoot()
|
||||
{
|
||||
if (visualRoot != null)
|
||||
return;
|
||||
|
||||
Renderer directRenderer = GetComponent<Renderer>();
|
||||
if (directRenderer != null)
|
||||
{
|
||||
visualRoot = transform;
|
||||
return;
|
||||
}
|
||||
|
||||
Renderer childRenderer = GetComponentInChildren<Renderer>(true);
|
||||
if (childRenderer != null)
|
||||
visualRoot = childRenderer.transform;
|
||||
}
|
||||
|
||||
[ContextMenu("Set Mode: Stretch Segment Only")]
|
||||
private void SetStretchSegmentOnlyMode()
|
||||
{
|
||||
lineUseMode = LineUseMode.StretchSegmentOnly;
|
||||
}
|
||||
|
||||
[ContextMenu("Reset Corrections")]
|
||||
private void ResetCorrections()
|
||||
{
|
||||
rootRotationOffsetEuler = Vector3.zero;
|
||||
visualLocalPositionOffset = Vector3.zero;
|
||||
visualLocalRotationOffsetEuler = Vector3.zero;
|
||||
}
|
||||
|
||||
[ContextMenu("Calibrate Original Length From Renderer Bounds")]
|
||||
private void CalibrateOriginalLengthFromRendererBounds()
|
||||
{
|
||||
Renderer renderer = visualRoot != null ? visualRoot.GetComponentInChildren<Renderer>(true) : GetComponentInChildren<Renderer>(true);
|
||||
if (renderer == null)
|
||||
{
|
||||
Debug.LogWarning("FishingModelLineFollower: Renderer를 찾지 못해서 Original Length를 자동 계산할 수 없습니다.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 size = renderer.bounds.size;
|
||||
float measured = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
|
||||
originalLength = Mathf.Max(0.0001f, measured);
|
||||
|
||||
Debug.Log($"FishingModelLineFollower: Original Length를 {originalLength:F4}로 설정했습니다.", this);
|
||||
}
|
||||
|
||||
public void SetTargets(Transform startPoint, Transform endPoint)
|
||||
{
|
||||
rodTipPoint = startPoint;
|
||||
bobberPoint = endPoint;
|
||||
}
|
||||
|
||||
public void SetReverseVisualDirection(bool value)
|
||||
{
|
||||
reverseVisualDirection = value;
|
||||
}
|
||||
|
||||
public void SetOriginalLength(float value)
|
||||
{
|
||||
originalLength = Mathf.Max(0.0001f, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8d0073af66f0fc49a7fb32df0bf5e41
|
||||
@@ -1,53 +1,255 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class FishingRewardSystem : MonoBehaviour
|
||||
{
|
||||
public enum RewardType
|
||||
[Serializable]
|
||||
public class LootEntry
|
||||
{
|
||||
Normal,
|
||||
Rare
|
||||
public FishingItemType itemType = FishingItemType.Fish;
|
||||
public string displayName = "생선";
|
||||
[Min(0f)] public float weight = 1f;
|
||||
|
||||
public LootEntry(FishingItemType itemType, string displayName, float weight)
|
||||
{
|
||||
this.itemType = itemType;
|
||||
this.displayName = displayName;
|
||||
this.weight = Mathf.Max(0f, weight);
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Reward Chance")]
|
||||
[Range(0f, 100f)]
|
||||
[SerializeField] private float rareChance = 10f;
|
||||
|
||||
[Header("Reward Count")]
|
||||
[SerializeField] private int normalMemory;
|
||||
[SerializeField] private int rareMemory;
|
||||
|
||||
public int NormalMemory => normalMemory;
|
||||
public int RareMemory => rareMemory;
|
||||
|
||||
public RewardType GiveReward()
|
||||
public struct CatchResult
|
||||
{
|
||||
if (Random.value < rareChance / 100f)
|
||||
return GiveRareMemory();
|
||||
public FishingItemType ItemType;
|
||||
public string DisplayName;
|
||||
public bool CountsAsCleanupItem;
|
||||
public bool IsMemoryPiece;
|
||||
|
||||
return GiveNormalMemory();
|
||||
public CatchResult(FishingItemType itemType, string displayName, bool countsAsCleanupItem, bool isMemoryPiece)
|
||||
{
|
||||
ItemType = itemType;
|
||||
DisplayName = displayName;
|
||||
CountsAsCleanupItem = countsAsCleanupItem;
|
||||
IsMemoryPiece = isMemoryPiece;
|
||||
}
|
||||
}
|
||||
|
||||
private RewardType GiveNormalMemory()
|
||||
[Header("Loot Table - Dirty Pond")]
|
||||
[Tooltip("연못이 정화되기 전 낚이는 아이템 목록입니다. 기억의 조각은 이 테이블에 있어도 자동 제외됩니다.")]
|
||||
[SerializeField] private List<LootEntry> dirtyPondLootTable = new List<LootEntry>();
|
||||
|
||||
[Header("Loot Table - Clean Pond")]
|
||||
[Tooltip("연못이 정화된 뒤 낚이는 아이템 목록입니다. 기억의 조각을 포함할 수 있습니다.")]
|
||||
[SerializeField] private List<LootEntry> cleanPondLootTable = new List<LootEntry>();
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
public IReadOnlyList<LootEntry> DirtyPondLootTable => dirtyPondLootTable;
|
||||
public IReadOnlyList<LootEntry> CleanPondLootTable => cleanPondLootTable;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
normalMemory++;
|
||||
|
||||
Debug.Log("ÀÏ¹Ý ±â¾ï +1");
|
||||
|
||||
return RewardType.Normal;
|
||||
SetDefaultLootTables();
|
||||
}
|
||||
|
||||
private RewardType GiveRareMemory()
|
||||
private void Awake()
|
||||
{
|
||||
rareMemory++;
|
||||
|
||||
Debug.Log("Èñ±Í ±â¾ï +1");
|
||||
|
||||
return RewardType.Rare;
|
||||
EnsureLootTables();
|
||||
}
|
||||
|
||||
public void ResetRewardCount()
|
||||
private void OnValidate()
|
||||
{
|
||||
normalMemory = 0;
|
||||
rareMemory = 0;
|
||||
EnsureLootTables();
|
||||
ClampLootTable(dirtyPondLootTable);
|
||||
ClampLootTable(cleanPondLootTable);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureLootTables()
|
||||
{
|
||||
if (dirtyPondLootTable == null)
|
||||
dirtyPondLootTable = new List<LootEntry>();
|
||||
|
||||
if (cleanPondLootTable == null)
|
||||
cleanPondLootTable = new List<LootEntry>();
|
||||
|
||||
if (dirtyPondLootTable.Count == 0)
|
||||
SetDefaultDirtyLootTable();
|
||||
|
||||
if (cleanPondLootTable.Count == 0)
|
||||
SetDefaultCleanLootTable();
|
||||
}
|
||||
|
||||
private void SetDefaultLootTables()
|
||||
{
|
||||
SetDefaultDirtyLootTable();
|
||||
SetDefaultCleanLootTable();
|
||||
}
|
||||
|
||||
private void SetDefaultDirtyLootTable()
|
||||
{
|
||||
dirtyPondLootTable = new List<LootEntry>
|
||||
{
|
||||
new LootEntry(FishingItemType.Fish, "생선", 25f),
|
||||
new LootEntry(FishingItemType.RottenFish, "상한 생선", 8f),
|
||||
new LootEntry(FishingItemType.Trash, "쓰레기", 28f),
|
||||
new LootEntry(FishingItemType.Bottle, "병", 18f),
|
||||
new LootEntry(FishingItemType.PlasticBag, "봉지", 18f),
|
||||
new LootEntry(FishingItemType.JellyfishPowder, "해파리 가루", 6f),
|
||||
new LootEntry(FishingItemType.OldCompass, "낡은 나침반", 4f)
|
||||
};
|
||||
}
|
||||
|
||||
private void SetDefaultCleanLootTable()
|
||||
{
|
||||
cleanPondLootTable = new List<LootEntry>
|
||||
{
|
||||
new LootEntry(FishingItemType.MemoryPiece, "기억의 조각", 30f),
|
||||
new LootEntry(FishingItemType.Fish, "생선", 30f),
|
||||
new LootEntry(FishingItemType.OldCompass, "낡은 나침반", 15f),
|
||||
new LootEntry(FishingItemType.JellyfishPowder, "해파리 가루", 15f),
|
||||
new LootEntry(FishingItemType.RottenFish, "상한 생선", 4f)
|
||||
};
|
||||
}
|
||||
|
||||
private void ClampLootTable(List<LootEntry> table)
|
||||
{
|
||||
if (table == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < table.Count; i++)
|
||||
{
|
||||
if (table[i] == null)
|
||||
{
|
||||
table[i] = new LootEntry(FishingItemType.Fish, "생선", 1f);
|
||||
continue;
|
||||
}
|
||||
|
||||
table[i].weight = Mathf.Max(0f, table[i].weight);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(table[i].displayName))
|
||||
table[i].displayName = GetDefaultDisplayName(table[i].itemType);
|
||||
}
|
||||
}
|
||||
|
||||
public CatchResult RollCatch(bool pondCleaned, bool forceMemoryPiece)
|
||||
{
|
||||
if (forceMemoryPiece)
|
||||
return CreateCatchResult(FishingItemType.MemoryPiece, GetDefaultDisplayName(FishingItemType.MemoryPiece));
|
||||
|
||||
List<LootEntry> table = pondCleaned ? cleanPondLootTable : dirtyPondLootTable;
|
||||
LootEntry selectedEntry = RollFromTable(table, pondCleaned);
|
||||
|
||||
if (selectedEntry == null)
|
||||
return CreateCatchResult(FishingItemType.Fish, GetDefaultDisplayName(FishingItemType.Fish));
|
||||
|
||||
return CreateCatchResult(selectedEntry.itemType, selectedEntry.displayName);
|
||||
}
|
||||
|
||||
private LootEntry RollFromTable(List<LootEntry> table, bool pondCleaned)
|
||||
{
|
||||
if (table == null || table.Count == 0)
|
||||
return null;
|
||||
|
||||
float totalWeight = 0f;
|
||||
|
||||
for (int i = 0; i < table.Count; i++)
|
||||
{
|
||||
LootEntry entry = table[i];
|
||||
|
||||
if (!IsRollableEntry(entry, pondCleaned))
|
||||
continue;
|
||||
|
||||
totalWeight += entry.weight;
|
||||
}
|
||||
|
||||
if (totalWeight <= 0f)
|
||||
return null;
|
||||
|
||||
float roll = UnityEngine.Random.Range(0f, totalWeight);
|
||||
float current = 0f;
|
||||
|
||||
for (int i = 0; i < table.Count; i++)
|
||||
{
|
||||
LootEntry entry = table[i];
|
||||
|
||||
if (!IsRollableEntry(entry, pondCleaned))
|
||||
continue;
|
||||
|
||||
current += entry.weight;
|
||||
|
||||
if (roll <= current)
|
||||
return entry;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsRollableEntry(LootEntry entry, bool pondCleaned)
|
||||
{
|
||||
if (entry == null)
|
||||
return false;
|
||||
|
||||
if (entry.weight <= 0f)
|
||||
return false;
|
||||
|
||||
if (!pondCleaned && entry.itemType == FishingItemType.MemoryPiece)
|
||||
return false;
|
||||
|
||||
return entry.itemType != FishingItemType.None;
|
||||
}
|
||||
|
||||
private CatchResult CreateCatchResult(FishingItemType itemType, string displayName)
|
||||
{
|
||||
string finalDisplayName = string.IsNullOrWhiteSpace(displayName) ? GetDefaultDisplayName(itemType) : displayName;
|
||||
bool countsAsCleanupItem = IsCleanupItem(itemType);
|
||||
bool isMemoryPiece = itemType == FishingItemType.MemoryPiece;
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log($"낚시 획득: {finalDisplayName}");
|
||||
|
||||
return new CatchResult(itemType, finalDisplayName, countsAsCleanupItem, isMemoryPiece);
|
||||
}
|
||||
|
||||
public bool IsCleanupItem(FishingItemType itemType)
|
||||
{
|
||||
return itemType == FishingItemType.Trash ||
|
||||
itemType == FishingItemType.Bottle ||
|
||||
itemType == FishingItemType.PlasticBag;
|
||||
}
|
||||
|
||||
public string GetDefaultDisplayName(FishingItemType itemType)
|
||||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case FishingItemType.Fish:
|
||||
return "생선";
|
||||
|
||||
case FishingItemType.RottenFish:
|
||||
return "상한 생선";
|
||||
|
||||
case FishingItemType.Trash:
|
||||
return "쓰레기";
|
||||
|
||||
case FishingItemType.Bottle:
|
||||
return "병";
|
||||
|
||||
case FishingItemType.PlasticBag:
|
||||
return "봉지";
|
||||
|
||||
case FishingItemType.JellyfishPowder:
|
||||
return "해파리 가루";
|
||||
|
||||
case FishingItemType.OldCompass:
|
||||
return "낡은 나침반";
|
||||
|
||||
case FishingItemType.MemoryPiece:
|
||||
return "기억의 조각";
|
||||
|
||||
case FishingItemType.None:
|
||||
default:
|
||||
return "없음";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
Assets/My project/Fishing Scripts/UI/FishingRodState.cs
Normal file
37
Assets/My project/Fishing Scripts/UI/FishingRodState.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 낚싯대를 잡고 있는지 기록하는 간단한 상태 스크립트입니다.
|
||||
/// FishingRod 오브젝트에 붙이고, XR Grab Interactable의 Select Entered/Exited 이벤트에 연결하세요.
|
||||
/// </summary>
|
||||
public class FishingRodState : MonoBehaviour
|
||||
{
|
||||
[Header("State")]
|
||||
[SerializeField] private bool isHeld;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
public bool IsHeld => isHeld;
|
||||
|
||||
public void MarkHeld()
|
||||
{
|
||||
SetHeld(true);
|
||||
}
|
||||
|
||||
public void MarkReleased()
|
||||
{
|
||||
SetHeld(false);
|
||||
}
|
||||
|
||||
public void SetHeld(bool value)
|
||||
{
|
||||
if (isHeld == value)
|
||||
return;
|
||||
|
||||
isHeld = value;
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log(isHeld ? "낚싯대 잡음" : "낚싯대 놓음");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19b938e652163b1459e2a5d8d862510b
|
||||
244
Assets/My project/Fishing Scripts/UI/FishingStartTrigger.cs
Normal file
244
Assets/My project/Fishing Scripts/UI/FishingStartTrigger.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
/// <summary>
|
||||
/// 낚시터 시작 영역에 붙이는 스크립트입니다.
|
||||
/// 플레이어가 Trigger 영역 안에 들어오면 안내 UI를 켜고,
|
||||
/// 지정한 Start Action 입력이 들어오면 FishingGameManager.StartFishing()을 호출합니다.
|
||||
/// 필요하면 낚싯대를 잡고 있을 때만 시작되도록 제한할 수 있습니다.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public class FishingStartTrigger : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[Tooltip("낚시 미니게임을 제어하는 FishingGameManager입니다.")]
|
||||
[SerializeField] private FishingGameManager fishingGameManager;
|
||||
|
||||
[Tooltip("낚시터 근처에 들어왔을 때 보여줄 시작 안내 UI입니다.")]
|
||||
[SerializeField] private GameObject startGuideUI;
|
||||
|
||||
[Header("Input")]
|
||||
[Tooltip("낚시 시작 입력입니다. 예: XRI RightHand / Primary Button. SubmitAction과 같은 버튼은 피하는 것을 추천합니다.")]
|
||||
[SerializeField] private InputActionReference startAction;
|
||||
|
||||
[Tooltip("Input Action Manager가 없거나 액션이 자동 활성화되지 않으면 켜두세요.")]
|
||||
[SerializeField] private bool enableInputActionManually = true;
|
||||
|
||||
[Header("Player Check")]
|
||||
[Tooltip("플레이어 루트 오브젝트의 태그입니다. 보통 XR Origin에 Player 태그를 붙입니다.")]
|
||||
[SerializeField] private string playerTag = "Player";
|
||||
|
||||
[Tooltip("태그 체크를 끄고 모든 Collider 진입을 플레이어로 취급합니다. 테스트용입니다.")]
|
||||
[SerializeField] private bool ignorePlayerTagForTest = false;
|
||||
|
||||
[Header("Rod Requirement")]
|
||||
[Tooltip("켜면 낚싯대를 잡고 있을 때만 낚시를 시작할 수 있습니다.")]
|
||||
[SerializeField] private bool requireRodHeld = false;
|
||||
|
||||
[Tooltip("낚싯대에 붙어 있는 FishingRodState입니다.")]
|
||||
[SerializeField] private FishingRodState requiredRod;
|
||||
|
||||
[Header("Rules")]
|
||||
[Tooltip("플레이어가 영역에서 나가면 낚시를 중단하고 UI를 숨깁니다. VR에서는 처음에 Off 추천.")]
|
||||
[SerializeField] private bool stopFishingOnExit = false;
|
||||
|
||||
[Tooltip("낚시가 시작되면 시작 안내 UI를 숨깁니다.")]
|
||||
[SerializeField] private bool hideGuideWhenFishingStarts = true;
|
||||
|
||||
[Tooltip("기억의 조각을 이미 획득한 뒤에도 다시 시작할 수 있게 합니다.")]
|
||||
[SerializeField] private bool allowRestartAfterClear = false;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
private bool playerInside;
|
||||
private bool actionWasEnabled;
|
||||
|
||||
public bool PlayerInside => playerInside;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
Collider col = GetComponent<Collider>();
|
||||
if (col != null)
|
||||
col.isTrigger = true;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Collider col = GetComponent<Collider>();
|
||||
if (col != null && !col.isTrigger)
|
||||
col.isTrigger = true;
|
||||
|
||||
SetGuideVisible(false);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
RegisterStartAction();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
UnregisterStartAction();
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (!IsPlayer(other))
|
||||
return;
|
||||
|
||||
playerInside = true;
|
||||
RefreshGuide();
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 시작 영역 진입");
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (!IsPlayer(other))
|
||||
return;
|
||||
|
||||
playerInside = false;
|
||||
SetGuideVisible(false);
|
||||
|
||||
if (stopFishingOnExit && fishingGameManager != null)
|
||||
fishingGameManager.StopFishing(true);
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 시작 영역 이탈");
|
||||
}
|
||||
|
||||
private bool IsPlayer(Collider other)
|
||||
{
|
||||
if (ignorePlayerTagForTest)
|
||||
return true;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
if (other.CompareTag(playerTag))
|
||||
return true;
|
||||
|
||||
Transform current = other.transform;
|
||||
while (current != null)
|
||||
{
|
||||
if (current.CompareTag(playerTag))
|
||||
return true;
|
||||
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void RegisterStartAction()
|
||||
{
|
||||
if (startAction == null || startAction.action == null)
|
||||
return;
|
||||
|
||||
actionWasEnabled = startAction.action.enabled;
|
||||
startAction.action.performed += OnStartAction;
|
||||
|
||||
if (enableInputActionManually && !actionWasEnabled)
|
||||
startAction.action.Enable();
|
||||
}
|
||||
|
||||
private void UnregisterStartAction()
|
||||
{
|
||||
if (startAction == null || startAction.action == null)
|
||||
return;
|
||||
|
||||
startAction.action.performed -= OnStartAction;
|
||||
|
||||
if (enableInputActionManually && !actionWasEnabled)
|
||||
startAction.action.Disable();
|
||||
}
|
||||
|
||||
private void OnStartAction(InputAction.CallbackContext context)
|
||||
{
|
||||
TryStartFishing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI 버튼이나 다른 스크립트에서도 호출할 수 있는 낚시 시작 함수입니다.
|
||||
/// </summary>
|
||||
public void TryStartFishing()
|
||||
{
|
||||
if (!CanStartFishing())
|
||||
return;
|
||||
|
||||
fishingGameManager.StartFishing();
|
||||
|
||||
if (hideGuideWhenFishingStarts)
|
||||
SetGuideVisible(false);
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("낚시 시작 요청 완료");
|
||||
}
|
||||
|
||||
public bool CanStartFishing()
|
||||
{
|
||||
if (!playerInside)
|
||||
return false;
|
||||
|
||||
if (fishingGameManager == null)
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.LogWarning("FishingStartTrigger: FishingGameManager가 연결되지 않았습니다.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fishingGameManager.IsActiveGame)
|
||||
return false;
|
||||
|
||||
if (fishingGameManager.IsMemoryPieceCollected && !allowRestartAfterClear)
|
||||
return false;
|
||||
|
||||
if (requireRodHeld)
|
||||
{
|
||||
if (requiredRod == null)
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.LogWarning("FishingStartTrigger: Require Rod Held가 켜져 있지만 Required Rod가 연결되지 않았습니다.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!requiredRod.IsHeld)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RefreshGuide()
|
||||
{
|
||||
if (!playerInside)
|
||||
{
|
||||
SetGuideVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fishingGameManager != null && fishingGameManager.IsMemoryPieceCollected && !allowRestartAfterClear)
|
||||
{
|
||||
SetGuideVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fishingGameManager != null && fishingGameManager.IsActiveGame)
|
||||
{
|
||||
SetGuideVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetGuideVisible(true);
|
||||
}
|
||||
|
||||
private void SetGuideVisible(bool visible)
|
||||
{
|
||||
if (startGuideUI != null)
|
||||
startGuideUI.SetActive(visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 861cf89cbda384e4b9bf8207fcb6e487
|
||||
361
Assets/My project/Fishing Scripts/UI/FishingUIEffects.cs
Normal file
361
Assets/My project/Fishing Scripts/UI/FishingUIEffects.cs
Normal file
@@ -0,0 +1,361 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class FishingUIEffects : MonoBehaviour
|
||||
{
|
||||
private readonly Dictionary<Object, Coroutine> runningEffects = new Dictionary<Object, Coroutine>();
|
||||
private readonly Dictionary<Transform, Vector3> originalScales = new Dictionary<Transform, Vector3>();
|
||||
private readonly Dictionary<RectTransform, Vector2> originalAnchoredPositions = new Dictionary<RectTransform, Vector2>();
|
||||
|
||||
public CanvasGroup EnsureCanvasGroup(GameObject target)
|
||||
{
|
||||
if (target == null)
|
||||
return null;
|
||||
|
||||
CanvasGroup group = target.GetComponent<CanvasGroup>();
|
||||
if (group == null)
|
||||
group = target.AddComponent<CanvasGroup>();
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public void SetCanvasGroupInstant(GameObject target, CanvasGroup group, bool visible)
|
||||
{
|
||||
if (target == null && group == null)
|
||||
return;
|
||||
|
||||
if (target != null)
|
||||
target.SetActive(visible);
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
group.alpha = visible ? 1f : 0f;
|
||||
group.interactable = visible;
|
||||
group.blocksRaycasts = visible;
|
||||
}
|
||||
}
|
||||
|
||||
public void FadeCanvasGroup(GameObject target, CanvasGroup group, bool visible, float duration)
|
||||
{
|
||||
if (target == null && group == null)
|
||||
return;
|
||||
|
||||
if (group == null && target != null)
|
||||
group = EnsureCanvasGroup(target);
|
||||
|
||||
if (group == null)
|
||||
{
|
||||
if (target != null)
|
||||
target.SetActive(visible);
|
||||
return;
|
||||
}
|
||||
|
||||
StopManaged(group);
|
||||
runningEffects[group] = StartCoroutine(FadeCanvasGroupRoutine(target, group, visible, Mathf.Max(0f, duration)));
|
||||
}
|
||||
|
||||
private IEnumerator FadeCanvasGroupRoutine(GameObject target, CanvasGroup group, bool visible, float duration)
|
||||
{
|
||||
if (target != null && visible)
|
||||
target.SetActive(true);
|
||||
|
||||
group.interactable = visible;
|
||||
group.blocksRaycasts = visible;
|
||||
|
||||
float startAlpha = group.alpha;
|
||||
float endAlpha = visible ? 1f : 0f;
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
group.alpha = endAlpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
float timer = 0f;
|
||||
while (timer < duration)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / duration);
|
||||
t = EaseOutCubic(t);
|
||||
group.alpha = Mathf.Lerp(startAlpha, endAlpha, t);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
group.alpha = endAlpha;
|
||||
}
|
||||
|
||||
if (target != null && !visible)
|
||||
target.SetActive(false);
|
||||
|
||||
runningEffects.Remove(group);
|
||||
}
|
||||
|
||||
public void Pop(Transform target, float peakScale = 1.12f, float duration = 0.18f)
|
||||
{
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
StopManaged(target);
|
||||
runningEffects[target] = StartCoroutine(PopRoutine(target, Mathf.Max(1f, peakScale), Mathf.Max(0.01f, duration)));
|
||||
}
|
||||
|
||||
private IEnumerator PopRoutine(Transform target, float peakScale, float duration)
|
||||
{
|
||||
if (!originalScales.TryGetValue(target, out Vector3 originalScale))
|
||||
{
|
||||
originalScale = target.localScale;
|
||||
originalScales[target] = originalScale;
|
||||
}
|
||||
|
||||
float half = duration * 0.5f;
|
||||
float timer = 0f;
|
||||
|
||||
while (timer < half)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / half);
|
||||
target.localScale = Vector3.Lerp(originalScale, originalScale * peakScale, EaseOutCubic(t));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
timer = 0f;
|
||||
Vector3 peak = originalScale * peakScale;
|
||||
|
||||
while (timer < half)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / half);
|
||||
target.localScale = Vector3.Lerp(peak, originalScale, EaseOutCubic(t));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
target.localScale = originalScale;
|
||||
runningEffects.Remove(target);
|
||||
}
|
||||
|
||||
public void Shake(RectTransform target, float strength = 12f, float duration = 0.18f)
|
||||
{
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
StopManaged(target);
|
||||
runningEffects[target] = StartCoroutine(ShakeRoutine(target, Mathf.Max(0f, strength), Mathf.Max(0.01f, duration)));
|
||||
}
|
||||
|
||||
private IEnumerator ShakeRoutine(RectTransform target, float strength, float duration)
|
||||
{
|
||||
if (!originalAnchoredPositions.TryGetValue(target, out Vector2 originalPosition))
|
||||
{
|
||||
originalPosition = target.anchoredPosition;
|
||||
originalAnchoredPositions[target] = originalPosition;
|
||||
}
|
||||
|
||||
float timer = 0f;
|
||||
while (timer < duration)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / duration);
|
||||
float power = Mathf.Lerp(strength, 0f, t);
|
||||
Vector2 offset = UnityEngine.Random.insideUnitCircle * power;
|
||||
target.anchoredPosition = originalPosition + offset;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
target.anchoredPosition = originalPosition;
|
||||
runningEffects.Remove(target);
|
||||
}
|
||||
|
||||
public void Flash(Image image, Color color, float maxAlpha = 0.28f, float duration = 0.16f)
|
||||
{
|
||||
if (image == null)
|
||||
return;
|
||||
|
||||
StopManaged(image);
|
||||
runningEffects[image] = StartCoroutine(FlashRoutine(image, color, Mathf.Clamp01(maxAlpha), Mathf.Max(0.01f, duration)));
|
||||
}
|
||||
|
||||
private IEnumerator FlashRoutine(Image image, Color color, float maxAlpha, float duration)
|
||||
{
|
||||
image.gameObject.SetActive(true);
|
||||
image.raycastTarget = false;
|
||||
|
||||
float timer = 0f;
|
||||
while (timer < duration)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / duration);
|
||||
Color current = color;
|
||||
current.a = Mathf.Lerp(maxAlpha, 0f, EaseOutCubic(t));
|
||||
image.color = current;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Color clear = color;
|
||||
clear.a = 0f;
|
||||
image.color = clear;
|
||||
image.gameObject.SetActive(false);
|
||||
runningEffects.Remove(image);
|
||||
}
|
||||
|
||||
public void FillImage(Image image, float targetFill, float duration)
|
||||
{
|
||||
if (image == null)
|
||||
return;
|
||||
|
||||
targetFill = Mathf.Clamp01(targetFill);
|
||||
|
||||
StopManaged(image);
|
||||
runningEffects[image] = StartCoroutine(FillImageRoutine(image, targetFill, Mathf.Max(0f, duration)));
|
||||
}
|
||||
|
||||
private IEnumerator FillImageRoutine(Image image, float targetFill, float duration)
|
||||
{
|
||||
float startFill = image.fillAmount;
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
image.fillAmount = targetFill;
|
||||
}
|
||||
else
|
||||
{
|
||||
float timer = 0f;
|
||||
while (timer < duration)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / duration);
|
||||
image.fillAmount = Mathf.Lerp(startFill, targetFill, EaseOutCubic(t));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
image.fillAmount = targetFill;
|
||||
}
|
||||
|
||||
runningEffects.Remove(image);
|
||||
}
|
||||
|
||||
public void HighlightSlot(Image background, Image icon, Transform slotRoot, Color highlightColor, float duration, float popScale)
|
||||
{
|
||||
Object key = background != null ? background : icon != null ? icon : slotRoot;
|
||||
if (key == null)
|
||||
return;
|
||||
|
||||
StopManaged(key);
|
||||
runningEffects[key] = StartCoroutine(HighlightSlotRoutine(background, icon, slotRoot, highlightColor, Mathf.Max(0.01f, duration), Mathf.Max(1f, popScale), key));
|
||||
}
|
||||
|
||||
private IEnumerator HighlightSlotRoutine(Image background, Image icon, Transform slotRoot, Color highlightColor, float duration, float popScale, Object key)
|
||||
{
|
||||
Color? originalBackground = null;
|
||||
Color? originalIcon = null;
|
||||
Vector3 originalScale = Vector3.one;
|
||||
|
||||
if (background != null)
|
||||
{
|
||||
originalBackground = background.color;
|
||||
Color c = Color.Lerp(background.color, highlightColor, 0.65f);
|
||||
c.a = 1f;
|
||||
background.color = c;
|
||||
}
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
originalIcon = icon.color;
|
||||
Color c = icon.color;
|
||||
c.a = 1f;
|
||||
icon.color = c;
|
||||
}
|
||||
|
||||
if (slotRoot != null)
|
||||
{
|
||||
if (!originalScales.TryGetValue(slotRoot, out originalScale))
|
||||
{
|
||||
originalScale = slotRoot.localScale;
|
||||
originalScales[slotRoot] = originalScale;
|
||||
}
|
||||
}
|
||||
|
||||
float half = duration * 0.5f;
|
||||
float timer = 0f;
|
||||
while (timer < half)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / half);
|
||||
if (slotRoot != null)
|
||||
slotRoot.localScale = Vector3.Lerp(originalScale, originalScale * popScale, EaseOutCubic(t));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
timer = 0f;
|
||||
Vector3 peak = originalScale * popScale;
|
||||
while (timer < half)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(timer / half);
|
||||
|
||||
if (slotRoot != null)
|
||||
slotRoot.localScale = Vector3.Lerp(peak, originalScale, EaseOutCubic(t));
|
||||
|
||||
if (background != null && originalBackground.HasValue)
|
||||
background.color = Color.Lerp(background.color, originalBackground.Value, t);
|
||||
|
||||
if (icon != null && originalIcon.HasValue)
|
||||
icon.color = Color.Lerp(icon.color, originalIcon.Value, t);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (slotRoot != null)
|
||||
slotRoot.localScale = originalScale;
|
||||
|
||||
if (background != null && originalBackground.HasValue)
|
||||
background.color = originalBackground.Value;
|
||||
|
||||
if (icon != null && originalIcon.HasValue)
|
||||
icon.color = originalIcon.Value;
|
||||
|
||||
runningEffects.Remove(key);
|
||||
}
|
||||
|
||||
public void StopAllEffects()
|
||||
{
|
||||
foreach (Coroutine coroutine in runningEffects.Values)
|
||||
{
|
||||
if (coroutine != null)
|
||||
StopCoroutine(coroutine);
|
||||
}
|
||||
|
||||
runningEffects.Clear();
|
||||
|
||||
foreach (KeyValuePair<Transform, Vector3> pair in originalScales)
|
||||
{
|
||||
if (pair.Key != null)
|
||||
pair.Key.localScale = pair.Value;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<RectTransform, Vector2> pair in originalAnchoredPositions)
|
||||
{
|
||||
if (pair.Key != null)
|
||||
pair.Key.anchoredPosition = pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void StopManaged(Object key)
|
||||
{
|
||||
if (key == null)
|
||||
return;
|
||||
|
||||
if (runningEffects.TryGetValue(key, out Coroutine coroutine) && coroutine != null)
|
||||
StopCoroutine(coroutine);
|
||||
|
||||
runningEffects.Remove(key);
|
||||
}
|
||||
|
||||
private float EaseOutCubic(float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
t = 1f - Mathf.Pow(1f - t, 3f);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9b3bfbbd08e39e42b891728dcad3a9c
|
||||
@@ -5,15 +5,22 @@ public class RotateUI : MonoBehaviour
|
||||
[Header("Rotation Settings")]
|
||||
[SerializeField] private float rotateSpeed = 30f;
|
||||
[SerializeField] private bool clockwise = true;
|
||||
[SerializeField] private bool playOnStart = true;
|
||||
[SerializeField] private bool playOnStart = false;
|
||||
|
||||
private bool isRotating;
|
||||
|
||||
public bool IsRotating => isRotating;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
isRotating = playOnStart;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
rotateSpeed = Mathf.Max(0f, rotateSpeed);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isRotating)
|
||||
@@ -39,8 +46,13 @@ public void SetClockwise(bool value)
|
||||
clockwise = value;
|
||||
}
|
||||
|
||||
public void SetRotateSpeed(float value)
|
||||
{
|
||||
rotateSpeed = Mathf.Max(0f, value);
|
||||
}
|
||||
|
||||
public void ResetRotation()
|
||||
{
|
||||
transform.localEulerAngles = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e36e14e60fc40cf41bfd445f80e62535
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b1669e795bdb7b4c88e4376a98347d9
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d57aa12e9412ea74d844438588adc0f5
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9e1c44292c7bdb4da8926e8fc9addd2
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e76bfcda04825f043b3f6c1e6cef400b
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6365c45c31605c745bf1a33e3a1e0791
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d0cced1099954d478056e93dd67e0b4
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b20f3401dfb723541b090e4f3bcf5901
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
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
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 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: 0
|
||||
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
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -40,7 +40,7 @@ Material:
|
||||
- _ZCLIP_ON
|
||||
- _ZWRITE_ON
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_EnableInstancingVariants: 1
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
|
||||
@@ -38,7 +38,7 @@ Material:
|
||||
- _WORLDSPACEUV_ON
|
||||
- _ZCLIP_ON
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_EnableInstancingVariants: 1
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
@@ -185,6 +185,7 @@ Material:
|
||||
- _FoamBubblesSpread: 1
|
||||
- _FoamBubblesStrength: 0.217
|
||||
- _FoamClipping: 0.5
|
||||
- _FoamClippingDynamic: 0
|
||||
- _FoamDistanceOn: 1
|
||||
- _FoamDistortion: 0.34
|
||||
- _FoamOn: 1
|
||||
@@ -238,6 +239,7 @@ Material:
|
||||
- _PlanarReflectionsParams: 0
|
||||
- _PointSpotLightReflectionDistortion: 0.5
|
||||
- _PointSpotLightReflectionExp: 64
|
||||
- _PointSpotLightReflectionSharp: 0
|
||||
- _PointSpotLightReflectionSize: 0
|
||||
- _PointSpotLightReflectionStrength: 10
|
||||
- _QueueOffset: 0
|
||||
@@ -282,6 +284,7 @@ Material:
|
||||
- _SrcBlend: 1
|
||||
- _SunReflectionDistortion: 0.49
|
||||
- _SunReflectionPerturbance: 1
|
||||
- _SunReflectionSharp: 0
|
||||
- _SunReflectionSize: 0.122
|
||||
- _SunReflectionStrength: 0
|
||||
- _Surface: 0
|
||||
@@ -295,6 +298,7 @@ Material:
|
||||
- _TranslucencyReflectionMask: 0
|
||||
- _TranslucencyStrength: 1
|
||||
- _TranslucencyStrengthDirect: 0.05
|
||||
- _UnderwaterReflectionStrength: 0.5
|
||||
- _UnderwaterRefractionOffset: 0.2
|
||||
- _UnderwaterSurfaceSmoothness: 0.8
|
||||
- _VertexColorFoam: 0
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user