menu
This commit is contained in:
@@ -29,6 +29,16 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
return new FullScreenNearTimeJudgeUnit_BM();
|
||||
}
|
||||
|
||||
public override bool CheckJudgeAvailability(InputUnit inputUnit)
|
||||
{
|
||||
if (inputUnit is InputUnitSwipe swipe && note is Flick flick)
|
||||
{
|
||||
return flick.CheckSwipeDirection(swipe);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
|
||||
@@ -7,10 +7,14 @@ namespace Ichni.RhythmGame
|
||||
public class TouchAreaJudgeUnit : NoteJudgeUnit
|
||||
{
|
||||
public float areaRadius;
|
||||
protected override GameObject GetHintImagePrefab() => GameManager.instance.basePrefabs.areaHint;
|
||||
|
||||
protected override GameObject GetHintImagePrefab()
|
||||
{
|
||||
return GameManager.instance.basePrefabs.areaHint;
|
||||
}
|
||||
|
||||
private float CurrentScreenRatio() => Screen.width / 1920f;
|
||||
|
||||
|
||||
public TouchAreaJudgeUnit(NoteBase note, float areaRadius) : base(note)
|
||||
{
|
||||
this.areaRadius = areaRadius;
|
||||
@@ -18,7 +22,7 @@ namespace Ichni.RhythmGame
|
||||
|
||||
public override void UpdateJudge()
|
||||
{
|
||||
if(note.isFirstJudged) return;
|
||||
if (note.isFirstJudged) return;
|
||||
Vector2 noteScreenPosition = note.noteScreenPosition;
|
||||
RectTransform canvasRect = GameManager.instance.judgeHintCanvas.GetComponent<RectTransform>();
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, noteScreenPosition, null, out Vector2 uiPosition))
|
||||
@@ -37,21 +41,26 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
Vector2 inputScreenPosition = inputUnit.inputPosition;
|
||||
Vector2 noteScreenPosition = note.noteScreenPosition;
|
||||
|
||||
|
||||
float distance = Vector2.Distance(inputScreenPosition, noteScreenPosition);
|
||||
|
||||
//Debug.Log("Input Position: " + inputScreenPosition + ", Note Position: " + noteScreenPosition + ", Distance: " + distance);
|
||||
|
||||
if (distance <= areaRadius * CurrentScreenRatio())
|
||||
|
||||
|
||||
if (distance <= areaRadius)
|
||||
{
|
||||
if (inputUnit is InputUnitSwipe swipe && note is Flick flick)
|
||||
{
|
||||
return flick.CheckSwipeDirection(swipe.swipeDirection);
|
||||
return flick.CheckSwipeDirection(swipe);
|
||||
}
|
||||
|
||||
|
||||
Debug.Log("Input Position: " + inputScreenPosition +
|
||||
", Note Position: " + noteScreenPosition +
|
||||
", Distance: " + distance +
|
||||
", Area Radius: " + areaRadius +
|
||||
", Current Screen Ratio: " + CurrentScreenRatio());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +83,11 @@ namespace Ichni.RhythmGame
|
||||
|
||||
public override NoteJudgeUnit ConvertToGameType(NoteBase attachedNote)
|
||||
{
|
||||
return new TouchAreaJudgeUnit(attachedNote, areaRadius);
|
||||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
return new FullScreenNearTimeJudgeUnit(attachedNote);
|
||||
#elif UNITY_ANDROID || UNITY_IOS
|
||||
return new TouchAreaJudgeUnit(attachedNote, areaRadius);//TODO:改这里
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
public partial class Flick : NoteBase
|
||||
{
|
||||
public NoteJudgeType preJudgeType;
|
||||
|
||||
public List<Vector2> availableFlickDirections;
|
||||
public float flickBuffer = 0.5f;
|
||||
|
||||
@@ -66,22 +68,64 @@ namespace Ichni.RhythmGame
|
||||
}
|
||||
|
||||
base.Update();
|
||||
ExecuteFinalJudge(songTime);
|
||||
}
|
||||
|
||||
protected override void RemoveFromCheckingList()
|
||||
{
|
||||
GameManager.instance.inputManager.checkingFlickList.Remove(this);
|
||||
if (GameManager.instance.inputManager.checkingFlickList.Contains(this))
|
||||
{
|
||||
GameManager.instance.inputManager.checkingFlickList.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteStartJudge()
|
||||
{
|
||||
base.ExecuteStartJudge();
|
||||
|
||||
isFinalJudged = true;
|
||||
float triggerTime = GameManager.instance.songTime;
|
||||
float timeDifference = triggerTime - exactJudgeTime;
|
||||
|
||||
if (GameManager.instance.inputManager.checkingFlickList.Contains(this))
|
||||
NoteJudgeType startJudgeType = GetStartJudgeType(timeDifference);
|
||||
|
||||
if (startJudgeType != NoteJudgeType.Perfect)
|
||||
{
|
||||
GameManager.instance.inputManager.checkingFlickList.Remove(this);
|
||||
return;
|
||||
}
|
||||
|
||||
preJudgeType = startJudgeType;
|
||||
|
||||
isFirstJudged = true;
|
||||
|
||||
RemoveFromCheckingList();
|
||||
}
|
||||
|
||||
public void ExecuteFinalJudge(float triggerTime)
|
||||
{
|
||||
if (isFirstJudged && !isFinalJudged && preJudgeType != NoteJudgeType.NotJudged &&
|
||||
GameManager.instance.songTime >= exactJudgeTime)
|
||||
{
|
||||
if (preJudgeType == NoteJudgeType.Perfect)
|
||||
{
|
||||
Perfect(triggerTime);
|
||||
}
|
||||
else if (preJudgeType == NoteJudgeType.Good)
|
||||
{
|
||||
Good(triggerTime);
|
||||
}
|
||||
else if (preJudgeType == NoteJudgeType.Bad)
|
||||
{
|
||||
Bad(triggerTime);
|
||||
}
|
||||
else if (preJudgeType == NoteJudgeType.Miss)
|
||||
{
|
||||
Miss(triggerTime);
|
||||
}
|
||||
|
||||
if (preJudgeType != NoteJudgeType.Miss)
|
||||
{
|
||||
noteAudioSubmodule.PlayGeneralJudgeAudios();
|
||||
}
|
||||
|
||||
isFinalJudged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,8 +137,14 @@ namespace Ichni.RhythmGame
|
||||
return noteJudgeSubmodule.judgeUnitList.All(judgeUnit => judgeUnit.CheckJudgeAvailability(inputUnitSwipe));
|
||||
}
|
||||
|
||||
public bool CheckSwipeDirection(Vector2 screenSwipeDirection)
|
||||
public bool CheckSwipeDirection(InputUnitSwipe inputUnitSwipe)
|
||||
{
|
||||
if (inputUnitSwipe.isGeneric)
|
||||
{
|
||||
Debug.Log($"输入方向 {inputUnitSwipe.swipeDirection} 是通用的,直接匹配成功。");
|
||||
return true;
|
||||
}
|
||||
|
||||
Camera gameCamera = GameManager.instance.cameraManager.gameCamera.gameCamera;
|
||||
|
||||
foreach (Vector2 localDir in availableFlickDirections)
|
||||
@@ -113,18 +163,18 @@ namespace Ichni.RhythmGame
|
||||
continue;
|
||||
}
|
||||
|
||||
float dotProduct = Vector2.Dot(screenSwipeDirection, noteScreenDirection);
|
||||
float dotProduct = Vector2.Dot(inputUnitSwipe.swipeDirection, noteScreenDirection);
|
||||
|
||||
// 4. 检查点积是否满足阈值
|
||||
if (dotProduct >= flickBuffer)
|
||||
{
|
||||
// 匹配成功!无需再检查其他方向。
|
||||
Debug.Log($"匹配成功! 输入方向 {screenSwipeDirection} 匹配了本地方向 {localDir} (屏幕投影: {noteScreenDirection}), 点积: {dotProduct}");
|
||||
Debug.Log($"匹配成功! 输入方向 {inputUnitSwipe.swipeDirection} 匹配了本地方向 {localDir} (屏幕投影: {noteScreenDirection}), 点积: {dotProduct}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"匹配失败. 输入方向 {screenSwipeDirection} 未匹配任何允许的方向。");
|
||||
Debug.Log($"匹配失败. 输入方向 {inputUnitSwipe.swipeDirection} 未匹配任何允许的方向。");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +184,33 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
return isFirstJudged && noteJudgeSubmodule.judgeUnitList.All(judgeUnit => judgeUnit.CheckJudgeAvailability(inputUnitTouch));
|
||||
}
|
||||
|
||||
protected override void SetJudgeArea()
|
||||
{
|
||||
if (noteJudgeSubmodule != null)
|
||||
{
|
||||
if (GameManager.instance.songTime > exactJudgeTime - 0.1f && !isFirstJudged)
|
||||
{
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => !unit.isShowingJudge))
|
||||
{
|
||||
unit.SetShowingJudge(true);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
unit.UpdateJudge();
|
||||
}
|
||||
|
||||
if (GameManager.instance.songTime >= holdEndTime - Time.deltaTime)
|
||||
{
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
unit.SetShowingJudge(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Hold
|
||||
@@ -225,6 +252,8 @@ namespace Ichni.RhythmGame
|
||||
noteScreenPosition = GameManager.instance.cameraManager.gameCamera.gameCamera.WorldToScreenPoint(noteVisual.transform.position);
|
||||
}
|
||||
|
||||
SetJudgeArea();
|
||||
|
||||
foreach (EffectBase e in noteVisual.effectSubmodule.effectCollection["Generate"])
|
||||
{
|
||||
e.UpdateEffect(exactJudgeTime);
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dreamteck.Splines;
|
||||
using Sirenix.OdinInspector;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
@@ -39,6 +40,8 @@ namespace Ichni.RhythmGame
|
||||
public bool isFinalJudged;
|
||||
public override int HierarchyPriority => -10;
|
||||
|
||||
[Title("Debug")] public TMP_Text judgeRankHint;
|
||||
|
||||
/// <summary>
|
||||
/// 在MovableTrack上更新Note的位置,注意HoldNote需要重写这个方法
|
||||
/// </summary>
|
||||
@@ -86,6 +89,8 @@ namespace Ichni.RhythmGame
|
||||
gameObject.SetActive(false);
|
||||
GameManager.instance.noteManager.RegisterNote(this, exactJudgeTime - beyondTime - 0.5f);
|
||||
}
|
||||
|
||||
//judgeRankHint = Instantiate(GameManager.instance.basePrefabs.judgeRankHint, noteVisual.transform).GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
@@ -108,6 +113,10 @@ namespace Ichni.RhythmGame
|
||||
noteScreenPosition = GameManager.instance.cameraManager.gameCamera.gameCamera.WorldToScreenPoint(noteVisual.transform.position);
|
||||
}
|
||||
|
||||
SetJudgeArea();
|
||||
|
||||
//SetJudgeRankText();
|
||||
|
||||
foreach (EffectBase e in noteVisual.effectSubmodule.effectCollection["Generate"])
|
||||
{
|
||||
e.UpdateEffect(exactJudgeTime);
|
||||
@@ -191,6 +200,12 @@ namespace Ichni.RhythmGame
|
||||
}).AddTo(gameObject);
|
||||
|
||||
if (isOnTrack) track.childElementList.Remove(this);
|
||||
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
unit.SetShowingJudge(false);
|
||||
}
|
||||
|
||||
Destroy(gameObject, 1.2f); //注意所有特效时间不得超过1.2秒
|
||||
}
|
||||
|
||||
@@ -207,6 +222,12 @@ namespace Ichni.RhythmGame
|
||||
}).AddTo(gameObject);
|
||||
|
||||
if (isOnTrack) track.childElementList.Remove(this);
|
||||
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
unit.SetShowingJudge(false);
|
||||
}
|
||||
|
||||
Destroy(gameObject, 1.2f);
|
||||
}
|
||||
public virtual void Bad(float triggerTime){
|
||||
@@ -222,6 +243,12 @@ namespace Ichni.RhythmGame
|
||||
}).AddTo(gameObject);
|
||||
|
||||
if (isOnTrack) track.childElementList.Remove(this);
|
||||
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
unit.SetShowingJudge(false);
|
||||
}
|
||||
|
||||
Destroy(gameObject, 1.2f);
|
||||
}}
|
||||
|
||||
@@ -237,17 +264,23 @@ namespace Ichni.RhythmGame
|
||||
}).AddTo(gameObject);
|
||||
|
||||
if (isOnTrack) track.childElementList.Remove(this);
|
||||
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
unit.SetShowingJudge(false);
|
||||
}
|
||||
|
||||
Destroy(gameObject, 1.2f);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract partial class NoteBase
|
||||
{
|
||||
protected void SetJudgeArea()
|
||||
protected virtual void SetJudgeArea()
|
||||
{
|
||||
if (noteJudgeSubmodule != null)
|
||||
{
|
||||
if (GameManager.instance.songTime > exactJudgeTime - 0.25f && !isFirstJudged)
|
||||
if (GameManager.instance.songTime > exactJudgeTime - 0.1f && !isFirstJudged)
|
||||
{
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => !unit.isShowingJudge))
|
||||
{
|
||||
@@ -260,7 +293,7 @@ namespace Ichni.RhythmGame
|
||||
unit.UpdateJudge();
|
||||
}
|
||||
|
||||
if (GameManager.instance.songTime > exactJudgeTime + 0.25f)
|
||||
if (GameManager.instance.songTime > exactJudgeTime + 0.1f)
|
||||
{
|
||||
foreach (NoteJudgeUnit unit in noteJudgeSubmodule.judgeUnitList.Where(unit => unit.isShowingJudge))
|
||||
{
|
||||
@@ -274,6 +307,34 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
return exactJudgeTime.CompareTo(other.exactJudgeTime);
|
||||
}
|
||||
|
||||
private void SetJudgeRankText()
|
||||
{
|
||||
float triggerTime = GameManager.instance.songTime;
|
||||
float timeDifference = triggerTime - exactJudgeTime;
|
||||
|
||||
NoteJudgeType startJudgeType = GetStartJudgeType(timeDifference);
|
||||
if (startJudgeType == NoteJudgeType.Perfect)
|
||||
{
|
||||
judgeRankHint.text = "PERFECT";
|
||||
judgeRankHint.color = Color.cyan;
|
||||
}
|
||||
else if (startJudgeType == NoteJudgeType.Good)
|
||||
{
|
||||
judgeRankHint.text = "GOOD";
|
||||
judgeRankHint.color = Color.green;
|
||||
}
|
||||
else if (startJudgeType == NoteJudgeType.Bad)
|
||||
{
|
||||
judgeRankHint.text = "BAD";
|
||||
judgeRankHint.color = Color.magenta;
|
||||
}
|
||||
else if (startJudgeType == NoteJudgeType.Miss)
|
||||
{
|
||||
judgeRankHint.text = "MISS";
|
||||
judgeRankHint.color = Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract partial class NoteBase
|
||||
|
||||
@@ -73,11 +73,6 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
GameManager.instance.inputManager.checkingStayList.Remove(this);
|
||||
}
|
||||
|
||||
protected override NoteJudgeType GetStartJudgeType(float timeDifference)
|
||||
{
|
||||
return judgeIntervals.GetNoteJudgeType(timeDifference);
|
||||
}
|
||||
|
||||
public override void ExecuteStartJudge()
|
||||
{
|
||||
@@ -85,6 +80,12 @@ namespace Ichni.RhythmGame
|
||||
float timeDifference = triggerTime - exactJudgeTime;
|
||||
|
||||
NoteJudgeType startJudgeType = GetStartJudgeType(timeDifference);
|
||||
|
||||
if (startJudgeType != NoteJudgeType.Perfect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
preJudgeType = startJudgeType;
|
||||
|
||||
isFirstJudged = true;
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using Dreamteck.Splines;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Lean.Pool;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
@@ -24,7 +25,7 @@ namespace Ichni.RhythmGame
|
||||
new TimeInterval(-0.15f, -0.15f), new TimeInterval(-0.15f, -0.125f),
|
||||
new TimeInterval(-0.125f, -0.1f), new TimeInterval(-0.1f, 0.1f),
|
||||
new TimeInterval(0.1f, 0.125f), new TimeInterval(0.125f, 0.15f), 0.15f);
|
||||
|
||||
|
||||
if (parentElement.TryGetComponent(out Track track))
|
||||
{
|
||||
if (track.trackTimeSubmodule != null)
|
||||
|
||||
Reference in New Issue
Block a user