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

299 lines
11 KiB
C#
Raw Normal View History

2024-06-12 15:01:54 +08:00
using Object = UnityEngine.Object;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Framework.Constants;
using Gameplay.Manager;
using UnityEngine;
using System.Linq;
using PhxhSDK;
using System;
namespace Gameplay.Level
{
public class PlankManager : Singlenton<PlankManager>, IInitable, IUpdatable
{
private Dictionary<string, Plank> _planks;
public Dictionary<string, Plank> Planks => _planks;
private Dictionary<Plank, Dictionary<Rigidbody2D, HingeJoint2D>> _plankHingeJoints;
private GameObject _plankRoot;
private LevelData _planksLevelData;
private static readonly string HoleOfPlankPath =
string.Format(Framework.Constants.Constants.ItemPrefabPath, "HoleOfPlank");
public async UniTask PreLoadLevelItem()
{
try
{
var plankIndex = LevelUtils.SortPlankLayer(_planksLevelData.HolesOfPlanksIndex);
var sortLayer = LevelConstants.SortLayer;
for (var i = 0; i < _planksLevelData.planksType.Count; i++)
{
var index = plankIndex[i];
var plankName = LevelUtils.GetPlankName(_planksLevelData.planksType[index],
_planksLevelData.squareType[index]);
var plankPath = string.Format(Framework.Constants.Constants.PlankPrefabPath, plankName);
var myPlank = await AssetManager.Instance.LoadAssetAsync<GameObject>(plankPath);
var pos = LevelUtils.GetPlankPositionInfo(KongManager.Instance.HoleDic,
_planksLevelData.HolesOfPlanksIndex[index], _planksLevelData.planksType[index],
_planksLevelData.squareType[index]);
var tPlank = new Plank
{
Obj = Object.Instantiate(myPlank, pos, myPlank.transform.rotation)
};
tPlank.Obj.name += i;
tPlank.Obj.GetComponent<SpriteRenderer>().sortingOrder = sortLayer++;
tPlank.Init();
InitHingJoint(tPlank);
if (_planks.Keys.Contains(tPlank.Obj.name))
{
DebugUtil.LogError("SamePlank{0}", tPlank.Obj.name);
}
else
{
_planks.Add(tPlank.Obj.name, tPlank);
}
var holeOfPlankSortLayer = sortLayer++;
for (var j = 0; j < _planksLevelData.HolesOfPlanksIndex[index].Count; j++)
{
var myHoleOfPlank = await AssetManager.Instance.LoadAssetAsync<GameObject>(HoleOfPlankPath);
var holeOfPlankIndex = _planksLevelData.HolesOfPlanksIndex[index][j];
if (KongManager.Instance.HoleDic.TryGetValue($"Kong{holeOfPlankIndex}", out var hole))
{
var holeOfPlank = Object.Instantiate(myHoleOfPlank, hole.Obj.transform.position,
myHoleOfPlank.transform.rotation);
holeOfPlank.transform.SetParent(tPlank.Obj.transform);
holeOfPlank.name += j;
holeOfPlank.gameObject.GetComponent<SpriteRenderer>().sortingOrder = holeOfPlankSortLayer;
tPlank.HolesOfPlank.Add(holeOfPlank.name, holeOfPlank);
}
}
tPlank.Obj.transform.SetParent(_plankRoot.transform);
}
}
catch (Exception e)
{
DebugUtil.LogError("PlankMgr PreLoadLevelItem Error: {0}", e);
}
}
public void Init()
{
_plankRoot = GameObject.Find("PlankRoot");
_planks = new Dictionary<string, Plank>();
_plankHingeJoints = new Dictionary<Plank, Dictionary<Rigidbody2D, HingeJoint2D>>();
_planksLevelData = LevelManager.Instance.CurrentLevel.LevelData;
}
private void InitHingJoint(Plank plank)
{
foreach (var hole in plank.CurAffectedHoles.Values)
{
if (hole.LevelThumbtack != null)
{
AddHingJoint2D(plank, hole.LevelThumbtack);
}
}
}
public Plank GetPlank(string plankName)
{
if (_planks.TryGetValue(plankName, out var plank))
{
return plank;
}
return null;
}
public void RemovePlank(string plankName)
{
_planks.Remove(plankName);
}
public void ResumeDetection()
{
foreach (var plank in _planks.Values)
{
plank.StopDetect = false;
}
}
/// <summary>
/// 得到Hole所影响的所有木板
/// </summary>
public List<Plank> FindAffectedPlanks(Kong kong, bool isNeedRecord = false)
{
List<Plank> planks = new List<Plank>();
foreach (var plank in _planks.Values)
{
plank.StopDetect = isNeedRecord;
if (plank.Obj.activeSelf && plank.CurAffectedHoles.Values.Contains(kong))
{
planks.Add(plank);
}
}
return planks;
}
/// <summary>
/// 是否有不完全相交于洞口 (部分遮挡)
/// </summary>
public bool HasPlanksOverlapHole(Kong kong)
{
var result = false;
var planks = FindAffectedPlanks(kong);
foreach (var plank in planks)
{
if (plank.Obj.activeSelf && !LevelUtils.IsCanAddThumbtack(plank, kong))
{
result = true;
}
}
return result;
}
public void ReplaceAnchor(Plank plank, Thumbtack thumbtack)
{
try
{
if (plank == null || plank.Obj == null || thumbtack == null || thumbtack.Obj == null)
{
Debug.LogWarning("PlankManager.ReplaceAnchor: Plank or Thumbtack Obj is null!");
return;
}
var anchor = plank.Obj.transform.InverseTransformPoint(thumbtack.Obj.transform.position);
var hingeJoint2Ds = plank.Obj.GetComponents<HingeJoint2D>();
foreach (var hingeJoint2D in hingeJoint2Ds)
{
if (hingeJoint2D.connectedBody.Equals(thumbtack.Obj.GetComponent<Rigidbody2D>()))
{
hingeJoint2D.anchor = new Vector2(anchor.x, anchor.y);
}
}
}
catch (Exception e)
{
DebugUtil.LogError("PlankManager.ReplaceAnchor Fail. Plank: {0}, Thumbtack: {1}, Error: {2}",
plank?.Obj.name, thumbtack?.Obj.name, e);
}
}
public void AddHingJoint2D(Plank plank, Thumbtack thumbtack)
{
try
{
if (plank == null || plank.Obj == null || thumbtack == null || thumbtack.Obj == null)
{
Debug.LogWarning("PlankManager.AddHingJoint: Plank or Thumbtack Obj is null!");
return;
}
HingeJoint2D hingeJoint2D = plank.Obj.AddComponent<HingeJoint2D>();
var thumbtackRig = thumbtack.Obj.GetComponent<Rigidbody2D>();
hingeJoint2D.connectedBody = thumbtackRig;
var anchor = plank.Obj.transform.InverseTransformPoint(thumbtack.Obj.transform.position);
hingeJoint2D.anchor = new Vector2(anchor.x, anchor.y);
//DebugUtil.Log("{0}木板添加:{1}上的HJ2D", plank.Obj.name, thumbtack.Obj.name);
if (!_plankHingeJoints.TryGetValue(plank, out var hjList))
{
hjList = new Dictionary<Rigidbody2D, HingeJoint2D>();
hjList.Add(thumbtackRig, hingeJoint2D);
_plankHingeJoints.Add(plank, hjList);
}
else
{
_plankHingeJoints[plank].Add(thumbtackRig, hingeJoint2D);
}
}
catch (Exception e)
{
DebugUtil.LogError("PlankManager.AddHingJoint Fail. Plank: {0}, Thumbtack: {1}, Error: {2}",
plank?.Obj.name, thumbtack?.Obj.name, e);
}
}
public void RemoveHingJoint2D(Plank plank, Thumbtack thumbtack)
{
try
{
if (plank == null || plank.Obj == null || thumbtack == null || thumbtack.Obj == null)
{
Debug.LogWarning("PlankManager.RemoveHingJoint: Plank or Thumbtack Obj is null!");
return;
}
if (!_plankHingeJoints.TryGetValue(plank, out var hjDic))
return;
var thumbtackRig = thumbtack.Obj.GetComponent<Rigidbody2D>();
if (hjDic.TryGetValue(thumbtackRig, out var hj2D))
{
LevelManager.Instance.CurUndoState.RemoveH2DjPlanks.Add(plank);
DebugUtil.Log("{0}木板移除:{1}上的HJ2D", plank.Obj.name, thumbtack.Obj.name);
Object.DestroyImmediate(hj2D);
hjDic.Remove(thumbtackRig);
if (hjDic.Count <= 0)
{
plank.Obj.GetComponent<Rigidbody2D>().AddForce(Vector2.right * LevelConstants.AddForce);
}
}
}
catch (Exception e)
{
DebugUtil.LogError("PlankManager.RemoveHingJoint Fail. Plank: {0}, Thumbtack: {1}, Error: {2}",
plank?.Obj.name, thumbtack?.Obj.name, e);
}
}
public void RemoveAllHingJoint2D(Plank plank)
{
if (!_plankHingeJoints.TryGetValue(plank, out var hjDic))
{
DebugUtil.LogError("Error to get hjDic from _plankHingeJoints! Error plank: [ {0} ]", plank.Obj.name);
}
else
{
for (var i = 0; i < hjDic.Count; i++)
{
DebugUtil.LogWarning("销毁:{0}", hjDic.ElementAt(i).Value.connectedBody.name);
Object.DestroyImmediate(hjDic.ElementAt(i).Value);
}
hjDic.Clear();
}
}
public void Release()
{
if (_planks == null) return;
foreach (var plank in _planks)
{
if (plank.Value.Obj)
Object.DestroyImmediate(plank.Value.Obj);
}
_plankHingeJoints.Clear();
_planks.Clear();
}
public void Update(float deltaTime)
{
if (_planks == null) return;
foreach (var plank in _planks.Values)
{
plank.Update(deltaTime);
}
}
}
}