Browse Source

Merge branch 'master' into feature-bepu-physics-docs

Vaclav Elias 1 năm trước cách đây
mục cha
commit
beafe6d9c4

+ 179 - 0
en/manual/scripts/custom-assets.md

@@ -0,0 +1,179 @@
+# Creating Custom Assets
+
+Stride supports the creation of custom asset types that can be referenced in your scenes as well as reference other assets.
+To do so, you must add a reference to the `Stride.Core.Assets` package in your game's `.csproj`:
+Here's how it looks like in a default game project:
+```xml
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>net8.0-windows</TargetFrameworks>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Stride.Engine" Version="4.2.0.1" />
+    <PackageReference Include="Stride.Video" Version="4.2.0.1" />
+    <PackageReference Include="Stride.Physics" Version="4.2.0.1" />
+    <PackageReference Include="Stride.Navigation" Version="4.2.0.1" />
+    <PackageReference Include="Stride.Particles" Version="4.2.0.1" />
+    <PackageReference Include="Stride.UI" Version="4.2.0.1" />
+    <PackageReference Include="Stride.Core.Assets.CompilerApp" Version="4.2.0.1" IncludeAssets="build;buildTransitive" />
+
+    <PackageReference Include="Stride.Core.Assets" Version="4.2.0.1" />
+  </ItemGroup>
+</Project>
+```
+>[!Warning]
+> Make sure that the version specified for `Stride.Core.Assets` matches the other package's versions.
+
+Inside the same project, create a new csharp file and replace its content with the following:
+```cs
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Stride.Core;
+using Stride.Core.Assets;
+using Stride.Core.Assets.Compiler;
+using Stride.Core.BuildEngine;
+using Stride.Core.Serialization;
+using Stride.Core.Serialization.Contents;
+using Stride.Engine;
+
+namespace YOUR_GAME_NAMESPACE;
+
+/// <summary>
+/// Runtime representation of the asset, this is the actual class you would use in your scripts
+/// </summary>
+[DataContract]
+[ContentSerializer(typeof(DataContentSerializerWithReuse<YOUR_CLASS>))]
+[ReferenceSerializer, DataSerializerGlobal(typeof(ReferenceSerializer<YOUR_CLASS>), Profile = "Content")]
+public class YOUR_CLASS
+{
+	// Replace this with whatever you would want this asset to hold at runtime
+    public List<Prefab> PrefabCollection { get; set; } = new();
+}
+
+/// <summary>
+/// Design time and file representation of <see cref="YOUR_CLASS"/>, you can add content here that won't be included in the build
+/// </summary>
+[AssetDescription(FileExtension, AllowArchetype = false)]
+[AssetContentType(typeof(YOUR_CLASS))]
+[AssetFormatVersion(nameof(YOUR_GAME_NAMESPACE), CurrentVersion, "1.0.0.0")]
+public sealed class YOUR_CLASS_ASSET : Asset
+{
+    private const string CurrentVersion = "1.0.0.0";
+    public const string FileExtension = ".blks";
+
+	// Replace this with whatever you would want this asset to have while inside the gamestudio
+    public List<Prefab> PrefabCollection { get; set; } = new();
+}
+
+/// <summary> Compiler which transforms your <see cref="YOUR_CLASS_ASSET"/> into <see cref="YOUR_CLASS"/> when building your game </summary>
+[AssetCompiler(typeof(YOUR_CLASS_ASSET), typeof(AssetCompilationContext))]
+public sealed class YOUR_CLASS_COMPILER : AssetCompilerBase
+{
+    protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result)
+    {
+        var asset = (YOUR_CLASS_ASSET)assetItem.Asset;
+
+        // you can have many build steps, each one is running an AssetCommand
+        result.BuildSteps = new AssetBuildStep(assetItem);
+        result.BuildSteps.Add(new DESIGN_TO_RUNTIME_COMMAND(targetUrlInStorage, asset, assetItem.Package));
+    }
+
+    public override IEnumerable<ObjectUrl> GetInputFiles(AssetItem assetItem)
+    {
+        // Yield asset items you are dependent on to include them in the build 
+        
+        var asset = (YOUR_CLASS_ASSET)assetItem.Asset;
+        foreach (var block in asset.PrefabCollection)
+        {
+            var url = AttachedReferenceManager.GetUrl(block);
+
+            if (!string.IsNullOrEmpty(url))
+            {
+                yield return new ObjectUrl(UrlType.Content, url);
+            }
+        }
+    }
+
+    /// <summary>
+    /// An <see cref="AssetCommand"/> that converts design time asset into runtime asset.
+    /// </summary>
+    public class DESIGN_TO_RUNTIME_COMMAND(string url, YOUR_CLASS_ASSET parameters, IAssetFinder assetFinder)
+        : AssetCommand<YOUR_CLASS_ASSET>(url, parameters, assetFinder)
+    {
+        protected override Task<ResultStatus> DoCommandOverride(ICommandContext commandContext)
+        {
+            var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService);
+
+            var runtimeObject = new YOUR_CLASS{ PrefabCollection = Parameters.PrefabCollection };
+            assetManager.Save(Url, runtimeObject);
+
+            commandContext.Logger.Info($"Saving {nameof(YOUR_CLASS)}: {runtimeObject.PrefabCollection}");
+
+            return Task.FromResult(ResultStatus.Successful);
+        }
+    }
+}
+```
+This takes care of the support for this asset, you could create a `*.blks` file inside your `Assets` directory and fill in the content manually, but might as well do it through the editor ...
+
+## Adding a section for the Add asset menu inside the editor
+
+Create a new directory named `Templates` within your Game's directory, this directory will be used to store your templates.
+Inside of that directory, create a new file named after your new asset with the `.sdtpl` extension.
+
+![Template directory example](media/template-directory-example.png)
+
+Open the file and paste the following into it
+```
+!TemplateAssetFactory
+Id: 21CC3354-9F0B-4D1F-8242-62D56454B27C
+AssetTypeName: YOUR_CLASS_ASSET
+Name: THE NAME IN THE EDITOR
+Scope: Asset
+Description: A DESCRIPTIVE DESCRIPTION OF YOUR ASSET
+Group: WHERE THIS WOULD BE CLASSIFIED UNDER IN THE EDITOR
+DefaultOutputName: THE DEFAULT FILE NAME
+```
+Edit the different fields appropriately,
+- `Id` must be unique ! There are a couple of services online to generate one if you need to, search for `generate guid online`
+- `AssetTypeName` must match the name of the class that inherits from `Asset` (the namespace can be omitted)
+
+Now you have to edit your `*.sdpkg` to include this new template, to do so you just have to add the following lines below your `TemplateFolders:`
+```
+TemplateFolders:
+    - Path: !dir Templates
+      Group: Assets
+      Files:
+        - !file Templates/YOUR_TEMPLATE.sdtpl
+```
+Here's how it looks like when included into a default game `*.sdpkg`:
+```
+!Package
+SerializedVersion: {Assets: 3.1.0.0}
+Meta:
+    Name: MyGame21
+    Version: 1.0.0
+    Authors: []
+    Owners: []
+    Dependencies: null
+AssetFolders:
+    -   Path: !dir Assets
+    -   Path: !dir Effects
+ResourceFolders:
+    - !dir Resources
+OutputGroupDirectories: {}
+ExplicitFolders: []
+Bundles: []
+TemplateFolders:
+    - Path: !dir Templates
+      Group: Assets
+      Files:
+        - !file Templates/YOUR_TEMPLATE.sdtpl
+RootAssets: []
+```
+
+And you're finally done, have fun !
+
+![Result](media/template-result.png)

