Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions Prowl.Editor/AssetDatabase/AssetCreateMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Prowl.Editor.Panels;
using Prowl.Editor.Widgets;
using Prowl.Runtime;
using Prowl.Runtime.Resources;

namespace Prowl.Editor;

Expand All @@ -19,15 +20,37 @@ public static class AssetCreateMenu
/// </summary>
public static void Build(ContextMenuBuilder builder, string currentFolder, Action<string>? onCreated = null)
{
builder.Item($"{EditorIcons.Folder} Folder", () => { var p = CreateFolder(currentFolder); if (p != null) onCreated?.Invoke(p); });
builder.Item($"{EditorIcons.Folder} Folder", () => {

var task = new Tasks.CreateAssetTask();

task.TaskType = Tasks.CreateAssetTask.AssetType.Folder;
task.BeginCreateTask(new CreateAssetMenuRegistry.Entry() { Name = "New Folder", Extension = "", Icon = FileIconRegistry.GetIconForExtension("") }, currentFolder);

});
builder.Separator();

// Registry-discovered asset types (Scene, Material, InputActions, user-defined, etc.)
CreateAssetMenuRegistry.BuildMenu(builder, currentFolder, onCreated);

builder.Item($"{EditorIcons.WandMagicSparkles} Shader", () => { var p = CreateShader(currentFolder); if (p != null) onCreated?.Invoke(p); });
builder.Item($"{EditorIcons.WandMagicSparkles} Shader", () => {

var task = new Tasks.CreateAssetTask();

task.TaskType = Tasks.CreateAssetTask.AssetType.Shader;
task.BeginCreateTask(new CreateAssetMenuRegistry.Entry() { Name = "New Shader", Extension = ".shader", Type = typeof(Shader), Icon = FileIconRegistry.GetIconForExtension(".shader") }, currentFolder);

});
builder.Separator();
builder.Item($"{EditorIcons.FileCode} C# Script", () => NewScriptDialog.Open(currentFolder, onCreated));
builder.Item($"{EditorIcons.FileCode} C# Script", () =>
{
NewScriptDialog.Open(GetCurrentFolder());

/*var task = new Tasks.CreateAssetTask();
task.TaskType = Tasks.CreateAssetTask.AssetType.Script;
task.BeginCreateTask(new CreateAssetMenuRegistry.Entry() { Name = "New Script", Extension = ".cs", Type = typeof(MonoBehaviour), Icon = FileIconRegistry.GetIconForExtension(".cs") }, currentFolder);*/

});
}

/// <summary>
Expand Down
9 changes: 6 additions & 3 deletions Prowl.Editor/AssetDatabase/CreateAssetMenuRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public static void Initialize()
/// <summary>
/// Appends one menu item per registered asset type to the given context menu builder.
/// Names containing '/' are split into nested submenus (e.g. "Shader Graph/Surface"
/// produces an "Shader Graph" submenu with a "Surface" item inside).
/// produces a "Shader Graph" submenu with a "Surface" item inside).
/// </summary>
public static void BuildMenu(ContextMenuBuilder builder, string currentFolder, Action<string>? onCreated = null)
{
Expand Down Expand Up @@ -135,8 +135,11 @@ private static void BuildMenuRecursive(ContextMenuBuilder builder,
string icon = !string.IsNullOrEmpty(captured.Icon) ? captured.Icon : EditorIcons.FileCirclePlus;
builder.Item($"{icon} {display}", () =>
{
var path = CreateAsset(captured, currentFolder);
if (path != null) onCreated?.Invoke(path);
var task = new Tasks.CreateAssetTask();

task.TaskType = Tasks.CreateAssetTask.AssetType.Asset;
task.BeginCreateTask(captured, currentFolder);

});
}
foreach (var (head, list) in branches)
Expand Down
43 changes: 43 additions & 0 deletions Prowl.Editor/EditorApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,49 @@ public override void EndGui(Paper paper)

private const int BarCount = 10;

public static string GetEmbeddedResourceText(string resource)
{
var stream = GetEmbeddedResource(resource);

string data = "";
using (StreamReader reader = new StreamReader(stream))
{
data = reader.ReadToEnd();
}

return data;
}

public static Stream? GetEmbeddedResource(string resource)
{
var assembly = Assembly.GetExecutingAssembly();

var resourceName = "Prowl.Editor.Resources." + resource;

var stream = assembly.GetManifestResourceStream(resourceName);
return stream;
}

public static FileStream? GetResource(string resource)
{
var assembly = Assembly.GetExecutingAssembly();

var resourceName = resource;

var pathToFile = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) +
resourceName;

using (var stream = assembly.GetManifestResourceStream(resourceName))
{
using (var fileStream = File.Create(pathToFile))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
}
}
return File.OpenRead(pathToFile);
}

