修正了Tap的名称,编写了渲染Note的逻辑

This commit is contained in:
OrdinaryMan647 2025-11-19 01:26:30 +08:00
parent 62853fa9be
commit 1fcb6dedf0
20 changed files with 1056 additions and 273 deletions

File diff suppressed because one or more lines are too long

View File

@ -148,6 +148,7 @@ GameObject:
- component: {fileID: 5207352570132040939}
- component: {fileID: 8104531933206489017}
- component: {fileID: 7810372270032017921}
- component: {fileID: 7093576537923845205}
m_Layer: 0
m_Name: HeadAnchorPoint
m_TagString: Untagged
@ -242,3 +243,15 @@ MeshCollider:
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!114 &7093576537923845205
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8900154505411094545}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a3d1b0613bc35c14a915a806b27b6cf5, type: 3}
m_Name:
m_EditorClassIdentifier:

View File

@ -11,7 +11,7 @@ GameObject:
- component: {fileID: 3133920083175420714}
- component: {fileID: 6279844256921695762}
m_Layer: 0
m_Name: NoteAnchorPoint
m_Name: TapAnchorPoint
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -93,10 +93,10 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 7443082168914965180}
- component: {fileID: 4869839956365182491}
- component: {fileID: 715087861950065430}
- component: {fileID: 673455592900407993}
m_Layer: 0
m_Name: Note
m_Name: Tap
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -119,18 +119,6 @@ Transform:
- {fileID: 3133920083175420714}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &4869839956365182491
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2366632135410690476}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a2100bdbe3afed446ab147d3cf7c0508, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!65 &715087861950065430
BoxCollider:
m_ObjectHideFlags: 0
@ -152,6 +140,18 @@ BoxCollider:
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 0}
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &673455592900407993
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2366632135410690476}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f055fb95e30ebde45b74584656d8d3d8, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &8241740096970702598
GameObject:
m_ObjectHideFlags: 0
@ -163,7 +163,7 @@ GameObject:
- component: {fileID: 8905090958658591294}
- component: {fileID: 5017689155040747022}
m_Layer: 0
m_Name: NoteRenderer
m_Name: TapRenderer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@ -417,9 +417,9 @@ RectTransform:
m_Father: {fileID: 1791412692}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: -155, y: 457}
m_SizeDelta: {x: 280, y: 500}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -140, y: -1.6697998}
m_SizeDelta: {x: 280, y: -11.34039}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &35238248
MonoBehaviour:
@ -3599,7 +3599,7 @@ GameObject:
- component: {fileID: 450412148}
- component: {fileID: 450412147}
m_Layer: 5
m_Name: ChartStting
m_Name: ChartSetting
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -8194,6 +8194,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 071aa469eea9e9d4d9d022c8a98fa777, type: 3}
m_Name:
m_EditorClassIdentifier:
_Transform: {fileID: 0}
--- !u!1 &1166455538
GameObject:
m_ObjectHideFlags: 0

View File

