299 lines
11 KiB
C#
299 lines
11 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|
||
} |