private void DrawIntro(Paper paper)
{
float w = paper.ScreenRect.Size.X;
Expand Down
32 changes: 29 additions & 3 deletions Prowl.Editor/Panels/ProjectPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ namespace Prowl.Editor.Panels;
[EditorWindow("General/Project")]
public class ProjectPanel : DockPanel
{
public static ProjectPanel Instance;
public override string Title => "Project";
public override string Icon => EditorIcons.Folder;

// Handled Virtual (Placeholder) content to be displayed with normal objects
public List<ContentItem> VirtualContentItems = new();

public string CurrentFolder => _currentFolder;
private string _currentFolder = ""; // Relative to Assets/, empty = Assets root
private string _searchText = "";
private float _thumbnailSize = 64f;
Expand Down Expand Up @@ -56,6 +61,9 @@ public override void OnGUI(Paper paper, float width, float height)
var font = EditorTheme.DefaultFont;
if (font == null || Project.Current == null) return;

// Sets itself as instance on start
Instance ??= this;

// Detect new ping and navigate to the pinged asset's folder
if (Selection.PingedGuid != Guid.Empty && Selection.PingedGuid != _lastPingedGuid)
{
Expand Down Expand Up @@ -1009,6 +1017,7 @@ private void StartRename(ContentItem item, bool inTree = false)
});
}


