Skip to content

Commit 25e4788

Browse files
authored
Merge pull request #38 from Toys0125/Fix-old-documation
Fix old documation and improve the upload section.
2 parents 29004e8 + 46287cc commit 25e4788

3 files changed

Lines changed: 220 additions & 6 deletions

File tree

content/docs/avatar/building.mdx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import { Callout } from 'fumadocs-ui/components/callout';
66

77
## Avoid Duplicate GameObjects
88

9-
- Ensure that there are **NO** duplicate named GameObjects within the hierarchy of your avatar, including the armature, as this will cause your avatar to fail to load after building the AssetBundle.
9+
- Basis Avatar will by default rename all duplicate name GameObjects within the avatar's hierarchy.
10+
<Callout type="warning">
11+
If you enable `Do not auto-rename bones` in the Processing Options. Ensure that there are **NO** duplicate named GameObjects within the hierarchy of your avatar, including the armature, as this will cause your avatar to fail to load after building the AssetBundle.
12+
</Callout>
1013

1114
## Build the AssetBundle
1215

content/docs/avatar/uploading.mdx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
---
22
title: Uploading
33
---
4-
4+
import { Step, Steps } from 'fumadocs-ui/components/steps';
55
import { Callout } from 'fumadocs-ui/components/callout';
6+
import { UrlConverter } from '@/components/UrlConverter';
67

78
## Uploading Your Avatar
89

910
Basis allows you to load an Avatar .BEE file from a remote URL location, which is also required for other users in a networked session to also load the assets.
1011

12+
<Callout type="info">
13+
You can add your avatar password directly into the url for your .BEE file by `https://locationofBeefile.BEE#(Base64Encode(Password))`<br />
14+
Which you are appending `#` and Base64Encoded string of your password.
15+
</Callout>
16+
1117
In order to support this, you will need to direct link to a remote location. For this example, we will use Google Drive.
1218

1319
(Google Drive supports the direct link of files up to 100MB due to their Virus Scanning policy.)
@@ -23,6 +29,8 @@ Now when you drag your files into this Folder, you will not individually need to
2329

2430
We will need to look into the URL to grab the information we need for your BEE file.
2531

