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

299 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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);
}
}
}
}