Forest_Client/Forest/Assets/Scripts/Gameplay/Level/KongManager.cs

200 lines
6.8 KiB
C#

using Object = UnityEngine.Object;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Framework.Constants;
using Gameplay.Manager;
using UnityEngine;
using PhxhSDK;
using System;
using TMPro;
namespace Gameplay.Level
{
public class KongManager : Singlenton<KongManager>, IInitable
{
private Dictionary<string, Kong> _holeDic;
public Dictionary<string, Kong> HoleDic => _holeDic;
private List<Vector3> _addedNewHolesPos;
private List<Kong> _addedNewHoles;
private GameObject _kongRoot;
private GameObject _thumbtackRoot;
private GameObject _tThumb;
private GameObject _tHole;
private LevelData _holeLevelData;
private const string HoleOfPlankLayer = "HoleOfPlank";
public async UniTask PreLoadLevelItem()
{
_tThumb = await LoadItem("Thumbtack");
_tHole = await LoadItem("Kong");
try
{
var xPos = LevelUtils.GeneratePositions(_holeLevelData.columnCount, 1);
var yPos = LevelUtils.GeneratePositions(_holeLevelData.rowCount, -1);
_holeDic = new Dictionary<string, Kong>();
for (var y = 0; y < yPos.Count; y++)
{
for (var x = 0; x < xPos.Count; x++)
{
var index = y * xPos.Count + x;
if (_holeLevelData.holesIndex.Contains(index))
{
var myHole = Object.Instantiate(_tHole, _kongRoot.transform);
myHole.name = _tHole.name + index;
myHole.transform.position = new Vector3(xPos[x], yPos[y], 0f);
var hole = new Kong(myHole, index);
if (!_holeLevelData.emptyHoleIndex.Contains(index))
{
var myThumb = Object.Instantiate(_tThumb, _thumbtackRoot.transform);
myThumb.name = _tThumb.name + index;
myThumb.transform.position = new Vector3(xPos[x], yPos[y], 0f);
var thumbtack = new Thumbtack(myThumb);
hole.LevelThumbtack = thumbtack;
}
_holeDic.Add(myHole.name, hole);
}
}
}
_addedNewHolesPos = LevelUtils.GetAdditionalAddedHolesPos(new Vector3(xPos[0], yPos[^1], 0f),
LevelManager.Instance.CurrentLevel.LevelData.columnCount);
}
catch (Exception e)
{
DebugUtil.LogError("HoleManager.PreLoadLevelItem Fail. Error: {0}", e);
}
}
public void Init()
{
_holeLevelData = LevelManager.Instance.CurrentLevel.LevelData;
_kongRoot = GameObject.Find("KongRoot");
_thumbtackRoot = GameObject.Find("ThumbtackRoot");
_addedNewHolesPos = new List<Vector3>();
_addedNewHoles = new List<Kong>();
}
private async UniTask<GameObject> LoadItemPrefab(string itemName)
{
try
{
var path = string.Format(Framework.Constants.Constants.ItemPrefabPath, itemName);
var item = await AssetManager.Instance.LoadAssetAsync<GameObject>(path);
return item;
}
catch (Exception e)
{
DebugUtil.LogError("HoleManager.LoadItemPrefab Fail. ItemName: {0}, Error: {1}", itemName, e);
return null;
}
}
private async UniTask<GameObject> LoadItem(string itemName)
{
GameObject item = null;
item = await LoadItemPrefab(itemName);
if (item == null)
{
item = Resources.Load<GameObject>(itemName);
}
return item;
}
public Kong GetHole(string holeName)
{
if (!_holeDic.TryGetValue(holeName, out Kong hole))
{
DebugUtil.LogError("Error Get hole by name:{0}", holeName);
}
return hole;
}
public Vector3 CanAddNewHole()
{
var newPos = Vector3.zero;
if (_addedNewHolesPos is { Count: > 0 })
newPos = _addedNewHolesPos[0];
return newPos;
}
public void AddNewHole()
{
try
{
if (_addedNewHolesPos is { Count: > 0 })
{
var myHole = Object.Instantiate(_tHole, _kongRoot.transform);
var index = _holeLevelData.rowCount * _holeLevelData.columnCount + _addedNewHoles.Count;
myHole.name = _tHole.name + index;
myHole.transform.position = _addedNewHolesPos[0];
var hole = new Kong(myHole, index);
_holeDic.Add(myHole.name, hole);
_addedNewHoles.Add(hole);
_addedNewHolesPos.RemoveAt(0);
}
}
catch (Exception e)
{
DebugUtil.LogError("HoleManager.AddNewHole Fail. Error: {0}", e);
}
}
/// <summary>
/// Hole是否有和Plank的孔重叠
/// </summary>
public bool IsOverlapHoleOfPlank(Kong kong, Plank plank)
{
var hitColliders = LevelUtils.GetTriggerColliders(kong.Obj, HoleOfPlankLayer);
foreach (var hit in hitColliders)
{
if (plank.HolesOfPlank.TryGetValue(hit.name, out var holeOfPlank))
{
var holeOfPlankCenter = holeOfPlank.transform.position;
var holeCenter = kong.Obj.gameObject;
if (LevelUtils.JudgeContains(holeOfPlankCenter, holeCenter) &&
Vector3.Distance(kong.Obj.transform.position, holeOfPlank.transform.position) <=
LevelConstants.MaxDistance)
{
return true;
}
}
}
return false;
}
public void ShowHoleIndex()
{
foreach (var hole in _holeDic)
{
var text = hole.Value.Obj.transform.Find("Index").gameObject;
text.SetActive(true);
text.GetComponent<TextMeshPro>().text = hole.Key.Substring("Hole".Length);
}
}
public void Release()
{
if (_holeDic == null) return;
foreach (var hole in _holeDic.Values)
{
hole.LevelThumbtack?.Obj.Destroy();
hole.Obj.Destroy();
}
_holeDic.Clear();
}
}
}