32+
33+
2634
Example:
2735
```
2836
https://drive.google.com/file/d/YourIDBringsAllTheLagToMyYard/view?usp=sharing
@@ -37,35 +45,51 @@ Example:
3745
```
3846
https://drive.google.com/uc?export=download&id=YourIDBringsAllTheLagToMyYard
3947
```
48+
<UrlConverter />
4049

4150
<Callout type="warn">
4251
**DO NOT UPLOAD YOUR GENERATED PASSWORD FILE OR SHARE IT**
4352
</Callout>
4453

4554
## Loading in Basis
55+
<Steps>
4656

57+
<Step>
4758
Load up Basis, open the menu, and select Avatars.
4859

4960
![Basis menu](/img/avatars/11.png)
61+
</Step>
5062

63+
<Step>
5164
In the Avatar menu, select 'New Avatar' near the top of the window.
5265

5366
![Add Avatar button](/img/avatars/12.png)
67+
</Step>
5468

69+
70+
<Step>
5571
Paste the **BEE File URL** into the Avatar URL field and the **SUPER SECRET ENCRYPTED PASSWORD** into the Avatar Password field.
5672

5773
![BEE file URL & password](/img/avatars/13.png)
74+
</Step>
5875

76+
<Step>
5977
Click the Add button and the avatar should then automatically load!
6078

6179
![Add BEE file button](/img/avatars/14.png)
80+
</Step>
81+
</Steps>
6282

63-
You will see your avatar appear at the bottom of the avatar list on the left (1) and the details of the avatar, such as the timestamp of when it was compiled, along with the Title and Description (2)
64-
65-
This window will also show icons to indicate compatibility across various OS platforms (3).
83+
## Avatar Details
6684

6785
![New Avatar details](/img/avatars/15.png)
6886

87+
Once your avatar is loaded, you'll see the following in the Avatar Details panel:
88+
89+
- **(1) Avatar List** - Your avatar appears at the bottom of the avatar list on the left side
90+
- **(2) Avatar Information** - The details panel displays the compilation timestamp, Title, and Description
91+
- **(3) Platform Compatibility** - Icons indicate which OS platforms support this avatar
92+
6993

7094
## Remove Avatars
7195

@@ -75,6 +99,6 @@ Avatars can be removed by clicking on the Avatar in the menu and hitting the red
7599

76100
To remove all saved avatar information, outside of the game interface, you can also do the following:
77101

78-
- Delete `%appdata%\..\LocalLow\Basis Unity\Basis Unity\VerySafePasswordStore.json`.
102+
- Delete `%appdata%\..\LocalLow\Basis Unity\Basis Unity\KeyStore.json`.
79103

80104
When you next reload the game the previously stored Avatars will now be gone.

src/components/UrlConverter.tsx

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
'use client';
2+
3+
import { useState } from 'react';
4+
import { Copy, Check } from 'lucide-react';
5+
6+
export function UrlConverter() {
7+
const [mode, setMode] = useState<'google-drive' | 'custom-domain'>('google-drive');
8+
const [inputUrl, setInputUrl] = useState('');
9+
const [inputPassword, setInputPassword] = useState('');
10+
const [outputUrl, setOutputUrl] = useState('');
11+
const [copied, setCopied] = useState(false);
12+
13+
const encodeBase64Utf8 = (str: string) => {
14+
try {
15+
return btoa(encodeURIComponent(str));
16+
} catch {
17+
try {
18+
return btoa(str);
19+
} catch {
20+
return '';
21+
}
22+
}
23+
};
24+
25+
const extractAndConvert = (url: string) => {
26+
const match = url.match(/\/d\/([a-zA-Z0-9-_]+)/);
27+
if (match && match[1]) {
28+
const fileId = match[1];
29+
let downloadUrl = `https://drive.google.com/uc?export=download&id=${fileId}`;
30+
if (inputPassword && inputPassword.length > 0) {
31+
const encoded = encodeBase64Utf8(inputPassword);
32+
if (encoded) downloadUrl = `${downloadUrl}#${encoded}`;
33+
}
34+
setOutputUrl(downloadUrl);
35+
return downloadUrl;
36+
}
37+
setOutputUrl('');
38+
return null;
39+
};
40+
41+
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
42+
const value = e.target.value;
43+
setInputUrl(value);
44+
if (mode === 'google-drive') {
45+
extractAndConvert(value);
46+
} else {
47+
// For custom domain, just update the output URL directly
48+
let customUrl = value;
49+
if (inputPassword && inputPassword.length > 0) {
50+
const encoded = encodeBase64Utf8(inputPassword);
51+
if (encoded) customUrl = `${customUrl}#${encoded}`;
52+
}
53+
setOutputUrl(customUrl || '');
54+
}
55+
setCopied(false);
56+
};
57+
58+
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
59+
const value = e.target.value;
60+
setInputPassword(value);
61+
// Recompute output using the existing URL and new password
62+
if (inputUrl) {
63+
if (mode === 'google-drive') {
64+
extractAndConvert(inputUrl);
65+
} else {
66+
// For custom domain, recompute with new password
67+
let customUrl = inputUrl;
68+
if (value && value.length > 0) {
69+
const encoded = encodeBase64Utf8(value);
70+
if (encoded) customUrl = `${inputUrl}#${encoded}`;
71+
}
72+
setOutputUrl(customUrl || '');
73+
}
74+
}
75+
setCopied(false);
76+
};
77+
78+
const handleModeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
79+
const newMode = e.target.value as 'google-drive' | 'custom-domain';
80+
setMode(newMode);
81+
setInputUrl('');
82+
setInputPassword('');
83+
setOutputUrl('');
84+
setCopied(false);
85+
};
86+
87+
const copyToClipboard = async () => {
88+
if (outputUrl) {
89+
await navigator.clipboard.writeText(outputUrl);
90+
setCopied(true);
91+
setTimeout(() => setCopied(false), 2000);
92+
}
93+
};
94+
95+
return (
96+
<div className="rounded-lg border border-fd-border bg-fd-card p-6 my-6">
97+
<h3 className="font-semibold mb-4">
98+
{mode === 'google-drive'
99+
? 'Google Drive Direct Link Converter'
100+
: 'Custom URL Converter'}
101+
</h3>
102+
103+
<div className="space-y-4">
104+
<div>
105+
<label className="block text-sm font-medium mb-2">
106+
Conversion Mode:
107+
</label>
108+
<select
109+
value={mode}
110+
onChange={handleModeChange}
111+
className="w-full px-3 py-2 border border-fd-border rounded-md bg-fd-background text-fd-foreground focus:outline-none focus:ring-2 focus:ring-fd-primary"
112+
>
113+
<option value="google-drive">Google Drive Link</option>
114+
<option value="custom-domain">Custom Domain</option>
115+
</select>
116+
</div>
117+
118+
<div>
119+
<label className="block text-sm font-medium mb-2">
120+
{mode === 'google-drive'
121+
? 'Paste your Google Drive Share Link:'
122+
: 'Paste your Custom Domain URL:'}
123+
</label>
124+
<input
125+
type="text"
126+
value={inputUrl}
127+
onChange={handleInputChange}
128+
placeholder={
129+
mode === 'google-drive'
130+
? 'https://drive.google.com/file/d/YOUR_FILE_ID/view?usp=sharing'
131+
: 'https://example.com/path/to/file'
132+
}
133+
className="w-full px-3 py-2 border border-fd-border rounded-md bg-fd-background text-fd-foreground placeholder-fd-muted-foreground focus:outline-none focus:ring-2 focus:ring-fd-primary"
134+
/>
135+
</div>
136+
137+
<div>
138+
<label className="block text-sm font-medium mb-2">
139+
Optional avatar password (will be base64-encoded and appended)
140+
</label>
141+
<input
142+
type="password"
143+
value={inputPassword}
144+
onChange={handlePasswordChange}
145+
placeholder="Optional password"
146+
className="w-full px-3 py-2 border border-fd-border rounded-md bg-fd-background text-fd-foreground placeholder-fd-muted-foreground focus:outline-none focus:ring-2 focus:ring-fd-primary"
147+
/>
148+
</div>
149+
150+
{outputUrl && (
151+
<div>
152+
<label className="block text-sm font-medium mb-2">
153+
Direct Download Link:
154+
</label>
155+
<div className="flex gap-2">
156+
<input
157+
type="text"
158+
value={outputUrl}
159+
readOnly
160+
className="flex-1 px-3 py-2 border border-fd-border rounded-md bg-fd-background text-fd-foreground"
161+
/>
162+
<button
163+
onClick={copyToClipboard}
164+
className="flex items-center gap-2 px-4 py-2 bg-fd-primary text-fd-primary-foreground rounded-md hover:opacity-90 transition-opacity"
165+
>
166+
{copied ? (
167+
<>
168+
<Check size={18} />
169+
<span>Copied!</span>
170+
</>
171+
) : (
172+
<>
173+
<Copy size={18} />
174+
<span>Copy</span>
175+
</>
176+
)}
177+
</button>
178+
</div>
179+
<p className="text-sm text-fd-muted-foreground mt-2">
180+
Use this link as your <strong>BEE File URL</strong> in Basis
181+
</p>
182+
</div>
183+
)}
184+
</div>
185+
</div>
186+
);
187+
}

0 commit comments

Comments
 (0)