update: 11/28/24 - Somewhere along the way, I modified the publish.sh script to better handle script selection + hidden folder pruning. Included a diff of the version I am using now vs. the original version posted... however, the site is seemingly not accepting it in any form at the moment.... so... https://www.diffchecker.com/wuuLn6gN/
This document is an attempt to update guides for Plugin/Script .NET assembly building, VAR packaging, and soon, Testing (there is at least 1 viable framework in the works)
This now works using the latest SDK (v8.0x) without me needing to list individual .cs files to include along with the assemblies for namespace/intellisense.
Project Structure / Publish Script Placement:
Let DevelopmentDirectory or DD refer to the folder containing your PluginFolder. I assume PluginFolder matches the plugin's name.
This document is an attempt to update guides for Plugin/Script .NET assembly building, VAR packaging, and soon, Testing (there is at least 1 viable framework in the works)
.NET Assembly Building
In the tutorial I've found, I had to list .cs files to include in my assembly.This now works using the latest SDK (v8.0x) without me needing to list individual .cs files to include along with the assemblies for namespace/intellisense.
XML:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net35</TargetFramework>
<LangVersion>6</LangVersion>
<DefineConstants>VAM_GT_1_20;VAM_GT_1_20_77_0</DefineConstants>
<OutputType>Library</OutputType>
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<FileAlignment>4096</FileAlignment>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="UnityEngine">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UIModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.UIModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.TextRenderingModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.TextRenderingModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.AnimationModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.AnimationModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.PhysicsModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.PhysicsModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.AudioModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.AudioModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.AssetBundleModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.AssetBundleModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.VRModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.VRModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.XRModule">
<HintPath>../../../../VaM_Data/Managed/UnityEngine.XRModule.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>../../../../VaM_Data/Managed/Assembly-CSharp.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
VAR publishing automation script
Depending on your project structure, packaging a VAR from the linux / wsl command line can be as easy as:
Bash:
./publish.sh MyPlugin
Let DevelopmentDirectory or DD refer to the folder containing your PluginFolder. I assume PluginFolder matches the plugin's name.
- - First, personalize.
- Place the file ALONGSIDE PluginFolder, inside of the directory DD.
- Replace EntityCX w/ your own CreatorName.
- - Also, modify the meta info to your liking.
- - note: For my setup, DevelopmentDirectory (DD) is the same as my `CreatorName`, `EntityCX`
Bash:
somePath/EntityCX$ ls -la ./
AppearanceSwapper/
SomeOtherPluginFolder/
AppearanceSwapper_run_number
publish.sh
- - Verify the file is executable.
- -
chmod +x ./publish.sh
- -
- - Run the script.
- -
somePath/DD$ ./publish.sh PluginFolder
- -
- - The var-destined files get packaged to DD/CreatorName.PluginName.X.var where `X` is the run number.
- - DD/publish/PluginName is created if it does not exist.
- - holds copy of packaged structure
- - eg, Custom\Scripts\CreatorName\PluginFolder\*.
- - will persist, until you delete it, serving as a backup between publish runs and local updates, etc.
- - holds copy of packaged structure
- - An empty .hide file is created alongside every .cs file not in the plugin's root directory.
- - This keeps the file from showing up in the browser when the user is searching for the plugin's main file(s).
- - Your .sln, .csproj, obj/* and bin/* paths are skipped.
- - DD/publish/PluginName is created if it does not exist.
- - `X` is a run number created and stored as a file in DD
- - Used to update your plugin version number in the meta file.
- - Consider, from other guides, how you might use this along w/ your meta file versioning number system.
- - Given the name `PluginName_run_number`.
- - Manually updatable; will continue to increment up, starting from the integer you set.
- - Appended to the VAR filename.
- - Used to update your plugin version number in the meta file.
- - A `PluginName.cslist` file
- lists all var-destined .cs files to be created/updated
- in special cases, you may still have to make some manual additions
- and/or, you can edit the script to your preferences.
- in special cases, you may still have to make some manual additions
- - included in top level of VAR package, and copied to DD/PluginName/
- lists all var-destined .cs files to be created/updated
- Prerequisites: (available through most distro package managers - ie. sudo apt install...)
- jq, for querying.
- You might find this useful for modifying the script, in the case your assets themselves are not purely scripts.
- zip
- Any viable compression tool is fine. Just chose a friendly-named one for recognizability.
- jq, for querying.
Bash:
#!/bin/bash
CREATOR_NAME="EntityCX"
# Assure the plugin/directory name is provided as an argument
if [ -z "$1" ]; then
echo "Usage: $0 <PLUGIN_NAME>"
exit 1
fi
PLUGIN_NAME="$1"
# Define the publish path
PUBLISH_PATH="publish/Custom/Scripts/${CREATOR_NAME}/${PLUGIN_NAME}"
# Define the path to the run_number file for the plugin
RUN_NUMBER_FILE="${PLUGIN_NAME}_run_number"
# Initialize or increment run number
RUN_NUMBER=$(cat "$RUN_NUMBER_FILE" 2>/dev/null || echo 0)
echo $((RUN_NUMBER + 1)) > "$RUN_NUMBER_FILE"
# Create empty publish directory if it does not exist
mkdir -p "$PUBLISH_PATH"
find "$PUBLISH_PATH" -mindepth 1 -delete
# Copy all non-project and debug files to the publish path
#cp -R "${PLUGIN_NAME}"/* "$PUBLISH_PATH/"
# Copy files to the publish path, excluding .csproj and .sln files
find "${PLUGIN_NAME}/" -mindepth 1 -maxdepth 1 \( -type f -o -type d \) \
! -name "*.csproj" \
! -name "*.sln" \
! -name ".*" \
! -path "${PLUGIN_NAME}/bin" -prune \
! -path "${PLUGIN_NAME}/obj" -prune \
! -path "${PLUGIN_NAME}/.*" -prune \
-exec cp -R {} "$PUBLISH_PATH/" \;
# Generate the content list
CONTENT_LIST=$(find "$PUBLISH_PATH" \
\( -path "*/bin" -o -path "*/obj" \) -prune -o -type f ! -name ".*" \
! -iname "*.md" ! -iname "*.var" ! -iname "*.sln" ! -iname "*.csproj" \
-printf "Custom/Scripts/${CREATOR_NAME}/${PLUGIN_NAME}/%P\n" | \
jq -R . | jq -s .)
# Create the .cslist file
CS_LIST_FILE="${PUBLISH_PATH}/${PLUGIN_NAME}.cslist"
echo "$CONTENT_LIST" | jq -r '.[] | select(endswith(".cs"))' | sed "s|Custom/Scripts/${CREATOR_NAME}/${PLUGIN_NAME}/||" > "$CS_LIST_FILE"
# Copy the .cslist file to the plugin's root directory
cp "$CS_LIST_FILE" "${PLUGIN_NAME}/"
# Create .hide files for .cs files not in the root of PUBLISH_PATH
echo "$CONTENT_LIST" | jq -r '.[] | select(endswith(".cs"))' | while read -r cs_file; do
if [[ "$cs_file" == */*/*/* ]]; then # Check if there's a directory structure after Custom/Scripts/CreatorName/PluginName/
touch "$PUBLISH_PATH/${cs_file#Custom/Scripts/${CREATOR_NAME}/${PLUGIN_NAME}/}.hide"
fi
done
# Create the meta.json file, with generated content list
cat <<EOF > publish/meta.json
{
"licenseType": "CC BY-SA",
"creatorName": "${CREATOR_NAME}",
"packageName": "${PLUGIN_NAME}",
"includeVersionsInReferences": "true",
"description": "v0.1.${RUN_NUMBER} ${PLUGIN_NAME} Plugin",
"credits": "",
"instructions": "",
"promotionalLink": "",
"programVersion": "1.20.0.1",
"contentList": ${CONTENT_LIST},
"dependencies": {}
}
EOF
# Change to the publish directory
cd publish
# Create the var file with the incremented run number
VAR_FILE="${CREATOR_NAME}.${PLUGIN_NAME}.${RUN_NUMBER}.var"
echo $CONTENT_LIST | jq -r '.[]' | xargs zip -r "$VAR_FILE"
# Add the meta.json file to the var
zip -r "$VAR_FILE" meta.json
CONTENT_LIST=""
CS_LIST_FILE=""