@ -22,7 +22,7 @@ public abstract class BasePool<BaseClass> : MonoBehaviour where BaseClass : Mono
/// <summary>
/// 依据一个原型,返回一个空的可用对象
/// </summary>
public DerivedClass Get<DerivedClass>(DerivedClass prefab) where DerivedClass : BaseClass
public virtual DerivedClass Get<DerivedClass>(DerivedClass prefab) where DerivedClass : BaseClass
{
var type = typeof(DerivedClass);
if (!Pools.ContainsKey(type))
@ -42,8 +42,10 @@ public abstract class BasePool<BaseClass> : MonoBehaviour where BaseClass : Mono
//如果对象池没有对象,则创建一个对象
obj = Instantiate(prefab);
ActiveObjectList[type].Add(obj);
//运行调用方法
OnCreate(obj);
}
//激活时调用Get钩子
OnGet(obj);
obj.gameObject.SetActive(true);
obj.enabled = true;
@ -53,12 +55,16 @@ public abstract class BasePool<BaseClass> : MonoBehaviour where BaseClass : Mono
/// <summary>
/// 回收当前对象
/// </summary>
public void Release(BaseClass Object)
public virtual void Release(BaseClass Object)
{
if(Object != null)
{
UnityEngine.Debug.LogError("BasePool" + ":输入为Null,请检查逻辑");
}
var type = Object.GetType();
//如果字典中没有该类的对象池,则创建一个该类型的对象池
if (!Pools.ContainsKey(type)) Pools[type] = new Stack<BaseClass>();
//回收时调用释放钩子
OnRelease(Object);
Object.gameObject.SetActive(false);
@ -70,7 +76,7 @@ public abstract class BasePool<BaseClass> : MonoBehaviour where BaseClass : Mono
/// </summary>
/// <param name="Object"></param>
/// <returns></returns>
public bool ContainsObject(BaseClass Object)
public virtual bool ContainsObject(BaseClass Object)
{
var type = Object.GetType();
//如果没有该类型的对象池,则返回假
@ -83,7 +89,7 @@ public abstract class BasePool<BaseClass> : MonoBehaviour where BaseClass : Mono
/// <remarks>
/// <paramref name="该操作会清空所有的对象"/>
/// </remarks>
public void ClearPool()
public virtual void ClearPool()
{
foreach (var stack in Pools.Values)
{
@ -95,7 +101,7 @@ public abstract class BasePool<BaseClass> : MonoBehaviour where BaseClass : Mono
Pools.Clear();
}
/// <summary>
/// 返回一个当前类型的只读列表
/// 返回一个当前类型的只读列表(其实有更好的写法,之后会尝试优化,不使用ReadOnlyCollection)
/// </summary>
public ReadOnlyCollection<DerivedClass> GetActiveObjectList<DerivedClass>() where DerivedClass : BaseClass
{

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
/// <summary>
/// 谱面运行数据类,负责将谱面数据解析之后生成运行时数据项,与控制层通讯,这些数据项是查询现有数据项的唯一依据
@ -12,14 +13,24 @@ public class ChartRuntimeModel
/// </summary>
public SortedSet<RuntimeBaseNoteData> ChartRuntimeSet = new SortedSet<RuntimeBaseNoteData>(new UniversalBaseNoteComparer());
/// <summary>
/// 输入搜索的开始与结束时间,返回符合条件的对象视图
/// 输入搜索的开始与结束时间,返回符合条件的对象视图,当输入小于0时,返回Null
/// </summary>
public SortedSet<RuntimeBaseNoteData> SearchRange(float startTime, float endTime)
{
var view = ChartRuntimeSet.GetViewBetween(new TempBaseNoteComparer(startTime), new TempBaseNoteComparer(endTime));
if(startTime<=0||endTime <= 0) { return null; }
//深拷贝
var view = new SortedSet<RuntimeBaseNoteData>(ChartRuntimeSet.GetViewBetween(
new TempBaseNoteComparer(startTime),
new TempBaseNoteComparer(endTime)
)
);
return view;
}
/// <summary>
/// 清除所有的运行时数据
/// </summary>
public void Clear() { ChartRuntimeSet.Clear(); UnityEngine.Debug.Log(ChartRuntimeSet.Count); }
/// <summary>
/// 删除指定的数据项
/// </summary>
public void DeleteDataItem(RuntimeBaseNoteData obj)
@ -27,7 +38,7 @@ public class ChartRuntimeModel
ChartRuntimeSet.Remove(obj);
}
/// <summary>
/// 获得指定的数据项引用,如果不存在对应的数据项则会返回null
/// 获得指定的数据项引用,如果不存在对应的数据项则会返回Null
/// </summary>
public RuntimeBaseNoteData GetDataItem(RuntimeBaseNoteData obj)
{
@ -56,7 +67,7 @@ public class ChartRuntimeModel
{
switch (item)
{
case RuntimeNoteData:
case RuntimeTapData:
{
chart.noteList.Add(new NoteListItem(
item.xPos,
@ -109,6 +120,9 @@ public class ChartRuntimeModel
}
}
/// <summary>
/// 比较器,逻辑为同一个位置,同一个时间,不能出现同一种类型的Note
/// </summary>
public class UniversalBaseNoteComparer : IComparer<RuntimeBaseNoteData>
{
public int Compare(RuntimeBaseNoteData x, RuntimeBaseNoteData y)
@ -169,9 +183,9 @@ public class TempBaseNoteComparer : RuntimeBaseNoteData
targetTime = time;
}
}
public class RuntimeNoteData : RuntimeBaseNoteData
public class RuntimeTapData : RuntimeBaseNoteData
{
public RuntimeNoteData(float targetTime, float xPos, float yPos, BPMGroup bpmGroup)
public RuntimeTapData(float targetTime, float xPos, float yPos, BPMGroup bpmGroup)
{
this.targetTime = targetTime;
this.xPos = xPos;

View File

@ -1,22 +1,48 @@
using System.Collections.Generic;
using System.Diagnostics;
public class NotePoolManager : BasePool<BaseNote>
{
/// <summary>
/// 基于运行时数据用于存储生成出来活跃对象列表
/// </summary>
private Dictionary<RuntimeBaseNoteData, BaseNote> _dataToNoteCache = new Dictionary<RuntimeBaseNoteData, BaseNote>();
/// <summary>
/// 在每一个对象被创建出来的时候都会自动为其注册返回事件
/// </summary>
protected override void OnCreate(BaseNote obj)
{
obj.OnNoteUesd += ReturnBaseNoteToPool;
}
/// <summary>
/// 在激活新的对象的时候,将会在当前对象池中存储该对象的数据,用于快速查找
/// </summary>
protected override void OnGet(BaseNote obj)
{
base.OnGet(obj);
}
protected override void OnRelease(BaseNote obj)
{
// 缓存映射关系
if (obj.SelfRef != null)
{
_dataToNoteCache.Add(obj.SelfRef, obj);
}
}
/// <summary>
/// 泛型note回收方法
/// 在对象被回收的时候,从活跃列表中移除该对象
/// </summary>
protected override void OnRelease(BaseNote obj)
{
base.OnRelease(obj);
// 清理缓存
if (obj.SelfRef != null && _dataToNoteCache.ContainsKey(obj.SelfRef))
{
_dataToNoteCache.Remove(obj.SelfRef);
}
}
/// <summary>
/// 泛型Note回收方法
/// </summary>
/// <param name="note"></param>
public void ReturnBaseNoteToPool(BaseNote note)
{
//如果字典中没有该类的对象池,则创建一个
@ -25,5 +51,81 @@ public class NotePoolManager : BasePool<BaseNote>
Pools[type].Push(note);
note.gameObject.SetActive(false);
}
public override void ClearPool()
{
foreach (var list in ActiveObjectList)
{
foreach (var note in list.Value)
{
ReturnBaseNoteToPool(note);
}
}
}
/// <summary>
/// 使用运行时数据以近似遍历的方式在父对象池进行变量查找
/// </summary>
public BaseNote GetNoteByRuntimeData(RuntimeBaseNoteData data)
{
if (data == null)
{
UnityEngine.Debug.LogError("NotePoolManager" + "传入的数据是Null");
return null;
}
BaseNote note = null;
switch (data)
{
case RuntimeTapData:
{
ForEach((TapController n) =>
{
if (n.SelfRef == data) note = n;
});
break;
}
case RuntimeDragData:
{
ForEach((DragController n) =>
{
if (n.SelfRef == data) note = n;
});
break;
}
case RuntimeFlickData:
{
ForEach((FlickController n) =>
{
if (n.SelfRef == data) note = n;
});
break;
}
case RuntimeSnakeData:
{
ForEach((DataFlowController n) =>
{
if (n.SelfRef == data) note = n;
});
break;
}
}
UnityEngine.Debug.LogError("NotePoolManager" + ":这个运行时数据不在对象池的键中,没有找到对应的视图对象");
return note;
}
/// <summary>
/// 在Note自己的字典集合中查询对象,查找失败将会返回Null,该方法仍在测试中
/// </summary>
public BaseNote GetNoteByRuntimeDataInPool(RuntimeBaseNoteData data)
{
if (data == null)
{
UnityEngine.Debug.LogError("NotePoolManager" + ":传入的数据是Null");
return null;
}
if (_dataToNoteCache.TryGetValue(data, out BaseNote result))
{
return result;
}
return null;
}
}

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using static TMPro.Examples.TMP_ExampleScript_01;
/// <summary>
/// 用于描述Note判定情况的委托
@ -173,14 +175,20 @@ public abstract class BaseNote : MonoBehaviour,IRaycastHittable
//像判定区间,还有游戏难度,关卡属性,可以放在这里初始化
}
/// <summary>
/// 返回一个自己的引用
/// </summary>
public RuntimeBaseNoteData OnHitByRay(RaycastHit hit)
virtual public RuntimeBaseNoteData OnHitByRay(RaycastHit hit)
{
// 打印自己的信息
Debug.Log($"物体 {gameObject.name} 被击中了!");
Debug.Log($"碰撞点: {hit.point}, 法线: {hit.normal}");
Debug.Log($"物体 {gameObject.name} 被击中了!\n" +
$"碰撞点: {hit.point}, 法线: {hit.normal}\n" +
$"自身引用为{SelfRef}\n" +
$"父对象: {transform.parent?.name}"
);
// 可以添加更多自定义信息
return SelfRef;
}

View File

@ -48,10 +48,11 @@ public class DataFlowController : BaseNote
}
else
{
retObj = Instantiate<DataFlowUnit>(dataFlowUnitPrefab,_transform);
retObj = Instantiate<DataFlowUnit>(dataFlowUnitPrefab, _transform);
}
retObj.gameObject.SetActive(true);
retObj.enabled = true;
retObj.SelfRef = (RuntimeSnakeData)SelfRef;
return retObj;
}
@ -64,13 +65,16 @@ public class DataFlowController : BaseNote
{
obj.gameObject.SetActive(false);
obj.enabled = false;
dataFlowUnitPool.Push(obj);
dataFlowUnitPool.Push(obj);
}
}
private void CreateDataFlow( float valueInterval,ReferencePointLocation referencePoint,float currentTime)
private void CreateDataFlow(float valueInterval, ReferencePointLocation referencePoint, float currentTime)
{
if (SelfRef == null)
{
Debug.LogError($"当前对象没有数据,请检查主控赋值");
}
//指定起始坐标
Vector2 startPoint = new Vector2(_startPointXPos, _startPointYPos);
Vector2 endPoint = new Vector2(_endPointXPos, _endPointYPos);
@ -83,38 +87,41 @@ public class DataFlowController : BaseNote
//计算出点的位置
var tempEndPoint = BezierFunctions.GetBezierPoint(
startPoint,
endPoint,
referencePoint,
startPoint,
endPoint,
referencePoint,
(currentTime + valueInterval) / _endTime
);
GetView().Init(
tempStartPoint,
tempEndPoint,
currentTime,
currentTime + valueInterval,
0.4f,
_songInformation,
var temp = GetView();
temp.Init(
tempStartPoint,
tempEndPoint,
currentTime,
currentTime + valueInterval,
0.4f,
_songInformation,
_BPMGroup
);
temp.SelfRef = (RuntimeSnakeData)SelfRef;
//自增时间
currentTime += valueInterval;
//移动尾部
tempStartPoint = tempEndPoint;
}
//这里生成最后一段蛇
GetView().Init(
tempStartPoint,
endPoint,
currentTime,
_endTime,
0.4f,
_songInformation,
var go = GetView();
go.Init(
tempStartPoint,
endPoint,
currentTime,
_endTime,
0.4f,
_songInformation,
_BPMGroup
);
go.SelfRef = (RuntimeSnakeData)SelfRef;
}
public void Init(Vector2 startPoint, Vector2 endPoint, float startTime, float endTime, float width, SongInformationContainer container, BPMGroup timing, ReferencePointLocation referencePoint)
{
@ -134,7 +141,8 @@ public class DataFlowController : BaseNote
_BPMGroup = timing;
CreateDataFlow(_BPMGroup.Beat / 4, referencePoint, startTime);
Debug.Log(SelfRef);
CreateDataFlow(_BPMGroup.Beat / 2, referencePoint, startTime);
}
}

View File

@ -1,12 +1,13 @@
using UnityEngine;
using UnityEngine.UIElements;
public class DataFlowUnit : DataFlowController
public class DataFlowUnit : MonoBehaviour
{
//protected Transform _transform;
//protected Transform _rendererTransform;
//protected Transform _anchorPointTransform;
protected Transform _transform;
protected Transform _rendererTransform;
protected Transform _anchorPointTransform;
public RuntimeSnakeData SelfRef;
//首尾位置
private float _UnitStartPointXPos;
private float _UnitStartPointYPos;
@ -15,8 +16,8 @@ public class DataFlowUnit : DataFlowController
//起始时间
private float _UnitStartTime;
private float _UnitEndTime;
//SongInformationContainer _songInformation;
//BPMGroup _BPMGroup;
SongInformationContainer _songInformation;
BPMGroup _BPMGroup;
/// <summary>
/// 现在时间与结束点时间的差值
@ -141,12 +142,19 @@ public class DataFlowUnit : DataFlowController
private Vector3[] _vertex = new Vector3[24];
private float _unitWidth = 0.4f;
#endregion
public DataFlowUnitAnchorController _anchorController;
void Awake()
{
_transform = gameObject.GetComponent<Transform>();
_rendererMeshFilter = _transform.Find("Renderer").GetComponent<MeshFilter>();
_rendererTransform = _transform.Find("Renderer").GetComponent<Transform>();
_anchorPointTransform = _transform.Find("HeadAnchorPoint").GetComponent<Transform>();
//由于锚点是独立于物件存在的,所以需要额外设置脚本
_anchorController = _anchorPointTransform.gameObject.GetComponent<DataFlowUnitAnchorController>();
//将mesh标记为动态
_rendererMeshFilter.mesh.MarkDynamic();
}
@ -227,6 +235,9 @@ public class DataFlowUnit : DataFlowController
_anchorPointTransform.gameObject.SetActive(false);
_BPMGroup = timing;
Debug.Log(SelfRef);
_anchorController.SetSelfRef(SelfRef);
}
}

View File

@ -0,0 +1,30 @@
using UnityEngine;
/// <summary>
/// 仅仅是给射线一个开盒蛇引用的机会,将会直接持有父类的数据,击中任意锚点都会获取到父类的数据
/// </summary>
public class DataFlowUnitAnchorController :MonoBehaviour, IRaycastHittable
{
RuntimeBaseNoteData SelfRef=null;
/// <summary>
/// 重写射线命中方法,确保能正确返回引用
/// </summary>
public RuntimeBaseNoteData OnHitByRay(RaycastHit hit)
{
// 如果自身没有 SelfRef尝试从父对象获取
if (SelfRef == null)
{
Debug.LogError($"当前对象没有数据");
}
Debug.Log($"DataFlow锚点被击中了\n自身引用为{SelfRef}\n碰撞点: {hit.point}, 法线: {hit.normal}\n");
return SelfRef;
}
/// <summary>
/// 用于设置数据项目
/// </summary>
public void SetSelfRef(RuntimeBaseNoteData data)
{
SelfRef = data;
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a2100bdbe3afed446ab147d3cf7c0508
guid: a3d1b0613bc35c14a915a806b27b6cf5
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,13 +1,13 @@
using System.Collections.Generic;
using UnityEngine;
public class NoteController : BaseNote
public class TapController : BaseNote
{
private SpriteRenderer m_SpriteRenderer;
void Awake()
{
_transform = gameObject.GetComponent<Transform>();
_anchorPointTransform = _transform.Find("NoteAnchorPoint").GetComponent<Transform>();
_rendererTransform = _transform.Find("NoteRenderer").GetComponent<Transform>();
_anchorPointTransform = _transform.Find("TapAnchorPoint").GetComponent<Transform>();
_rendererTransform = _transform.Find("TapRenderer").GetComponent<Transform>();
//获取自身渲染器组件
m_SpriteRenderer = _anchorPointTransform.GetComponent<SpriteRenderer>();
}
@ -36,3 +36,4 @@ public class NoteController : BaseNote
_BPMGroup = timing;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f055fb95e30ebde45b74584656d8d3d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,18 +1,28 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LeftPanelView : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
public Transform _Transform;
// Update is called once per frame
void Update()
public Button BPMList { get; private set; }
public Button DesignCheck { get; private set; }
public Button Mesh { get; private set; }
public Button Crosshair { get; private set; }
public Button Folder { get; private set; }
public Button Setting { get; private set; }
public Button Audio { get; private set; }
public Button ChartSetting { get; private set; }
private void Awake()
{
_Transform = gameObject.GetComponent<Transform>();
BPMList = _Transform.Find("BPMList").GetComponent<Button>();
DesignCheck = _Transform.Find("DesignCheck").GetComponent<Button>();
Mesh = _Transform.Find("Mesh").GetComponent<Button>();
Crosshair = _Transform.Find("Crosshair").GetComponent<Button>();
Folder = _Transform.Find("Folder").GetComponent<Button>();
Setting = _Transform.Find("Setting").GetComponent<Button>();
Audio = _Transform.Find("Audio").GetComponent<Button>();
ChartSetting = _Transform.Find("ChartSetting").GetComponent<Button>();
}
}

View File

@ -3,17 +3,28 @@ using System.IO;
using System;
using SFB;
using System.Collections;
public enum GeneralOptionPanelEvent
{
MouseGudies, BuildingModel, EditModel
}
using Ookii.Dialogs;
using UnityEditor.Experimental.GraphView;
using System.Collections.Generic;
using System.Linq;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
/// <summary>
/// 用于持续检测用户的鼠标输入并且做出对应UI的响应,这是一个测试中的脚本,之后需要重构
/// </summary>
public class MainMenuController : MonoBehaviour
{
enum GeneralOptionPanelEvent
{
MouseGuides, BuildingModel, EditModel
}
enum EditOperation
{
}
Coroutine _runningCoroutine;
private Transform _Transform;
private MainMenuView _MainMenuView;
private MainMenuModel _MainMenuModel;
@ -44,7 +55,14 @@ public class MainMenuController : MonoBehaviour
/// 当歌曲时间发生变化事触发该事件,传入的时间为改变后的时间,更新之后的UI
/// </summary>
private event Action<float> OnTimeChange;
/// <summary>
/// 当用户有编辑操作的时候触发这个事件
/// </summary>
private event EventHandler EditCommand;
/// <summary>
/// 需要修改提示栏可以触发这个事件
/// </summary>
private event EventHandler ChangePromptBar;
#region Unity生命周期函数
void Start()
@ -60,16 +78,20 @@ public class MainMenuController : MonoBehaviour
//初始化各个界面
InitTopPenal();
InitLeftPenal();
InitProgressBar();
InitAllOptionPanel();
//这里初始化选择器的视图
_SelectView = _MainMenuView.NotePool.Get(_MainMenuView.MainMenuSelectView);
_SelectView.Init(0, _SongTimeContainer, _MainMenuModel.MainBPMGroup);
//注册事件
//注册时间变化事件
OnTimeChange += _MainMenuView.TopPanel.ChangeTimeText;
OnTimeChange += ChangeProgressBar;
//注册命令事件
EditCommand += DeleteNote;
//注册物件更新事件
OnCurrentDataUpdate += UpdateNoteDataWindow;
}
void Update()
@ -79,6 +101,7 @@ public class MainMenuController : MonoBehaviour
//在数据层更新当前的歌曲时间
_SongTimeContainer.UpdateSongInformation(_MainMenuModel.SongCurrentTime);
UpdateNoteView(_MainMenuModel.SongCurrentTime, _MainMenuModel.SongCurrentTime+ _MainMenuModel.EndOffset);
//检查当前输入
CheckUserInput();
}
@ -89,7 +112,14 @@ public class MainMenuController : MonoBehaviour
/// </summary>
private void ChangeTimeWhitMouseScroll(float value)
{
_MainMenuModel.SongCurrentTime += value * _MainMenuModel.MainBPMGroup.Beat / 4;
//改变歌曲的进度,改变的量为一拍的4分之一,只在歌曲时间内才能改变
if (_MainMenuModel.SongCurrentTime + value * _MainMenuModel.MainBPMGroup.Beat / 4>=0 &&
_MainMenuModel.SongCurrentTime + value * _MainMenuModel.MainBPMGroup.Beat / 4 <= _MainMenuModel.SongDuration)
{
_MainMenuModel.SongCurrentTime += value * _MainMenuModel.MainBPMGroup.Beat / 4;
}
if (value == 0) return;
OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
}
@ -118,7 +148,21 @@ public class MainMenuController : MonoBehaviour
_MainMenuView.TopPanel.PlaySongButton.onClick.AddListener(OnPlaySongButtonClick);
_MainMenuView.TopPanel.StopSongButton.onClick.AddListener(OnStopSongButtonClick);
}
Coroutine _runningCoroutine;
private void InitLeftPenal()
{
_MainMenuView.LeftPanel.BPMList.onClick.AddListener(() => { });
_MainMenuView.LeftPanel.DesignCheck.onClick.AddListener(() => { });
_MainMenuView.LeftPanel.Mesh.onClick.AddListener(() => { });
_MainMenuView.LeftPanel.Crosshair.onClick.AddListener(() => { });
_MainMenuView.LeftPanel.Folder.onClick.AddListener(() =>
{
//文件夹处理,Json导入,Json导出
ReadFile();
});
_MainMenuView.LeftPanel.Setting.onClick.AddListener(() => { });
_MainMenuView.LeftPanel.Audio.onClick.AddListener(() => { });
_MainMenuView.LeftPanel.ChartSetting.onClick.AddListener(() => { });
}
/// <summary>
/// 开始播放按钮绑定的方法
/// </summary>
@ -214,6 +258,7 @@ public class MainMenuController : MonoBehaviour
OnTimeChange?.Invoke(_MainMenuModel.SongCurrentTime);
}
#endregion
#region
/// <summary>
/// 监听用户的输入
/// </summary>
@ -254,11 +299,21 @@ public class MainMenuController : MonoBehaviour
CloseBuildingOptionPanel();
}//使用ESC退出建造模式
}
if (Input.GetKeyDown(KeyCode.Delete))
{
EditCommand?.Invoke(this, null);
}
if (Input.GetKeyDown(KeyCode.I))
{
InitProjectOnChart();
}
if (Input.GetKeyDown(KeyCode.F))
{
ReadFile();
}
}
#endregion
#region
/// <summary>
/// 文件写入操作
@ -283,14 +338,26 @@ public class MainMenuController : MonoBehaviour
CloseGeneralOptionPanel();
}
/// <summary>
/// 选择谱面文件,读取
/// 选择谱面文件,读取,该操作在成功读取文件之后将会覆盖当前的数据
/// </summary>
private void ReadFile()
{
string[] filePath = StandaloneFileBrowser.OpenFolderPanel("选择文件夹", Application.persistentDataPath, false);
//StandaloneFileBrowser.OpenFolderPanel("选择文件夹", Application.persistentDataPath, false);
string[] filePath = StandaloneFileBrowser.OpenFilePanel("选择文件夹", Application.persistentDataPath, "json", false);
if (filePath == null) return;
_MainMenuView.TopPanel.StatusBar.text = filePath[0];
();
/*
* ,,
*
*/
try
{
_MainMenuModel.ReadChartByPath(filePath[0] + "\\Chart.json");
_MainMenuModel.ReadChartByPath(filePath[0]);
}
catch (System.NullReferenceException e)
{
@ -303,18 +370,112 @@ public class MainMenuController : MonoBehaviour
return;
}
}
/// <summary>
/// 清除当前的所有数据,核爆运行时数据,所有的东西都需要写一个自毁按钮,这是创造者的浪漫
/// </summary>
private void ()
{
//核爆视图数据
_MainMenuView.NotePool.ClearPool();
//核爆运行时数据库
_MainMenuModel.ClearRunTimeData();
}
/// <summary>
/// 从当前的持久化数据中重新读取数据,目前拿的还是默认的时间组,需要修改迭代
/// </summary>
private void InitProjectOnChart()
{
foreach (var item in _MainMenuModel.PersistentChartData.noteList)
{
//运行时数据
var selfRef = _MainMenuModel.CreateNewTapDataItem(
item.targetTime,
item.x,
item.y,
item.timingGroup
);
//视觉对象初始化
var Go = _MainMenuView.NotePool.Get(_MainMenuView.TapPrefab);
Go.Init(
new Vector2(
item.x,
item.y),
item.targetTime,
_SongTimeContainer,
_MainMenuModel.MainBPMGroup);
//设置视觉对象指针
Go.SelfRef = selfRef;
}
foreach (var item in _MainMenuModel.PersistentChartData.dragList)
{
//运行时数据
var selfRef = _MainMenuModel.CreateNewDragDataItem(
item.targetTime,
item.x,
item.y,
item.timingGroup
);
//视觉对象初始化
var Go = _MainMenuView.NotePool.Get(_MainMenuView.DragPrefab);
Go.Init(
new Vector2(
item.x,
item.y),
item.targetTime,
_SongTimeContainer,
_MainMenuModel.MainBPMGroup);
//设置视觉对象指针
Go.SelfRef = selfRef;
}
foreach (var item in _MainMenuModel.PersistentChartData.flickList)
{
//运行时数据
var selfRef = _MainMenuModel.CreateNewFlickDataItem(
item.targetTime,
item.x,
item.y,
item.timingGroup,
item.direction
);
//视觉对象初始化
var Go = _MainMenuView.NotePool.Get(_MainMenuView.FlickPrefab);
Go.Init(
new Vector2(
item.x,
item.y),
item.targetTime,
_SongTimeContainer,
item.direction,
_MainMenuView.FlickSpritePairs,
_MainMenuModel.MainBPMGroup
);
//设置视觉对象指针
Go.SelfRef = selfRef;
}
foreach (var item in _MainMenuModel.PersistentChartData.dataFlowList)
{
var data = _MainMenuModel.CreateNewSnakeDataItem(
item.startTime,
item.startX,
item.startY,
item.endX,
item.endY,
item.endTime,
item.timingGroup,
item.type
);
}
}
#endregion
#region
/// <summary>
/// 创建新的note实例的函数
/// </summary>
private void CreateNewNote(Vector3 mouseWorldPos, NoteController note, int timingGroup)
private void CreateNewNote(Vector3 mouseWorldPos, TapController note, int timingGroup)
{
_MainMenuView.TopPanel.StatusBar.text = "已创建 " + note.gameObject.name;
var selfRef = _MainMenuModel.CreateNewNoteDataItem(_MainMenuModel.SongCurrentTime, mouseWorldPos.x, mouseWorldPos.y, timingGroup);
var selfRef = _MainMenuModel.CreateNewTapDataItem(_MainMenuModel.SongCurrentTime, mouseWorldPos.x, mouseWorldPos.y, timingGroup);
var Go = _MainMenuView.NotePool.Get(note);
Go.Init(
@ -420,6 +581,9 @@ public class MainMenuController : MonoBehaviour
Go.SelfRef = selfRef;
}
/// <summary>
/// 创建蛇实例的函数
/// </summary>
private IEnumerator CreateNewDataFlow(Vector3 mouseWorldPos, DataFlowController dataFlow, int timingGroup)
{
ReferencePointLocation reference = ReferencePointLocation.Near;
@ -515,8 +679,9 @@ public class MainMenuController : MonoBehaviour
endTime,
timingGroup,
reference);
var Go = _MainMenuView.NotePool.Get(dataFlow);
//注意,一定要在设置自身数据之后再进行初始化,不然子类会全部找不到自己的数据
Go.SelfRef = selfRef;
Go.Init(
mouseWorldPos,
currentMousePos,
@ -528,7 +693,7 @@ public class MainMenuController : MonoBehaviour
reference
);
Go.SelfRef = selfRef;
_MainMenuView.TopPanel.StatusBar.text = "开始位置:" + mouseWorldPos.ToString() + " 时间:" + startTime + " 结束位置:" + currentMousePos.ToString() + " 时间:" + endTime;
}
/// <summary>
@ -541,11 +706,11 @@ public class MainMenuController : MonoBehaviour
//处于创造模式下,单击左键将会创造预备创造的物件
switch (preGeneratedObject)
{
case NoteController:
case TapController:
{
CreateNewNote(
Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, 8)),
_MainMenuView.NotePrefab,
_MainMenuView.TapPrefab,
_MainMenuModel.MainBPMGroup.GroupNum);
break;
}
@ -589,7 +754,7 @@ public class MainMenuController : MonoBehaviour
}
}
#endregion
#region
#region
/// <summary>
/// 初始化所有右键会话窗口
/// </summary>
@ -621,7 +786,7 @@ public class MainMenuController : MonoBehaviour
/// </summary>
void InitBuildingOptionPanel()
{
BuildingOptionPanel.NoteButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.NoteButton.gameObject, _MainMenuView.NotePrefab));
BuildingOptionPanel.NoteButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.NoteButton.gameObject, _MainMenuView.TapPrefab));
BuildingOptionPanel.DragButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.DragButton.gameObject, _MainMenuView.DragPrefab));
BuildingOptionPanel.FlickButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.FlickButton.gameObject, _MainMenuView.FlickPrefab));
BuildingOptionPanel.DataFlowButton.onClick.AddListener(() => OnBuildingModelButtonClick(BuildingOptionPanel.DataFlowButton.gameObject, _MainMenuView.DataFlowPrefab));
@ -714,7 +879,7 @@ public class MainMenuController : MonoBehaviour
}
}
#endregion
#region
#region
/*
*
* 1.线
@ -743,7 +908,7 @@ public class MainMenuController : MonoBehaviour
Debug.DrawLine(ray.origin, hit.point, Color.green, 0.4f);
// 在碰撞点绘制一个小球
Debug.DrawRay(hit.point, hit.normal, Color.blue, 0.4f);
Debug.Log("击中了:"+hit.collider.gameObject.name);
Debug.Log("主控制器击中了:" + hit.collider.gameObject.name);
//这里触发一下更新事件
OnCurrentDataUpdate?.Invoke(GetNoteDataByRay(hit));
}
@ -770,13 +935,37 @@ public class MainMenuController : MonoBehaviour
/// </summary>
public void UpdateNoteDataWindow(RuntimeBaseNoteData data)
{
if(data!= currentData)
if (data != currentData)
{
Debug.Log("已经替换了目前的数据");
currentData = data;
_MainMenuView.NoteEditWindows.UpdateWindowData(currentData);
}
}
/// <summary>
/// 删除当前选择的物件
/// </summary>
public void DeleteNote(object sender, EventArgs e)
{
if (currentData == null) { _MainMenuView.TopPanel.StatusBar.text = "目前没有可以删除的Note (´;ω;`)"; }
var note = _MainMenuView.NotePool.GetNoteByRuntimeData(currentData);
if (note == null)
{
UnityEngine.Debug.LogError(this.name + ":查找结果为Null,请检查逻辑");
return;
}
_MainMenuView.NotePool.Release(note);
if (!_MainMenuModel.DeleteRuntimeDataItem(currentData))
{
UnityEngine.Debug.LogError(this.name + ":数据项目没有删除成功,请检查逻辑");
}
}
#endregion
#region
//储存当前查找到的数据引用,之后将作为查找的依据
@ -784,4 +973,155 @@ public class MainMenuController : MonoBehaviour
//当属性面板里面的数据发生修改时,用预先存储的数据去查找
//修改好数据之后,用新数据更新预先存储的数据,将成为新的查找依据
#endregion
#region
/*
*
* :
* ,,
* :,
*
* ,,
*/
/// <summary>
/// 这是上一帧已经渲染出来的数据集
/// </summary>
SortedSet<RuntimeBaseNoteData> previousFrameSet= new SortedSet<RuntimeBaseNoteData>();
/// <summary>
/// 更新所有Note视图
/// </summary>
public void UpdateNoteView(float startTime, float endTime)
{
var currentFrameSet = _MainMenuModel.SearchRange(startTime, endTime);
if (currentFrameSet == null || previousFrameSet==null)
{
UnityEngine.Debug.Log(this.name+":查询出来的结果为空");
return;
}
//获得一个需要删除的视图对象的列表
var delete = previousFrameSet.Except(currentFrameSet);
//获得一个需要创建的视图对象的列表
var create = currentFrameSet.Except(previousFrameSet);
Debug.Log($"开始时间为:{startTime}\n,"
+$"结束时间为:{endTime}\n"
+$"删除列表有{delete.Count()}数据,待创建列表有{create.Count()}个数据"
);
if (delete != null)
{
foreach (var NeedDeleteData in delete)
{
var temp = _MainMenuView.NotePool.GetNoteByRuntimeData(NeedDeleteData);
_MainMenuView.NotePool.Release(temp);
}
}
if (create != null)
{
foreach (var NeedCreateData in create)
{
CreateNewViewWithRunTimeData(NeedCreateData);
}
}
previousFrameSet = currentFrameSet;
}
/// <summary>
/// 依据运行时数据创建新的视图对象
/// </summary>
private BaseNote CreateNewViewWithRunTimeData(RuntimeBaseNoteData baseNoteData)
{
if (baseNoteData == null)
{
return null;
}
BaseNote baseNote = null;
switch (baseNoteData)
{
case RuntimeTapData:
{
var tap = baseNoteData as RuntimeTapData;
var note = _MainMenuView.NotePool.Get(_MainMenuView.TapPrefab);
note.SelfRef = tap;
note.Init(
new Vector2(
tap.xPos,
tap.yPos),
tap.targetTime,
_SongTimeContainer,
_MainMenuModel.MainBPMGroup
);
break;
}
case RuntimeDragData:
{
var drag = baseNoteData as RuntimeDragData;
var note = _MainMenuView.NotePool.Get(_MainMenuView.DragPrefab);
note.SelfRef = drag;
note.Init(
new Vector2(
drag.xPos,
drag.yPos),
drag.targetTime,
_SongTimeContainer,
_MainMenuModel.MainBPMGroup
);
break;
}
case RuntimeFlickData:
{
var flick = baseNoteData as RuntimeFlickData;
var note = _MainMenuView.NotePool.Get( _MainMenuView.FlickPrefab);
note.SelfRef = flick;
note.Init(
new Vector2(flick.xPos, flick.yPos),
flick.targetTime,
_SongTimeContainer,
_MainMenuView.FlickSpritePairs,
_MainMenuModel.MainBPMGroup
);
break;
}
case RuntimeSnakeData:
{
var slider = baseNoteData as RuntimeSnakeData;
var note = _MainMenuView.NotePool.Get(_MainMenuView.DataFlowPrefab);
note.SelfRef = slider;
note.Init(
new Vector2(slider.xPos ,slider.yPos),
new Vector2 (slider.endXPos,slider.endYPos),
slider .targetTime,
slider.endTime,
0.4f,
_SongTimeContainer,
_MainMenuModel.MainBPMGroup,
slider.referencePoint
);
break;
}
}
return baseNote;
}
#endregion
}
public class StringEventArgs : EventArgs
{
public string Message { get; set; }
public StringEventArgs(string message)
{
Message = message;
}
}

