Object Tracker

This commit is contained in:
SoulliesOfficial
2026-01-01 00:04:42 -05:00
parent be1ad1566b
commit 797a5f7141
14 changed files with 571 additions and 3 deletions

View File

@@ -187,6 +187,15 @@ namespace Ichni.RhythmGame
string.Empty, string.Empty, false, 0, 1, false, 10, Vector3.right, 10, 5, true, Vector3.zero);
}); //Particle Tracker
var objectTrackerButton = inspector.GenerateButton(this, particleSubcontainer, "Object Tracker",
() =>
{
ObjectTracker.GenerateElement("New Object Tracker", Guid.NewGuid(), new List<string>(), true, this,
string.Empty, string.Empty, 10, Vector2.zero, Vector2.zero, string.Empty,
false, Vector3.zero,Vector3.zero, string.Empty,
false, Vector3.zero, Vector3.zero, string.Empty);
}); //Object Tracker
StandardInspectionElement.GenerateForTransform(this, generateContainer); //关于有Transform的元素
inspector.GenerateButton(this, particleSubcontainer, "Track Global Color Change",
() => { TrackGlobalColorChange.GenerateElement("New Track Global Color Change", Guid.NewGuid(), new List<string>(), true, this, new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true)); }); //变量容器

View File

@@ -0,0 +1,284 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Dreamteck.Splines;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class ObjectTracker : GameElement
{
public Track track;
public ObjectController objectController;
public GameObject objectPrefab;
private List<string> themeBundleList;
private List<string> objectNameList;
public string themeBundleName;
public string objectName;
public float playTime;
public float stopTime;
public int spawnCount;
public Vector2 positionOffsetMin = Vector2.zero;
public Vector2 positionOffsetMax = Vector2.zero;
public string customPositionRuleName;
public bool applyRotationOffset = false;
public Vector3 rotationOffsetMin = Vector3.zero;
public Vector3 rotationOffsetMax = Vector3.zero;
public string customRotationRuleName;
public bool applyScaleOffset = false;
public Vector3 scaleOffsetMin = Vector3.one;
public Vector3 scaleOffsetMax = Vector3.one;
public string customScaleRuleName;
public static ObjectTracker GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, Track track, string themeBundleName, string objectName, int spawnCount,
Vector2 positionOffsetMin, Vector2 positionOffsetMax, string customPositionRuleName,
bool applyRotationOffset, Vector3 rotationOffsetMin, Vector3 rotationOffsetMax, string customRotationRuleName,
bool applyScaleOffset, Vector3 scaleOffsetMin, Vector3 scaleOffsetMax, string customScaleRuleName)
{
ObjectTracker objectTracker = Instantiate(EditorManager.instance.basePrefabs.objectTracker, track.transform).GetComponent<ObjectTracker>();
objectTracker.objectPrefab = ThemeBundleManager.instance.GetObject<GameObject>(themeBundleName, objectName);
objectTracker.objectController.objects = new[] { objectTracker.objectPrefab };
objectTracker.Initialize(elementName, id, tags, isFirstGenerated, track);
objectTracker.track = track;
objectTracker.objectController.spline = track.trackPathSubmodule.path;
objectTracker.themeBundleList = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
objectTracker.objectNameList = new List<string>();
objectTracker.themeBundleName = themeBundleName;
objectTracker.objectName = objectName;
objectTracker.SetSpawnSettings(spawnCount,
positionOffsetMin, positionOffsetMax, customPositionRuleName,
applyRotationOffset, rotationOffsetMin, rotationOffsetMax, customRotationRuleName,
applyScaleOffset, scaleOffsetMin, scaleOffsetMax, customScaleRuleName);
return objectTracker;
}
private void Update()
{
float songTime = EditorManager.instance.songInformation.songTime;
if (playTime > songTime || stopTime < songTime)
{
if (objectController.enabled)
{
objectController.enabled = false;
}
}
else
{
if (!objectController.enabled)
{
objectController.enabled = true;
objectController.Spawn();
}
}
}
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Object Tracker");
var generate = container.GenerateSubcontainer(3);
var themeBundleDropdown =
inspector.GenerateDropdown(this, generate, "Theme Bundle", themeBundleList, nameof(themeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
objectNameList = themeBundle.assetList_GameObject.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, generate, "Object Name", objectNameList, nameof(objectName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown =
inspector.GenerateDropdown(this, generate, "Object Name", new List<string>(), nameof(objectName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则物体名称下拉框不可用
var setButton = inspector.GenerateButton(this, generate, "Generate", () =>
{
this.objectPrefab = ThemeBundleManager.instance.GetObject<GameObject>(themeBundleName, objectName);
this.objectController.objects = new[] { this.objectPrefab };
this.objectController.Spawn();
});
if (themeBundleName == String.Empty || objectName == String.Empty)
{
setButton.button.interactable = false;
}
var spawnSettings = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, spawnSettings, "Spawn Count", nameof(spawnCount))
.AddListenerFunction(()=> objectController.spawnCount = spawnCount);
inspector.GenerateInputField(this, spawnSettings, "Play Time", nameof(playTime));
inspector.GenerateInputField(this, spawnSettings, "Stop Time", nameof(stopTime));
var posSettings = container.GenerateSubcontainer(1);
inspector.GenerateVector2InputField(this, posSettings, "Position Offset Min", nameof(positionOffsetMin))
.AddListenerFunction(()=> objectController.minOffset = positionOffsetMin);
inspector.GenerateVector2InputField(this, posSettings, "Position Offset Max", nameof(positionOffsetMax))
.AddListenerFunction(()=> objectController.maxOffset = positionOffsetMax);
//inspector.GenerateInputField(this, posSettings, "Custom Position Rule Name", nameof(customPositionRuleName));
var rotSettings = container.GenerateSubcontainer(1);
inspector.GenerateToggle(this, rotSettings, "Apply Rotation Offset", nameof(applyRotationOffset))
.AddListenerFunction(()=> objectController.applyRotation = applyRotationOffset);
inspector.GenerateVector3InputField(this, rotSettings, "Rotation Offset Min", nameof(rotationOffsetMin))
.AddListenerFunction(()=> objectController.minRotation = rotationOffsetMin);
inspector.GenerateVector3InputField(this, rotSettings, "Rotation Offset Max", nameof(rotationOffsetMax))
.AddListenerFunction(()=> objectController.maxRotation = rotationOffsetMax);
//inspector.GenerateInputField(this, rotSettings, "Custom Rotation Rule Name", nameof(customRotationRuleName));
var scaleSettings = container.GenerateSubcontainer(1);
inspector.GenerateToggle(this, scaleSettings, "Apply Scale Offset", nameof(applyScaleOffset))
.AddListenerFunction(()=> objectController.applyScale = applyScaleOffset);
inspector.GenerateVector3InputField(this, scaleSettings, "Scale Offset Min", nameof(scaleOffsetMin))
.AddListenerFunction(()=> objectController.minScaleMultiplier = scaleOffsetMin);
inspector.GenerateVector3InputField(this, scaleSettings, "Scale Offset Max", nameof(scaleOffsetMax))
.AddListenerFunction(()=> objectController.maxScaleMultiplier = scaleOffsetMax);
//inspector.GenerateInputField(this, scaleSettings, "Custom Scale Rule Name", nameof(customScaleRuleName));
}
public override void SaveBM()
{
matchedBM = new Beatmap.ObjectTracker_BM(elementName, elementGuid, tags,
parentElement.matchedBM as GameElement_BM,
themeBundleName, objectName,
playTime, stopTime,
spawnCount,
positionOffsetMin, positionOffsetMax, customPositionRuleName,
applyRotationOffset, rotationOffsetMin, rotationOffsetMax, customRotationRuleName,
applyScaleOffset, scaleOffsetMin, scaleOffsetMax, customScaleRuleName);
}
}
public partial class ObjectTracker
{
public void SetSpawnSettings(int spawnCount,
Vector2 positionOffsetMin, Vector2 positionOffsetMax, string customPositionRuleName,
bool applyRotationOffset, Vector3 rotationOffsetMin, Vector3 rotationOffsetMax, string customRotationRuleName,
bool applyScaleOffset, Vector3 scaleOffsetMin, Vector3 scaleOffsetMax, string customScaleRuleName)
{
this.spawnCount = spawnCount;
this.positionOffsetMin = positionOffsetMin;
this.positionOffsetMax = positionOffsetMax;
this.customPositionRuleName = customPositionRuleName;
this.applyRotationOffset = applyRotationOffset;
this.rotationOffsetMin = rotationOffsetMin;
this.rotationOffsetMax = rotationOffsetMax;
this.customRotationRuleName = customRotationRuleName;
this.applyScaleOffset = applyScaleOffset;
this.scaleOffsetMin = scaleOffsetMin;
this.scaleOffsetMax = scaleOffsetMax;
this.customScaleRuleName = customScaleRuleName;
objectController.spawnCount = spawnCount;
objectController.minOffset = positionOffsetMin;
objectController.maxOffset = positionOffsetMax;
objectController.applyRotation = applyRotationOffset;
objectController.minRotation = rotationOffsetMin;
objectController.maxRotation = rotationOffsetMax;
objectController.applyScale = applyScaleOffset;
objectController.minScaleMultiplier = scaleOffsetMin;
objectController.maxScaleMultiplier = scaleOffsetMax;
objectController.Spawn();
}
}
namespace Beatmap
{
public class ObjectTracker_BM : GameElement_BM
{
public string themeBundleName;
public string objectName;
public float playTime;
public float stopTime;
public int spawnCount;
public Vector2 positionOffsetMin;
public Vector2 positionOffsetMax;
public string customPositionRuleName;
public bool applyRotationOffset;
public Vector3 rotationOffsetMin;
public Vector3 rotationOffsetMax;
public string customRotationRuleName;
public bool applyScaleOffset;
public Vector3 scaleOffsetMin;
public Vector3 scaleOffsetMax;
public string customScaleRuleName;
public ObjectTracker_BM()
{
}
public ObjectTracker_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
string themeBundleName, string objectName,
float playTime, float stopTime,
int spawnCount,
Vector2 positionOffsetMin, Vector2 positionOffsetMax, string customPositionRuleName,
bool applyRotationOffset, Vector3 rotationOffsetMin, Vector3 rotationOffsetMax, string customRotationRuleName,
bool applyScaleOffset, Vector3 scaleOffsetMin, Vector3 scaleOffsetMax, string customScaleRuleName)
: base(elementName, elementGuid, tags, attachedElement)
{
this.themeBundleName = themeBundleName;
this.objectName = objectName;
this.playTime = playTime;
this.stopTime = stopTime;
this.spawnCount = spawnCount;
this.positionOffsetMin = positionOffsetMin;
this.positionOffsetMax = positionOffsetMax;
this.customPositionRuleName = customPositionRuleName;
this.applyRotationOffset = applyRotationOffset;
this.rotationOffsetMin = rotationOffsetMin;
this.rotationOffsetMax = rotationOffsetMax;
this.customRotationRuleName = customRotationRuleName;
this.applyScaleOffset = applyScaleOffset;
this.scaleOffsetMin = scaleOffsetMin;
this.scaleOffsetMax = scaleOffsetMax;
this.customScaleRuleName = customScaleRuleName;
}
public override void ExecuteBM()
{
matchedElement = ObjectTracker.GenerateElement(
elementName, elementGuid, tags, false,
GetElement(attachedElementGuid) as Track,
themeBundleName, objectName,
spawnCount,
positionOffsetMin, positionOffsetMax, customPositionRuleName,
applyRotationOffset, rotationOffsetMin, rotationOffsetMax, customRotationRuleName,
applyScaleOffset, scaleOffsetMin, scaleOffsetMax, customScaleRuleName);
}
public override GameElement DuplicateBM(GameElement attached)
{
return ObjectTracker.GenerateElement(
elementName, Guid.NewGuid(), new List<string>(tags), false,
attached as Track,
themeBundleName, objectName,
spawnCount,
positionOffsetMin, positionOffsetMax, customPositionRuleName,
applyRotationOffset, rotationOffsetMin, rotationOffsetMax, customRotationRuleName,
applyScaleOffset, scaleOffsetMin, scaleOffsetMax, customScaleRuleName);
}
}
}
}

View File

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

View File

@@ -20,6 +20,7 @@ namespace Ichni.RhythmGame
public GameObject pathNode;
public Material defaultTrackMaterial;
public GameObject particleTracker;
public GameObject objectTracker;
public GameObject sampler;
[Title("Trail相关")] public GameObject trail;