Added a visualizer option for camera paths and deleted the collider on the arrows. Otherwise, they would mess with the game's physics and game logic.

This commit is contained in:
originalnicodr committed 2024-02-03 00:10:06 -03:00
1 parent a12b8a36c1
commit b87873ab83
3 files changed
+91 -10

No files matched your search

+2
View File
@@ -7,10 +7,12 @@ namespace UnityExplorer
{
public static GameObject CreateArrow(Vector3 arrowPosition, Quaternion arrowRotation){
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
cylinder.GetComponent<Collider>().enabled = false;
cylinder.GetComponent<MeshFilter>().mesh = CreateCylinderMesh(0.01f, 20, 2);
cylinder.transform.rotation = Quaternion.LookRotation(Vector3.down, Vector3.up);
GameObject cone = GameObject.CreatePrimitive(PrimitiveType.Sphere);
cone.GetComponent<Collider>().enabled = false;
cone.GetComponent<MeshFilter>().mesh = CreateConeMesh(10, 0.05f, 0.1f);
cone.transform.SetParent(cylinder.transform, true);
+71 -7
View File
@@ -36,6 +36,9 @@ namespace UnityExplorer.UI.Panels
GameObject followObject = null;
Toggle visualizePathToggle;
public GameObject pathVisualizer = new GameObject("PathVisualizer");
// ~~~~~~~~ UI construction / callbacks ~~~~~~~~
protected override void ConstructPanelContent()
@@ -70,13 +73,19 @@ namespace UnityExplorer.UI.Panels
Toggle closedLoopToggle = new Toggle();
GameObject toggleClosedLoopObj = UIFactory.CreateToggle(horiGroup, "Close path in a loop", out closedLoopToggle, out Text toggleClosedLoopText);
UIFactory.SetLayoutElement(toggleClosedLoopObj, minHeight: 25, flexibleWidth: 9999);
closedLoopToggle.onValueChanged.AddListener((isClosedLoop) => {closedLoop = isClosedLoop;});
closedLoopToggle.isOn = false;
closedLoopToggle.onValueChanged.AddListener((isClosedLoop) => {closedLoop = isClosedLoop; MaybeRedrawPath();});
toggleClosedLoopText.text = "Close path in a loop";
InputFieldRef TimeInput = null;
GameObject secondRow = AddInputField("Time", "Path time (in seconds at 60fps):", $"Default: {time}", out TimeInput, Time_OnEndEdit, false);
TimeInput.Text = time.ToString();
GameObject visualizePathObj = UIFactory.CreateToggle(secondRow, "Visualize Path", out visualizePathToggle, out Text visualizePathText);
UIFactory.SetLayoutElement(visualizePathObj, minHeight: 25, flexibleWidth: 9999);
visualizePathToggle.isOn = false;
visualizePathToggle.onValueChanged.AddListener(ToggleVisualizePath);
visualizePathText.text = "Visualize path";
}
private void UpdateListNodes(){
@@ -92,6 +101,43 @@ namespace UnityExplorer.UI.Panels
}
}
private void ToggleVisualizePath(bool enable){
if (enable){
if (controlPoints.Count > 2){
UpdateCatmullRomMoverData();
List<CatmullRom.CatmullRomPoint> lookaheadPoints = GetCameraPathsManager().GetLookaheadPoints();
int skip_points = 5; // How many points do we have to skip before drawing another arrow (otherwise they look very cluttered)
int n = 0;
for (int i=0; i < lookaheadPoints.Count; i++){
// We also want to draw an arrow on the last point in case its skipped.
if (n < skip_points && i != lookaheadPoints.Count - 1){
n++;
continue;
}
GameObject arrow = ArrowGenerator.CreateArrow(lookaheadPoints[i].position, lookaheadPoints[i].rotation);
arrow.transform.SetParent(pathVisualizer.transform, true);
n = 0;
}
}
}
else {
foreach (Transform transform in pathVisualizer.transform)
{
UnityEngine.Object.Destroy(transform.gameObject);
}
}
}
private void MaybeRedrawPath(){
if (visualizePathToggle.isOn){
ToggleVisualizePath(false);
ToggleVisualizePath(true);
}
}
private void DrawNodeOptions(CatmullRom.CatmullRomPoint point, int index){
GameObject horiGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "LightOptions", true, false, true, false, 4,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
@@ -106,6 +152,8 @@ namespace UnityExplorer.UI.Panels
point.rotation = followObject != null ? FreeCamPanel.ourCamera.transform.localRotation : FreeCamPanel.ourCamera.transform.rotation;
controlPoints[index] = point;
MaybeRedrawPath();
EventSystemHelper.SetSelectedGameObject(null);
};
@@ -132,7 +180,7 @@ namespace UnityExplorer.UI.Panels
ButtonRef destroyButton = UIFactory.CreateButton(horiGroup, "Delete", "Delete");
UIFactory.SetLayoutElement(destroyButton.GameObject, minWidth: 80, minHeight: 25, flexibleWidth: 9999);
destroyButton.OnClick += () => {controlPoints.Remove(point); UpdateListNodes();};
destroyButton.OnClick += () => {controlPoints.Remove(point); UpdateListNodes(); MaybeRedrawPath();};
//ShowPos and rot?
}
@@ -157,12 +205,10 @@ namespace UnityExplorer.UI.Panels
void StartButton_OnClick()
{
if(GetCameraPathsManager()){
GetCameraPathsManager().setClosedLoop(closedLoop);
GetCameraPathsManager().setLocalPoints(followObject != null);
GetCameraPathsManager().setSplinePoints(controlPoints.ToArray());
GetCameraPathsManager().setTime(time);
UpdateCatmullRomMoverData();
GetCameraPathsManager().StartPath();
UIManager.ShowMenu = false;
pathVisualizer.SetActive(false);
}
EventSystemHelper.SetSelectedGameObject(null);
@@ -171,6 +217,7 @@ namespace UnityExplorer.UI.Panels
void TogglePause_OnClick(){
if(GetCameraPathsManager()){
GetCameraPathsManager().TogglePause();
pathVisualizer.SetActive(!GetCameraPathsManager().IsPaused());
}
EventSystemHelper.SetSelectedGameObject(null);
@@ -179,6 +226,7 @@ namespace UnityExplorer.UI.Panels
void Stop_OnClick(){
if (GetCameraPathsManager()){
GetCameraPathsManager().Stop();
pathVisualizer.SetActive(true);
}
EventSystemHelper.SetSelectedGameObject(null);
@@ -194,6 +242,7 @@ namespace UnityExplorer.UI.Panels
controlPoints.Add(point);
UpdateListNodes();
MaybeRedrawPath();
EventSystemHelper.SetSelectedGameObject(null);
}
@@ -219,10 +268,16 @@ namespace UnityExplorer.UI.Panels
}
public void UpdatedFollowObject(GameObject obj){
if(followObject != null) TranslatePointsToGlobal();
// Had to include this check because the pathVisualizer was null for some reason
if (pathVisualizer == null) pathVisualizer = new GameObject("PathVisualizer");
if (followObject != null){
TranslatePointsToGlobal();
pathVisualizer.transform.SetParent(null, true);
}
followObject = obj;
if (obj != null){
TranslatePointsToLocal();
pathVisualizer.transform.SetParent(obj.transform, true);
}
UpdateListNodes();
}
@@ -252,5 +307,14 @@ namespace UnityExplorer.UI.Panels
controlPoints = newControlPoints;
}
void UpdateCatmullRomMoverData(){
GetCameraPathsManager().setClosedLoop(closedLoop);
GetCameraPathsManager().setLocalPoints(followObject != null);
GetCameraPathsManager().setSplinePoints(controlPoints.ToArray());
GetCameraPathsManager().setTime(time);
GetCameraPathsManager().CalculateLookahead();
}
}
}
+18 -3
View File
@@ -10,6 +10,8 @@ using UnhollowerRuntimeLib;
using Il2CppInterop.Runtime.Injection;
#endif
using UnityExplorer.UI;
namespace UnityExplorer.CatmullRom
{
// Struct to keep position, rotation and fov of a spline point
@@ -128,6 +130,10 @@ namespace UnityExplorer.CatmullRom
playingPath = !playingPath;
}
public bool IsPaused(){
return playingPath;
}
public void Stop(){
playingPath = false;
delta = lookaheadDelta;
@@ -190,8 +196,7 @@ namespace UnityExplorer.CatmullRom
while (room <= 0.0001f) {
// If the camera reached the last lookAhead we stop it
if (delta >= 1){
playingPath = false;
delta = 0;
PathFinished();
}
delta = Math.Min(delta + lookaheadDelta, 1);
@@ -344,7 +349,7 @@ namespace UnityExplorer.CatmullRom
return a * t * t * t + b * t * t + c * t + d;
}
void CalculateLookahead() {
public void CalculateLookahead() {
// We assume 60 locked fps.
float frames = time * 60;
float pathLength = 0;
@@ -370,5 +375,15 @@ namespace UnityExplorer.CatmullRom
//ExplorerCore.LogWarning($"on path length {pathLength}");
//ExplorerCore.LogWarning($"lookaheadDelta {lookaheadDelta}");
}
public List<CatmullRomPoint> GetLookaheadPoints(){
return lookaheadPoints;
}
void PathFinished(){
playingPath = false;
delta = 0;
UIManager.GetPanel<UnityExplorer.UI.Panels.CamPaths>(UIManager.Panels.CamPaths).pathVisualizer.SetActive(true);
}
}
}