+ 물고기를 잡으면 드랍 가능한 형태의 오브젝트와 아이콘이 생성되게 변경되었습니다.
+ 플레이어(배)와 아이콘의 위치가 가까워지면 플레이어는 아이콘을 흡수하면서 아이템을 얻게됩니다.
+ 아이템 획득 시에 효과음을 추가하였습니다.
+ 아이템 획득 시에 좌측 중단에 UI를 통해서 어떠한 아이템을 얻었는지 확인할 수 있게 표시합니다.
+ 물고기 스팟 이펙트를 2가지 합치는 방식으로 변경하였습니다.
+ 물고기 스팟을 기준으로 플레이어와의 거리를 체크해 물고기 스팟이 도망치는 방식으로 변경되었습니다. (기존에는 Bound의 중심)
+ 물고기 스팟의 크기를 원하는 크기로 변경할 수 있도록 변경했습니다.
+ 인터페이스 IItem을 추가하였습니다.
+ Item,FishItem 로직을 변경했습니다.
This commit is contained in:
NTG 2024-01-22 02:42:31 +09:00
parent 33bf76d018
commit 03dd793340
39 changed files with 4798 additions and 562 deletions

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@ namespace BlueWaterProject
public class Boid : MonoBehaviour
{
[field: Title("FishInfo")]
[field: SerializeField] public FishInfo FishInfo { get; private set; }
[field: SerializeField] public FishItem FishItem { get; private set; }
[field: SerializeField] public Vector2 RandomCount { get; private set; } = new(1, 4);
[Title("개체 설정")]
@ -42,7 +42,7 @@ namespace BlueWaterProject
myBoids = boids;
moveSpeed = speed;
hitColliders = new Collider[maxNeighbourCount];
FishInfo.AddCount(Random.Range((int)RandomCount.x, (int)RandomCount.y));
FishItem.ItemCount = Random.Range((int)RandomCount.x, (int)RandomCount.y);
findNeighbourCoroutine ??= StartCoroutine("FindNeighbourCoroutine");
calculateEgoVectorCoroutine ??= StartCoroutine("CalculateEgoVectorCoroutine");

View File

@ -123,14 +123,14 @@ namespace BlueWaterProject
[ShowIf("@showWaterEffect")]
[SerializeField] private Vector3 fishSpotOffset = new(0, 0.5f, 0);
[field: SerializeField] public MeshRenderer BoundMeshRenderer { get; private set; }
// 디버깅
[Title("디버깅")]
[SerializeField] private List<Boid> boidList;
[SerializeField] private Collider[] hitColliders = new Collider[MAX_HIT_NUM];
[SerializeField] private LayerMask targetLayer;
[SerializeField] private LayerMask waterLayer;
public MeshRenderer BoundMeshRenderer { get; private set; }
private Vector3 spawnPos;
private Coroutine findTargetCoroutine;
@ -152,9 +152,23 @@ namespace BlueWaterProject
private void OnDrawGizmosSelected()
{
if (!isDrawGizmos) return;
var centerPos = Vector3.zero;
if (Application.isPlaying)
{
centerPos = fishSpot.position;
}
else
{
if (Physics.Raycast(BoundMeshRenderer.transform.position, Vector3.up, out var hit,
float.MaxValue,waterLayer))
{
centerPos = hit.point + fishSpotOffset;
}
}
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, viewRadius);
Gizmos.DrawWireSphere(centerPos, viewRadius);
}
private void Start()
@ -201,7 +215,7 @@ namespace BlueWaterProject
{
while (true)
{
var size = Physics.OverlapSphereNonAlloc(transform.position, viewRadius, hitColliders, targetLayer);
var size = Physics.OverlapSphereNonAlloc(fishSpot.position, viewRadius, hitColliders, targetLayer);
for (var i = 0; i < size; i++)
{
if (hitColliders[i] == null || !hitColliders[i].CompareTag("ShipPlayer")) continue;
@ -288,14 +302,23 @@ namespace BlueWaterProject
return rotation * escapeDirection;
}
public void CatchBoid(int count)
public void CatchBoid(Collider hitCollider, int count)
{
count = Mathf.Min(count, boidList.Count);
for (var i = 0; i < count; i++)
{
// 물고기 잡히는 이펙트 효과 추가
var currentBoid = boidList[0];
DataManager.Inst.PlayerInventory.AddFish(currentBoid.FishInfo.Name, currentBoid.FishInfo.Count);
var bounds = hitCollider.bounds;
var x = Random.Range(bounds.min.x, bounds.max.x);
//var y = Random.Range(bounds.min.y, bounds.max.y);
var z = Random.Range(bounds.min.z, bounds.max.z);
var randomPos = new Vector3(x, 0, z);
var catchItem = new FishItem(currentBoid.FishItem.ItemName, currentBoid.FishItem.ItemCount);
ItemDropManager.Inst.DropItem(catchItem, randomPos);
boidList.RemoveAt(0);
Destroy(currentBoid.gameObject);
}
@ -308,5 +331,7 @@ namespace BlueWaterProject
}
gameObject.SetActive(false);
}
public FishItem GetBoidInfo() => boidPrefab.FishItem;
}
}