View File

@ -13,6 +13,26 @@ public class MainMenuModel : MonoBehaviour
readonly private float DefaultNoteStream = 5f;
readonly private float DefaultBPM = 128;
readonly private float DefaultBaseBPM = 128;
private float BaseSpeed = 25;
private float TrackLength = 125;
private float NoteStream = 5f;
private float BPM = 128;
private float BaseBPM = 128;
/// <summary>
/// 到达零平面需要的时间,通过轨道长度除以音符流速与基准速度的积获得
/// </summary>
public float EndOffset
{
get
{
return TrackLength / (NoteStream * BaseSpeed);
}
}
/// <summary>
/// 存储所有拍线的时间,在加载BPM组的时候就需要初始化完成
/// </summary>
@ -31,10 +51,25 @@ public class MainMenuModel : MonoBehaviour
return BPMGroupManager.QueryBPMGroup(0);
}
}
/// <summary>
/// 用于持久化的数据的谱面对象
/// </summary>
public Chart PersistentChartData { set; get; }
/// <summary>
/// 用于管理BPM对象的数据模块
/// </summary>
public BPMGroupModel BPMGroupManager { set; get; }
/// <summary>
/// 用于管理所有谱面运行时数据的数据模块
/// </summary>
public ChartRuntimeModel ChartRuntimeDataManager { set; get; }
/// <summary>
/// 歌
/// </summary>
public AudioSource Song { set; get; }
/// <summary>
/// 当前歌曲时间,单位是秒
/// </summary>
public float SongCurrentTime
{
get
@ -47,9 +82,20 @@ public class MainMenuModel : MonoBehaviour
Song.time = value;
}
}
/// <summary>
/// 歌曲长度,单位:秒
/// </summary>
public float SongDuration
{
get
{
return Song.clip.length;
}
}
#region
private void Awake()
{
//Awake是程序的入口
Song = gameObject.GetComponent<AudioSource>();
InitMainMenuModel();
}
@ -70,109 +116,6 @@ public class MainMenuModel : MonoBehaviour
//初始化新项目的结构
NewProjectData();
}
/// <summary>
/// 依据时间更新所有BPM组的状态,将这个方法注册在控制层的时间变化事件中
/// </summary>
public void UpdateBPMGroup(float currentTime)
{
BPMGroupManager.UpdateBPMGroup(currentTime);
}
/// <summary>
/// 向管理器申请创建新的数据项,返回创建结果
/// </summary>
public bool CreateBPMDataItem(int groupNum, float startTime, float currentBPM)
{
BPMGroupManager.CreateNewBPMGroup(groupNum, startTime, currentBPM);
return BPMGroupManager.QueryBPMGroupDataItem(groupNum, startTime, currentBPM);
}
/// <summary>
/// 向管理器申请删除指定的数据项,返回删除结果
/// </summary>
public bool DeleteBPMDataItem(int groupNum, float startTime, float currentBPM)
{
BPMGroupManager.DeleteBPMGroup(groupNum, startTime);
return !BPMGroupManager.QueryBPMGroupDataItem(groupNum, startTime, currentBPM);
}
/// <summary>
/// 这里会返回一个包含当前所有BPM数据项的集合用于让C层持有数据库的备份,之后只能通过开发的接口更改数据,C层本身并不能直接访问BPM管理器
/// </summary>
public List<(int GroupNum, float startTime, float currentBPM)> GetAllBPMDataItem()
{
return BPMGroupManager.GetAllBPMDataItem();
}
/// <summary>
/// 更新所有的玩家设置
/// </summary>
public void UpdatePlayerSetting(float noteStream, float baseSpeed, float baseBPM, float trackLength)
{
BPMGroupManager.UpdatePlayerSetting(noteStream, baseSpeed, baseBPM, trackLength);
PersistentChartData.globalConfig.baseBPM = baseBPM;
PersistentChartData.globalConfig.baseSpeed = baseSpeed;
PersistentChartData.globalConfig.trackLength = trackLength;
PersistentChartData.globalConfig.noteStream = noteStream;
}
/// <summary>
/// 删除指定的数据项,返回删除的情况
/// </summary>
public bool DeleteNoteDataItem(RuntimeBaseNoteData obj)
{
ChartRuntimeDataManager.DeleteDataItem(obj);
if (ChartRuntimeDataManager.GetDataItem(obj) == null)
{
return true;
}
return false;
}
public RuntimeNoteData CreateNewNoteDataItem(float targetTime, float xPos, float yPos, int num)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeNoteData(targetTime, xPos, yPos, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
public RuntimeDragData CreateNewDragDataItem(float targetTime, float xPos, float yPos, int num)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeDragData(targetTime, xPos, yPos, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
public RuntimeFlickData CreateNewFlickDataItem(float targetTime, float xPos, float yPos, int num, FlickDirection direction)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeFlickData(targetTime, xPos, yPos, direction, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
public RuntimeSnakeData CreateNewSnakeDataItem(float targetTime, float xPos, float yPos, float endXPos, float endYPos, float endTime, int num, ReferencePointLocation referencePoint)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeSnakeData(targetTime, xPos, yPos, endXPos, endYPos, endTime, referencePoint, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
/// <summary>
/// 导出运行时模型与BPM管理模型中的数据项至持久化数据结构中
/// </summary>
public void UpdateChartData()
{
ChartRuntimeDataManager.GetChartData(PersistentChartData);
//导出BPM数据
var bpmList = BPMGroupManager.GetDataObject();
PersistentChartData.BPMList = bpmList;
}
private void NewProjectData()
{
//创建默认BPM组,编号为零
@ -204,6 +147,126 @@ public class MainMenuModel : MonoBehaviour
PersistentChartData.META.chartDesigner = "Program Team";
PersistentChartData.META.illustrator = "天辞ちゃんBananApple";
}
#endregion
#region BPM数据操作接口
/// <summary>
/// 依据时间更新所有BPM组的状态,将这个方法注册在控制层的时间变化事件中
/// </summary>
public void UpdateBPMGroup(float currentTime)
{
BPMGroupManager.UpdateBPMGroup(currentTime);
}
/// <summary>
/// 向管理器申请创建新的BPM数据项,返回创建结果
/// </summary>
public bool CreateBPMDataItem(int groupNum, float startTime, float currentBPM)
{
BPMGroupManager.CreateNewBPMGroup(groupNum, startTime, currentBPM);
return BPMGroupManager.QueryBPMGroupDataItem(groupNum, startTime, currentBPM);
}
/// <summary>
/// 向管理器申请删除指定的BPM数据项,返回删除结果
/// </summary>
public bool DeleteBPMDataItem(int groupNum, float startTime, float currentBPM)
{
BPMGroupManager.DeleteBPMGroup(groupNum, startTime);
return !BPMGroupManager.QueryBPMGroupDataItem(groupNum, startTime, currentBPM);
}
/// <summary>
/// 这里会返回一个包含当前所有BPM数据项的集合用于让C层持有数据库的备份,之后只能通过开发的接口更改数据,C层本身并不能直接访问BPM管理器
/// </summary>
public List<(int GroupNum, float startTime, float currentBPM)> GetAllBPMDataItem()
{
return BPMGroupManager.GetAllBPMDataItem();
}
/// <summary>
/// 更新所有BPM对象的玩家设置,
/// </summary>
public void UpdatePlayerSetting(float noteStream, float baseSpeed, float baseBPM, float trackLength)
{
BPMGroupManager.UpdatePlayerSetting(noteStream, baseSpeed, baseBPM, trackLength);
PersistentChartData.globalConfig.baseBPM = baseBPM;
PersistentChartData.globalConfig.baseSpeed = baseSpeed;
PersistentChartData.globalConfig.trackLength = trackLength;
PersistentChartData.globalConfig.noteStream = noteStream;
}
#endregion
#region
/// <summary>
/// 删除指定的数据项,返回删除的情况
/// </summary>
public bool DeleteRuntimeDataItem(RuntimeBaseNoteData obj)
{
ChartRuntimeDataManager.DeleteDataItem(obj);
if (ChartRuntimeDataManager.GetDataItem(obj) == null)
{
return true;
}
return false;
}
public RuntimeTapData CreateNewTapDataItem(float targetTime, float xPos, float yPos, int num)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeTapData(targetTime, xPos, yPos, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
public RuntimeDragData CreateNewDragDataItem(float targetTime, float xPos, float yPos, int num)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeDragData(targetTime, xPos, yPos, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
public RuntimeFlickData CreateNewFlickDataItem(float targetTime, float xPos, float yPos, int num, FlickDirection direction)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeFlickData(targetTime, xPos, yPos, direction, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
public RuntimeSnakeData CreateNewSnakeDataItem(float targetTime, float xPos, float yPos, float endXPos, float endYPos, float endTime, int num, ReferencePointLocation referencePoint)
{
var go = BPMGroupManager.QueryBPMGroup(num);
if (go == null) return null;
var item = new RuntimeSnakeData(targetTime, xPos, yPos, endXPos, endYPos, endTime, referencePoint, go);
ChartRuntimeDataManager.AddDataItem(item);
return item;
}
/// <summary>
/// 输入搜索的开始与结束时间,返回符合条件的集合
/// </summary>
public SortedSet<RuntimeBaseNoteData> SearchRange(float startTime, float endTime)
{
var set =ChartRuntimeDataManager.SearchRange(startTime, endTime);
return set;
}
public void ClearRunTimeData()
{
ChartRuntimeDataManager.Clear();
}
#endregion
#region
/// <summary>
/// 导出运行时模型与BPM管理模型中的数据项至持久化数据结构中
/// </summary>
public void UpdateChartData()
{
ChartRuntimeDataManager.GetChartData(PersistentChartData);
//导出BPM数据
var bpmList = BPMGroupManager.GetDataObject();
PersistentChartData.BPMList = bpmList;
}
/// <summary>
/// 依据路径读取Chart文件,注意,读取新的文件将会覆盖当前工程
/// </summary>
@ -211,9 +274,10 @@ public class MainMenuModel : MonoBehaviour
{
string json = File.ReadAllText(path);
PersistentChartData = JsonConvert.DeserializeObject<Chart>(json);
Debug.Log(PersistentChartData.ToString());
}
/// <summary>
/// 将谱面文件序列化json字符串
/// 将谱面文件序列化Json字符串
/// </summary>
public string GetChartJson()
{
@ -223,4 +287,6 @@ public class MainMenuModel : MonoBehaviour
print(jsonString);
return jsonString;
}
#endregion
}

View File

@ -15,7 +15,7 @@ public class MainMenuView : MonoBehaviour
public NoteEditWindowsView NoteEditWindows { get; private set; }
//可游玩物体的预制件引用
public NoteController NotePrefab { get; private set; }
public TapController TapPrefab { get; private set; }
public DragController DragPrefab { get; private set; }
public FlickController FlickPrefab { get; private set; }
public DataFlowController DataFlowPrefab { get; private set; }
@ -34,7 +34,7 @@ public class MainMenuView : MonoBehaviour
{
_Transform = gameObject.GetComponent<Transform>();
LoadDirationSprites();
LoadDirectionSprites();
LoadPlayObjectViewPrefab();
LoadDecorateObject();
LoadRightClickDialogWindow();
@ -57,7 +57,7 @@ public class MainMenuView : MonoBehaviour
/// </summary>
private void LoadPlayObjectViewPrefab()
{
NotePrefab = Resources.Load<NoteController>("NotePrefabs/note");
TapPrefab = Resources.Load<TapController>("NotePrefabs/Tap");
DragPrefab = Resources.Load<DragController>("NotePrefabs/Drag");
FlickPrefab = Resources.Load<FlickController>("NotePrefabs/Flick");
DataFlowPrefab = Resources.Load<DataFlowController>("NotePrefabs/DataFlow");
@ -67,7 +67,7 @@ public class MainMenuView : MonoBehaviour
/// <summary>
/// 用于加载FLick所有方向贴图
/// </summary>
private void LoadDirationSprites()
private void LoadDirectionSprites()
{
FlickSpritePairs.Add(FlickDirection.Any, Resources.Load<Sprite>("NoteSprites/AllFlick/AllFlick_0"));
FlickSpritePairs.Add(FlickDirection.Up, Resources.Load<Sprite>("NoteSprites/AllFlick/AllFlick_1"));

View File

@ -56,16 +56,16 @@ public class NoteEditWindowsView : MonoBehaviour
/// </summary>
public void UpdateWindowData(RuntimeBaseNoteData data)
{
Debug.Log("窗口编辑器中显示数据的类型为:"+data.GetType());
Debug.Log(this.name + ":窗口编辑器中显示数据的类型为:" + data.GetType());
switch (data)
{
case RuntimeNoteData:
case RuntimeTapData:
{
³õʼ»¯´°¿Ú();
Title.text = "Tap";
Start_x.text=data.xPos.ToString();
Start_y.text=data.yPos.ToString();
TargetTime.text=data.targetTime.ToString();
Start_x.text = data.xPos.ToString();
Start_y.text = data.yPos.ToString();
TargetTime.text = data.targetTime.ToString();
break;
}
case RuntimeDragData:
@ -122,14 +122,14 @@ public class NoteEditWindowsView : MonoBehaviour
}
}
private void ³õʼ»¯´°¿Ú()
{
Title.text = "null";
Start_x.text="null";
Start_y.text= "null";
Start_x.text = "null";
Start_y.text = "null";
TargetTime.text = "null";
End_x.text = "null";
End_y.text = "null";