private static void OpenWithSystem(ContentItem item)
{
string absPath = Path.Combine(Project.Current!.AssetsPath, item.RelativePath);
Expand All @@ -1033,6 +1042,8 @@ private void DrawGridView(Paper paper, Prowl.Scribe.FontFile font, List<ContentI
{
float cellSize = _thumbnailSize + 8f;
float labelH = 18f;


float totalCellH = cellSize + labelH;
int cols = Math.Max(1, (int)((width - 16) / cellSize));

Expand All @@ -1052,7 +1063,17 @@ private void DrawGridView(Paper paper, Prowl.Scribe.FontFile font, List<ContentI
var item = entries[idx];
bool isSelected = Selection.IsSelected(item);

DrawGridItem(paper, font, $"proj_gc_{idx}", item, idx, itemObjects, cellSize, labelH, totalCellH);

var size = paper.MeasureText(item.Name, EditorTheme.FontSize - 3, font);

if (size.X > cellSize)
{
size *= 2;
}

//Runtime.Debug.Log($"Size: ({item.Name}) {labelH} - {sizeY} - {sizeYo} ({(EditorTheme.FontSize - 5)/paper.Canvas.Scale})");

DrawGridItem(paper, font, $"proj_gc_{idx}", item, idx, itemObjects, cellSize, size.Y, totalCellH);
}
}
row++;
Expand Down Expand Up @@ -1181,16 +1202,19 @@ private void DrawGridItem(Paper paper, Prowl.Scribe.FontFile font, string id, Co
// Label
if (RenameOverlay.IsRenaming($"proj_asset_{item.RelativePath}"))
{
RenameOverlay.Draw(paper, $"{id}_rename");
RenameOverlay.Draw(paper, $"{id}_rename", RenameOverlay.Position.Bottom);
}
else
{
paper.Box($"{id}_l")
.PositionType(PositionType.SelfDirected)
.Position(0,UnitValue.Stretch())
.Width(cellSize).Height(labelH)
.Clip()
.Text(item.Name, font)
.Wrap(Scribe.TextWrapMode.Wrap)
.TextColor(isSubAsset ? EditorTheme.Purple300 : EditorTheme.Ink500)
.FontSize(EditorTheme.FontSize - 2).Alignment(TextAlignment.MiddleCenter);
.FontSize(EditorTheme.FontSize - 3).Alignment(TextAlignment.MiddleCenter);
}

BuildItemContextMenu(paper, $"{id}_ctx", item);
Expand Down Expand Up @@ -1245,6 +1269,8 @@ private List<ContentItem> GetContentEntries(EditorAssetDatabase db)
}
catch { }

items.AddRange(VirtualContentItems);

// Files
try
{
Expand Down
22 changes: 22 additions & 0 deletions Prowl.Editor/Resources/NewAudioOneShot.cstemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Prowl.Runtime;

[RequireComponent(typeof(AudioSource))]
public class {[className]} : MonoBehaviour
{
public bool PlayOnStart = true;

private AudioSource _source = null!;

public override void Start()
{
_source = GetComponent<AudioSource>()!;
if (PlayOnStart) Play();
}

public void Play()
{
if (_source.Clip != null) _source.Play();
}

public void Stop() => _source.Stop();
}
39 changes: 39 additions & 0 deletions Prowl.Editor/Resources/NewCharacterController.cstemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Prowl.Runtime;
using Prowl.Vector;

[RequireComponent(typeof(CharacterController))]
public class {[className]} : MonoBehaviour
{
public float MoveSpeed = 6f;
public float JumpSpeed = 8f;
public float Gravity = -20f;

private CharacterController _controller = null!;
private Float3 _velocity;

public override void Start()
{
_controller = GetComponent<CharacterController>()!;
}

public override void Update()
{
Float2 wasd = Input.GetWASD();
Float3 planar = Transform.Right * wasd.X + Transform.Forward * wasd.Y;
_velocity.X = planar.X * MoveSpeed;
_velocity.Z = planar.Z * MoveSpeed;

if (_controller.IsGrounded)
{
_velocity.Y = 0f;
if (Input.GetKeyDown(KeyCode.Space))
_velocity.Y = JumpSpeed;
}
else
{
_velocity.Y += Gravity * Time.DeltaTime;
}

_controller.Move(_velocity * Time.DeltaTime);
}
}
8 changes: 8 additions & 0 deletions Prowl.Editor/Resources/NewDataAsset.cstemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Prowl.Runtime;

[CreateAssetMenu("{[className]}", Extension = ".asset")]
public class {[className]} : EngineObject
{
public float ExampleFloat = 1f;
public string ExampleText = "";
}
32 changes: 32 additions & 0 deletions Prowl.Editor/Resources/NewFirstPersonCamera.cstemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;

using Prowl.Runtime;
using Prowl.Vector;

public class {[className]} : MonoBehaviour
{
public float Sensitivity = 0.15f;
public float MinPitch = -89f;
public float MaxPitch = 89f;

private float _yaw;
private float _pitch;

public override void Start()
{
Float3 euler = Transform.LocalEulerAngles;
_pitch = euler.X;
_yaw = euler.Y;
}

public override void Update()
{
if (!Input.CursorLocked) return;

Float2 delta = Input.MouseDelta;
_yaw += delta.X * Sensitivity;
_pitch = Math.Clamp(_pitch - delta.Y * Sensitivity, MinPitch, MaxPitch);

Transform.LocalEulerAngles = new Float3(_pitch, _yaw, 0f);
}
}
29 changes: 29 additions & 0 deletions Prowl.Editor/Resources/NewFollowCamera.cstemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

using Prowl.Runtime;
using Prowl.Vector;

public class {[className]} : MonoBehaviour
{
public GameObject? Target;
public Float3 Offset = new Float3(0, 3, -6);
public float FollowSmoothing = 8f;
public float LookSmoothing = 8f;

public override void LateUpdate()
{
if (Target == null) return;

Float3 desiredPos = Target.Transform.Position + Target.Transform.Rotation * Offset;
float tMove = 1f - MathF.Exp(-FollowSmoothing * Time.DeltaTime);
Transform.Position = Maths.Lerp(Transform.Position, desiredPos, tMove);

Float3 lookDir = Target.Transform.Position - Transform.Position;
if (Float3.LengthSquared(lookDir) > 0.0001f)
{
Quaternion desiredRot = Quaternion.LookRotation(Float3.Normalize(lookDir), Float3.UnitY);
float tLook = 1f - MathF.Exp(-LookSmoothing * Time.DeltaTime);
Transform.Rotation = Quaternion.Slerp(Transform.Rotation, desiredRot, tLook);
}
}
}
37 changes: 37 additions & 0 deletions Prowl.Editor/Resources/NewHealth.cstemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;

using Prowl.Runtime;

public class {[className]} : MonoBehaviour
{
public float MaxHealth = 100f;

private float _current;

public float Current => _current;
public float Normalized => MaxHealth > 0 ? _current / MaxHealth : 0f;
public bool IsDead => _current <= 0f;

public event Action<float>? HealthChanged;
public event Action? Died;

public override void OnEnable()
{
_current = MaxHealth;
}

public void Damage(float amount)
{
if (IsDead || amount <= 0f) return;
_current = MathF.Max(0f, _current - amount);
HealthChanged?.Invoke(_current);
if (IsDead) Died?.Invoke();
}

public void Heal(float amount)
{
if (IsDead || amount <= 0f) return;
_current = MathF.Min(MaxHealth, _current + amount);
HealthChanged?.Invoke(_current);
}
}
Loading
Loading