+ 2 - 1
en/manual/scripts/index.md

@@ -40,4 +40,5 @@ You can still use standard C# classes in Stride, but these aren't called scripts
 * [Debugging](debugging.md)
 * [Preprocessor variables](preprocessor-variables.md)
 * [Create a model from code](create-a-model-from-code.md)
-* [Create Gizmos for you components](gizmos.md)
+* [Create Gizmos for your components](gizmos.md)
+* [Create Custom Assets](custom-assets.md)

+ 3 - 0
en/manual/scripts/media/template-directory-example.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:351296c8a008d7dbc5f4b5ab415385406232096a2a9bed31e44d20dd40387dd5
+size 15690

+ 3 - 0
en/manual/scripts/media/template-result.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a63474d88b57fdde078442c8ce0229d48bd9d34e99cbdc4ce8678e6796ca2390
+size 84568

+ 3 - 0
en/manual/stride-for-unity-developers/index.md

@@ -205,6 +205,9 @@ The editor opens in a new tab. You can arrange the tabs how you like, or float t
 
 >[!Note]
 >When you modify resource files outside Game Studio, the corresponding assets update automatically in Game Studio.
+ 
+### Scriptable Objects
+See the [Custom Assets](../scripts/custom-assets.md) page.
 
 ### Import assets
 

+ 3 - 1
en/manual/toc.yml

@@ -532,8 +532,10 @@ items:
         href: scripts/preprocessor-variables.md
       - name: Create a model from code
         href: scripts/create-a-model-from-code.md
-      - name: Create Gizmos for you components
+      - name: Create Gizmos for your components
         href: scripts/gizmos.md
+      - name: Create Custom Assets
+        href: scripts/custom-assets.md
 
   - name: Sprites
     href: sprites/index.md