View File

@ -1,315 +0,0 @@
using System;
using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class Fish : MonoBehaviour
{
// 초기화 방식
[Title("초기화 방식")]
[SerializeField] private bool autoInit = true;
// 물고기의 기본 설정
[Title("물고기의 기본 설정")]
[SerializeField] private bool isDrawGizmos = true;
[Tooltip("타겟 인식 범위")]
[SerializeField] private float viewRadius = 10f;
[Tooltip("이동속도")]
[SerializeField] private float moveSpd = 500f;
[Tooltip("회전속도")]
[SerializeField] private float rotationSpeed = 10f;
[Tooltip("랜덤 방향으로 도주 여부")]
[SerializeField] private bool isRandomAngle = true;
[ShowIf("@isRandomAngle")]
[Tooltip("도망가는 방향의 랜덤 각도")]
[SerializeField] private float randomAngle = 180f;
[Tooltip("타겟을 재검색하는 시간")]
[SerializeField] private float rescanTime = 0.5f;
[Tooltip("도망가는 시간")]
[SerializeField] private float escapeTime = 10f;
[Tooltip("리스폰 여부")]
[SerializeField] private bool isRespawn = true;
[ShowIf("@isRespawn == true")]
[Tooltip("리스폰되는데 걸리는 시간")]
[SerializeField] private float respawnTime = 5f;
[Tooltip("도망치면서 랜덤 방향 전환 여부")]
[SerializeField] private bool randomDirectionChange;
[ShowIf("@!randomDirectionChange")]
[Tooltip("도망치면서 방향 전환하는데 걸리는 시간")]
[SerializeField] private float directionChangeInterval = 1f;
[ShowIf("@randomDirectionChange")]
[Tooltip("도망치면서 방향 전환하는데 걸리는 랜덤 최소 시간")]
[SerializeField] private float minDirectionChangeInterval = 0.1f;
[ShowIf("@randomDirectionChange")]
[Tooltip("도망치면서 방향 전환하는데 걸리는 랜덤 최대 시간")]
[SerializeField] private float maxDirectionChangeInterval = 1f;
[Tooltip("도주 방식")]
[SerializeField] private EscapeMode escapeMode = EscapeMode.STRAIGHT;
// ZIGZAG
[Title("ZIGZAG")]
[ShowIf("@escapeMode == EscapeMode.ZIGZAG")]
[Tooltip("흔들림의 정도")]
[SerializeField] private bool randomZigzag;
[ShowIf("@escapeMode == EscapeMode.ZIGZAG && !randomZigzag")]
[Tooltip("흔들림의 정도")]
[SerializeField] private float zigzagAmplitude = 1f;
[ShowIf("@escapeMode == EscapeMode.ZIGZAG && !randomZigzag")]
[Tooltip("흔들림의 주기")]
[SerializeField] private float zigzagFrequency = 1f;
[ShowIf("@escapeMode == EscapeMode.ZIGZAG && randomZigzag")]
[Tooltip("흔들림의 정도 랜덤 최솟값")]
[SerializeField] private float minZigzagAmplitude = 0.1f;
[ShowIf("@escapeMode == EscapeMode.ZIGZAG && randomZigzag")]
[Tooltip("흔들림의 정도 랜덤 최댓값")]
[SerializeField] private float maxZigzagAmplitude = 1f;
[Space]
[ShowIf("@escapeMode == EscapeMode.ZIGZAG && randomZigzag")]
[Tooltip("흔들림의 주기 랜덤 최솟값")]
[SerializeField] private float minZigzagFrequency = 0.1f;
[ShowIf("@escapeMode == EscapeMode.ZIGZAG && randomZigzag")]
[Tooltip("흔들림의 주기 랜덤 최댓값")]
[SerializeField] private float maxZigzagFrequency = 1f;
// 디버깅
[Title("디버깅")]
[SerializeField] private Collider[] hitColliders = new Collider[MAX_HIT_NUM];
[SerializeField] private LayerMask targetLayer;
private Rigidbody rb;
private Coroutine findTargetCoroutine;
private Coroutine escapeCoroutine;
private WaitForSeconds findCoroutineTime;
private Vector3 spawnPos;
private const int MAX_HIT_NUM = 3;
private void OnValidate()
{
findCoroutineTime = new WaitForSeconds(rescanTime);
}
private void OnDrawGizmosSelected()
{
if (!isDrawGizmos) return;
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, viewRadius);
}
[Button("셋팅 초기화")]
private void Init()
{
rb = GetComponent<Rigidbody>();
targetLayer = LayerMask.GetMask("Player");
}
#region Preset
[HorizontalGroup("Split")]
[Button("프리셋 1번")]
private void Preset1()
{
isDrawGizmos = true;
viewRadius = 20f;
moveSpd = 500f;
rotationSpeed = 10f;
isRandomAngle = false;
rescanTime = 0.5f;
escapeTime = 10f;
isRespawn = true;
respawnTime = 5f;
randomDirectionChange = false;
directionChangeInterval = 3f;
escapeMode = EscapeMode.STRAIGHT;
}
[HorizontalGroup("Split")]
[Button("프리셋 2번")]
private void Preset2()
{
isDrawGizmos = true;
viewRadius = 20f;
moveSpd = 500f;
rotationSpeed = 10f;
isRandomAngle = true;
randomAngle = 120f;
rescanTime = 0.5f;
escapeTime = 10f;
isRespawn = true;
respawnTime = 5f;
randomDirectionChange = true;
minDirectionChangeInterval = 1f;
maxDirectionChangeInterval = 3f;
directionChangeInterval = 3f;
escapeMode = EscapeMode.ZIGZAG;
randomZigzag = false;
zigzagAmplitude = 0.5f;
zigzagFrequency = 1f;
}
[HorizontalGroup("Split")]
[Button("프리셋 3번")]
private void Preset3()
{
isDrawGizmos = true;
viewRadius = 20f;
moveSpd = 500f;
rotationSpeed = 10f;
isRandomAngle = true;
randomAngle = 120f;
rescanTime = 0.5f;
escapeTime = 10f;
isRespawn = true;
respawnTime = 5f;
randomDirectionChange = true;
minDirectionChangeInterval = 1f;
maxDirectionChangeInterval = 3f;
directionChangeInterval = 3f;
escapeMode = EscapeMode.ZIGZAG;
randomZigzag = true;
minZigzagAmplitude = 0.1f;
maxZigzagAmplitude = 2f;
minZigzagFrequency = 0.1f;
maxZigzagFrequency = 2f;
}
#endregion
private void Awake()
{
if (autoInit)
{
Init();
}
}
private void OnEnable()
{
hitColliders = new Collider[MAX_HIT_NUM];
findCoroutineTime = new WaitForSeconds(rescanTime);
if (findTargetCoroutine != null) return;
findTargetCoroutine = StartCoroutine(FindTargetCoroutine());
}
private void Start()
{
spawnPos = transform.position;
}
private IEnumerator FindTargetCoroutine()
{
while (true)
{
var size = Physics.OverlapSphereNonAlloc(transform.position, viewRadius, hitColliders, targetLayer);
for (var i = 0; i < size; i++)
{
var hitCollider = hitColliders[i];
if (hitCollider == null || !hitCollider.CompareTag("ShipPlayer")) continue;
findTargetCoroutine = null;
escapeCoroutine = StartCoroutine(EscapeCoroutine(hitCollider));
yield break;
}
yield return findCoroutineTime;
}
}
private IEnumerator EscapeCoroutine(Collider targetCollider)
{
var currentDirectionChangeInterval = randomDirectionChange ?
UnityEngine.Random.Range(minDirectionChangeInterval, maxDirectionChangeInterval)
: directionChangeInterval;
var rotatedEscapeDirection = CalculateEscapeDirection(targetCollider.transform.position);
var time = 0f;
var directionChangeTime = 0f;
while (time < escapeTime)
{
time += Time.deltaTime;
directionChangeTime += Time.deltaTime;
if (directionChangeTime >= currentDirectionChangeInterval)
{
rotatedEscapeDirection = CalculateEscapeDirection(targetCollider.transform.position);
directionChangeTime = 0f;
currentDirectionChangeInterval = randomDirectionChange ?
UnityEngine.Random.Range(minDirectionChangeInterval, maxDirectionChangeInterval)
: directionChangeInterval;
if (escapeMode == EscapeMode.ZIGZAG && randomZigzag)
{
zigzagFrequency = UnityEngine.Random.Range(minZigzagFrequency, maxZigzagFrequency);
zigzagAmplitude = UnityEngine.Random.Range(minZigzagAmplitude, maxZigzagAmplitude);
}
}
var newDirection = escapeMode switch
{
EscapeMode.NONE => throw new ArgumentOutOfRangeException(),
EscapeMode.STRAIGHT => rotatedEscapeDirection,
EscapeMode.ZIGZAG => rotatedEscapeDirection +
new Vector3(Mathf.Sin(Time.time * zigzagFrequency) * zigzagAmplitude,0,
Mathf.Sin(Time.time * zigzagFrequency) * zigzagAmplitude),
EscapeMode.TOWARDS => -rotatedEscapeDirection,
_ => throw new ArgumentOutOfRangeException()
};
rb.velocity = newDirection.normalized * (moveSpd * Time.deltaTime);
var targetRotation = Quaternion.LookRotation(newDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
yield return null;
}
rb.velocity = Vector3.zero;
escapeCoroutine = null;
if (isRespawn)
{
//FishManager.Inst.RespawnFish(gameObject, respawnTime, spawnPos);
}
gameObject.SetActive(false);
}
private Vector3 CalculateEscapeDirection(Vector3 targetPos)
{
var escapeDirection = (transform.position - targetPos).normalized;
escapeDirection.y = 0;
if (!isRandomAngle) return escapeDirection;
var randomRotationAngle = UnityEngine.Random.Range(-randomAngle * 0.5f, randomAngle * 0.5f);
var rotation = Quaternion.Euler(0, randomRotationAngle, 0);
return rotation * escapeDirection;
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class FishInfo
{
[field: SerializeField] public string Name { get; private set; }
[field: SerializeField] public int Count { get; private set; }
public FishInfo(string name, int count)
{
Name = name;
Count = count;
}
public void AddCount(int? value = null)
{
if (value == null)
{
Count++;
}
else
{
Count += (int)value;
}
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class FishItem : Item
{
public FishItem(string name, int count = 1, Sprite icon = null) : base(name, count, icon)
{
ItemName = name;
ItemCount = count;
ItemIcon = icon;
}
}
}

View File

@ -0,0 +1,13 @@
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public interface IItem
{
string ItemName { get; set; }
int ItemCount { get; set; }
Sprite ItemIcon { get; set; }
void Acquire();
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a0f3e1c9930c204498f3a86452337290
guid: 895973422f0e42c4fb1a58e8df2d3505
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f3d65a23d1368484caef68ab14191563
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class DropItemGroupController : MonoBehaviour
{
[field: SerializeField] public List<DropItemInfoUi> dropItemInfoUiList = new(3);
private WaitForSeconds coroutineRestartTime = new(0.5f);
public void ShowDropItemInfoUi(IItem iItem)
{
StartCoroutine(ShowDropItemInfoUiCoroutine(iItem));
}
private IEnumerator ShowDropItemInfoUiCoroutine(IItem iItem)
{
while (true)
{
foreach (var list in dropItemInfoUiList)
{
if (list.UiView.gameObject.activeSelf) continue;
var itemText = iItem.ItemName + " x" + iItem.ItemCount;
list.SetInfo(iItem.ItemIcon, itemText);
list.ShowUi();
while (list.UiView.gameObject.activeSelf)
{
yield return null;
}
yield break;
}
yield return coroutineRestartTime;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3eee56b795537aa4aab4e0afcdd738e5

View File

@ -0,0 +1,31 @@
using Doozy.Runtime.UIManager.Containers;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class DropItemInfoUi : MonoBehaviour
{
[field: SerializeField] public UIView UiView { get; set; }
[field: SerializeField] public Image ItemIcon { get; set; }
[field: SerializeField] public TMP_Text ItemText { get; set; }
public void SetInfo(Sprite icon, string text)
{
ItemIcon.sprite = icon;
ItemText.text = text;
}
public void ShowUi()
{
UiView.Show();
}
public void HideUi()
{
UiView.Hide();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 38ce10e1036560e4789b9a24e540ef5b

View File

@ -0,0 +1,26 @@
using System;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class Item : IItem
{
[field: SerializeField] public string ItemName { get; set; }
[field: SerializeField] public int ItemCount { get; set; }
[field: SerializeField] public Sprite ItemIcon { get; set; }
public Item(string name, int count = 1, Sprite icon = null)
{
ItemName = name;
ItemCount = count;
ItemIcon = icon;
}
public void Acquire()
{
DataManager.Inst.PlayerInventory.AddItem(this);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6ed42387fa88b3b4d9ee7d94750f3dd5

View File

@ -0,0 +1,114 @@
using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class ItemController : MonoBehaviour
{
[Title("아이템")]
[SerializeField] private Item item;
[SerializeField] private ItemUiController itemUiPrefab;
[Title("자동 파괴")]
[SerializeField] private bool useAutoDestroy = true;
[ShowIf("@useAutoDestroy")]
[SerializeField] private float autoDestroyTime = 30f;
[Title("획득")]
[SerializeField] private bool drawGizmos = true;
[SerializeField] private float radius = 5f;
[SerializeField] private float acquisitionTime = 1f;
[SerializeField] private LayerMask targetLayer;
private Collider[] hitColliders = new Collider[1];
private Collider targetCollider;
private WaitForSeconds lootCoroutineTime = new(0.5f);
private AudioSource audioSource;
private Transform itemsLoot;
private ItemUiController itemLootUi;
private void OnDrawGizmosSelected()
{
if (!drawGizmos) return;
Gizmos.DrawWireSphere(transform.position, radius);
}
public void Init(Item newItem)
{
item = newItem;
if (!itemsLoot)
{
itemsLoot = UiManager.Inst.OceanUi.MainCanvas.transform.Find("ItemsLoot");
}
var myPos = transform.position;
var screenPos = CameraManager.Inst.MainCam.WorldToScreenPoint(myPos);
itemLootUi = Instantiate(itemUiPrefab, screenPos, Quaternion.identity, itemsLoot);
itemLootUi.Init(transform);
}
private void Awake()
{
audioSource = transform.parent.Find("Audio").GetComponent<AudioSource>();
itemsLoot = UiManager.Inst.OceanUi.MainCanvas.transform.Find("ItemsLoot");
}
private void Start()
{
if (useAutoDestroy)
{
Destroy(transform.parent.gameObject, autoDestroyTime);
Destroy(itemLootUi.gameObject, autoDestroyTime);
}
StartCoroutine(LootCoroutine());
}
private IEnumerator LootCoroutine()
{
while (true)
{
var maxSize = Physics.OverlapSphereNonAlloc(transform.position, radius, hitColliders, targetLayer);
if (maxSize > 0)
{
targetCollider = hitColliders[0];
itemLootUi.ItemAcquisition();
break;
}
yield return lootCoroutineTime;
}
var startPosition = transform.position;
var elapsedTime = 0f;
while (elapsedTime < acquisitionTime)
{
elapsedTime += Time.deltaTime;
var t = elapsedTime / acquisitionTime;
t = Mathf.SmoothStep(0f, 1f, t);
transform.position = Vector3.Lerp(startPosition, targetCollider.transform.position, t);
yield return null;
}
item.Acquire();
itemLootUi.gameObject.SetActive(false);
UiManager.Inst.OceanUi.DropItemGroupController.ShowDropItemInfoUi(item);
if (audioSource && audioSource.resource)
{
audioSource.Play();
}
yield return new WaitForSeconds(audioSource.clip.length);
Destroy(transform.parent.gameObject);
Destroy(itemLootUi.gameObject);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c3ea0c13f4edde747b6d5eb5d6842905

View File

@ -0,0 +1,40 @@
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class ItemDropManager : Singleton<ItemDropManager>
{
[Title("초기화 방식")]
[SerializeField] private bool autoInit = true;
[field: Title("아이템")]
[field: SerializeField] public GameObject ItemPrefab { get; private set; }
[SerializeField] private Transform instantiateObjects;
[SerializeField] private Transform items;
[Button("셋팅 초기화")]
private void Init()
{
instantiateObjects = GameObject.Find("InstantiateObjects").transform;
items = instantiateObjects.transform.Find("Items");
}
protected override void OnAwake()
{
base.OnAwake();
if (autoInit)
{
Init();
}
}
public void DropItem(Item item, Vector3 dropPosition)
{
var itemController = Instantiate(ItemPrefab, dropPosition, Quaternion.identity, items).GetComponentInChildren<ItemController>();
itemController.Init(item);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bb206c5a6ef8a5c4699d0abf67531d7d

View File

@ -1,27 +1,21 @@
using System;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UI;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class ItemLootUi : MonoBehaviour
public class ItemUiController : MonoBehaviour
{
[SerializeField] private RectTransform rectTransform;
[SerializeField] private Image border;
[SerializeField] private Image icon;
[SerializeField] private RectTransform line;
[SerializeField] private bool useAutoDestroy = true;
[ShowIf("@useAutoDestroy")]
[SerializeField] private float autoDestroyTime = 10f;
private Vector3 lootWorldPos;
private Transform targetTransform;
public void Init(Vector3 value, Sprite sprite = null)
public void Init(Transform target, Sprite sprite = null)
{
lootWorldPos = value;
targetTransform = target;
if (sprite)
{
icon.sprite = sprite;
@ -29,17 +23,17 @@ namespace BlueWaterProject
gameObject.SetActive(true);
}
private void Start()
{
if (useAutoDestroy)
{
Destroy(gameObject, autoDestroyTime);
}
}
private void Update()
{
rectTransform.position = CameraManager.Inst.MainCam.WorldToScreenPoint(lootWorldPos);
rectTransform.position = CameraManager.Inst.MainCam.WorldToScreenPoint(targetTransform.position);
}
public void ItemAcquisition()
{
if (line)
{
line.gameObject.SetActive(false);
}
}
}
}

View File

@ -17,39 +17,35 @@ namespace BlueWaterProject
[field: SerializeField] public Slider ShipBoostSlider { get; set; }
[field: SerializeField] public GameObject SpeedLines { get; set; }
[field: SerializeField] public DropItemGroupController DropItemGroupController { get; set; }
[field: SerializeField] public ItemLootUi ItemLootUi { get; set; }
[SerializeField] private Vector2 itemLootOffset;
private Canvas canvas;
private RectTransform canvasRectTransform;
private Transform itemsLoot;
public Canvas MainCanvas { get; private set; }
[Button("셋팅 초기화")]
private void Init()
{
canvas = GetComponent<Canvas>();
if (!canvas)
MainCanvas = GetComponent<Canvas>();
if (!MainCanvas)
{
Debug.LogError("canvas is null error");
return;
}
canvasRectTransform = canvas.GetComponent<RectTransform>();
var processBar = canvas.transform.Find("ProcessBar").gameObject;
var processBar = MainCanvas.transform.Find("ProcessBar").gameObject;
var fill = processBar.transform.Find("Fill").GetComponent<Image>();
var previousGaugeLine = processBar.transform.Find("PreviousGaugeLine").transform;
var reloadSlider = canvas.transform.Find("ReloadSlider").GetComponent<Slider>();
var reloadSlider = MainCanvas.transform.Find("ReloadSlider").GetComponent<Slider>();
ProcessBar = new ProcessBar(processBar, fill, previousGaugeLine, reloadSlider);
ProcessBar.SetActiveReloadSlider(false);
ShipBoostSlider = canvas.transform.Find("ShipBoostSlider").GetComponent<Slider>();
ShipBoostSlider = MainCanvas.transform.Find("ShipBoostSlider").GetComponent<Slider>();
ShipBoostSlider.value = 0f;
SpeedLines = canvas.transform.Find("SpeedLines").gameObject;
SpeedLines = MainCanvas.transform.Find("SpeedLines").gameObject;
SpeedLines.SetActive(false);
itemsLoot = canvas.transform.Find("ItemsLoot");
DropItemGroupController = MainCanvas.transform.Find("DropItemGroup").GetComponent<DropItemGroupController>();
}
private void Awake()
@ -72,13 +68,6 @@ namespace BlueWaterProject
ProcessBar.SetPosition(result);
}
}
public void CreateItemLootUi(Vector3 lootPos, Sprite sprite = null)
{
var screenPos = CameraManager.Inst.MainCam.WorldToScreenPoint(lootPos);
var itemLootUi = Instantiate(ItemLootUi, screenPos, Quaternion.identity, itemsLoot);
itemLootUi.Init(lootPos);
}
public void SetActiveSpeedLine(bool value) => SpeedLines.SetActive(value);
}

View File

@ -69,18 +69,7 @@ namespace BlueWaterProject
{
var hitBoids = hitColliders[i].GetComponentInParent<Boids>();
var catchSize = Random.Range((int)randomCatch.x, (int)randomCatch.y);
hitBoids.CatchBoid(catchSize);
for (var j = 0; j < catchSize; j++)
{
var bounds = hitColliders[i].bounds;
var x = Random.Range(bounds.min.x, bounds.max.x);
//var y = Random.Range(bounds.min.y, bounds.max.y);
var z = Random.Range(bounds.min.z, bounds.max.z);
var randomPos = new Vector3(x, 0, z);
UiManager.Inst.OceanUi.CreateItemLootUi(randomPos);
}
hitBoids.CatchBoid(hitColliders[i], catchSize);
}
}
else

View File

@ -8,26 +8,20 @@ namespace BlueWaterProject
[Serializable]
public class PlayerInventory
{
[SerializeField] private List<FishInfo> fishInfoList = new();
[SerializeField] private List<Item> items = new();
public void AddFish(string name, int? count = null)
public void AddItem(IItem item)
{
var existingFish = fishInfoList.Find(fish => fish.Name == name);
if (existingFish != null)
var existingItem = items.Find(i => i.ItemName == item.ItemName);
if (existingItem != null)
{
existingFish.AddCount(count);
existingItem.ItemCount += item.ItemCount;
}
else
{
fishInfoList.Add(new FishInfo(name, 1));
items.Add(new Item(item.ItemName, item.ItemCount));
}
}
public int GetFishCount(string name)
{
var fish = fishInfoList.Find(f => f.Name == name);
return fish?.Count ?? 0;
}
}
}

View File

@ -1,11 +1,14 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class ProcessBar : MonoBehaviour
[Serializable]
public class ProcessBar
{
[field: SerializeField] public GameObject Obj { get; set; }
[field: SerializeField] public Image Fill { get; set; }

View File

@ -158,7 +158,8 @@ MonoBehaviour:
showBounds: 1
fishSpot: {fileID: 6023135201199208214}
showWaterEffect: 1
fishSpotOffset: {x: 0, y: 0.5, z: 0}
fishSpotOffset: {x: 0, y: 0.3, z: 0}
<BoundMeshRenderer>k__BackingField: {fileID: 2486807546603369919}
boidList: []
hitColliders:
- {fileID: 0}

View File

@ -134,9 +134,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b5a4bdb4c510d354687a785c3f642878, type: 3}
m_Name:
m_EditorClassIdentifier:
<FishInfo>k__BackingField:
<Name>k__BackingField: "\uB9DD\uCE58\uBA38\uB9AC\uC0C1\uC5B4"
<Count>k__BackingField: 0
<FishItem>k__BackingField:
<ItemName>k__BackingField: "\uB9DD\uCE58\uBA38\uB9AC\uC0C1\uC5B4"
<ItemCount>k__BackingField: 0
<ItemIcon>k__BackingField: {fileID: 0}
<RandomCount>k__BackingField: {x: 10, y: 1}
obstacleDistance: 10
viewAngle: 120

View File

@ -46,9 +46,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b5a4bdb4c510d354687a785c3f642878, type: 3}
m_Name:
m_EditorClassIdentifier:
<FishInfo>k__BackingField:
<Name>k__BackingField: "\uACE0\uB4F1\uC5B4"
<Count>k__BackingField: 0
<FishItem>k__BackingField:
<ItemName>k__BackingField: "\uACE0\uB4F1\uC5B4"
<ItemCount>k__BackingField: 0
<ItemIcon>k__BackingField: {fileID: 0}
<RandomCount>k__BackingField: {x: 1, y: 4}
obstacleDistance: 10
viewAngle: 120

View File

@ -46,9 +46,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b5a4bdb4c510d354687a785c3f642878, type: 3}
m_Name:
m_EditorClassIdentifier:
<FishInfo>k__BackingField:
<Name>k__BackingField: "\uAC00\uC624\uB9AC"
<Count>k__BackingField: 0
<FishItem>k__BackingField:
<ItemName>k__BackingField: "\uAC00\uC624\uB9AC"
<ItemCount>k__BackingField: 0
<ItemIcon>k__BackingField: {fileID: 0}
<RandomCount>k__BackingField: {x: 5, y: 7}
obstacleDistance: 10
viewAngle: 120

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6ab1c52e106d85344b5b9ad6e4857b0e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 46de620c604c02449b960aaea6682273
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,222 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1733947209264972765
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6499268732264954890}
- component: {fileID: 8975262077732393561}
m_Layer: 0
m_Name: Audio
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6499268732264954890
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1733947209264972765}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 726335702565593345}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!82 &8975262077732393561
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1733947209264972765}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 8300000, guid: de54536a55703434b8ad53b9a7da3d35, type: 3}
m_Resource: {fileID: 8300000, guid: de54536a55703434b8ad53b9a7da3d35, type: 3}
m_PlayOnAwake: 0
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!1 &4185765918994780331
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 726335702565593345}
m_Layer: 0
m_Name: FishItemDrop
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &726335702565593345
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4185765918994780331}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 816226554442943762}
- {fileID: 6499268732264954890}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &7996128800962867104
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 816226554442943762}
- component: {fileID: 9212167707718790757}
m_Layer: 21
m_Name: ItemController
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &816226554442943762
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7996128800962867104}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 726335702565593345}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9212167707718790757
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7996128800962867104}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c3ea0c13f4edde747b6d5eb5d6842905, type: 3}
m_Name:
m_EditorClassIdentifier:
item:
<ItemName>k__BackingField:
<ItemCount>k__BackingField: 0
<ItemIcon>k__BackingField: {fileID: 0}
itemUiPrefab: {fileID: 630240011905187802, guid: 0d213e978cd398441bcd61573163ca16,
type: 3}
useAutoDestroy: 1
autoDestroyTime: 30
drawGizmos: 1
radius: 15
acquisitionTime: 1.5
targetLayer:
serializedVersion: 2
m_Bits: 512

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3e821daa41aac7d47b39f8cfebac29d0
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -35,7 +35,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -60, y: -60}
m_SizeDelta: {x: -40, y: -40}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6178358912228675412
CanvasRenderer:
@ -268,12 +268,9 @@ GameObject:
- component: {fileID: 3090447943159425445}
- component: {fileID: 3090447943159425443}
- component: {fileID: 3090447943159425442}
- component: {fileID: 3090447943159425446}
- component: {fileID: 7030230213418535633}
- component: {fileID: 7380289147853920374}
- component: {fileID: 8464029479315233580}
- component: {fileID: 630240011905187802}
m_Layer: 5
m_Name: ItemLootUi
m_Name: ItemUiController
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -323,7 +320,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 0.5019608, b: 0, a: 0.19607843}
m_RaycastTarget: 1
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
@ -339,78 +336,7 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &3090447943159425446
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3090447943159425444}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ad63971631c874d1aa33146b8079b8a5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 3090447943159425442}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!114 &7030230213418535633
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3090447943159425444}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 684da8d3856b6400ca0468d3888c5374, type: 3}
m_Name:
m_EditorClassIdentifier:
fadeTime: 0.2
onHoverAlpha: 0.6
onClickAlpha: 0.7
--- !u!225 &7380289147853920374
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3090447943159425444}
m_Enabled: 1
m_Alpha: 1
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!114 &8464029479315233580
--- !u!114 &630240011905187802
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: de54536a55703434b8ad53b9a7da3d35
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 1
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant: