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);
|
2024-06-26 12:53:46 +08:00
|
|
|
|
//DebugUtil.Log("{0}木板移除:{1}上的HJ2D", plank.Obj.name, thumbtack.Obj.name);
|
2024-06-12 15:01:54 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|