他喵的又在搞飛機了..=ω=a
他喵的又在搞飛機了
2019年9月20日 星期五
[教學]如何把Github上面的.netStandard專案自動部屬到Nuget.org(使用Appveyor和build.cake)
# 前言 :
最近在寫專案
想說趁機試一下如何把自動化佈署
把`.netStandard`的專案部屬到`nuget`上
.
結果找了好久發現大家教學寫得都不一樣
三洨
.
找了找最後覺得[這篇](https://dev.to/joaofbantunes/creating-a-cicd-pipeline-for-a-net-library-part-1---intro-2j61?fbclid=IwAR2P8wr3x75airwMQLkpyFC73DZFDXF1l1JZna_XfvG_7L2mdXa45kQo674)寫得最好
就整理一下心得好了
.
# 佈署方式 :
簡單來說,CI(持續整合) CD(自動佈署)有好幾種方法
最基本的兩種
1. CI/CD 供應商(例如`Appveyor`)會提供自己的設定檔和格式,通常是`appveyor.yml `
可以在裡面設定一些參數
優點是快速上手,通常自動測試設定很快就完成了
但缺點是不同的自動化平台的設定方式會有些差別
2. 叫CI跑自己設定好的腳本
雖然說多了幾個不明所以的檔案會有點礙眼
但如果哪天要從`appveyor`換到`Tr@vis CI`,只要讓`travis.yml`跑自己寫好的腳本就好了
.
還有本地也可以執行腳本,不需要等到push後才知道跑出來的結果
.
內建的參數有點玩膩了(並沒有
就來玩玩看用腳本自動佈署的方式好了
.
# 執行流程
先簡單說明一下執行過程好了,以`Appveyor`為例
在跑CI/CD時
.
執行的流程大概會是 :
1. `Appveyor`會抓取專案內的`appveyor.yml`設定
2. 然後讓`Appveyor`執行`build.ps1`
並且帶入參數,例如`目前執行的branch`,還有`nuget上傳的金鑰`等等
3. `build.ps1`再執行`build.cake`,會把剛剛的那些參數傳過去
4. `build.cake`會定義一些流程,然後可以根據`不同參數`執行`不同動作`
假如在`master`上,就會自動佈署
如果是`develop`或是其他Branch,就只跑測試就好
.
所以說,跑腳本可以做的事情,會比`appveyor.yml`上面設定參數的自由度更高
.
# 腳本(build.cake)
這邊的說明方式是直接把整份`build.cake`直接翻開來加上註解做說明
也可以從[這邊](https://github.com/osu-Karaoke/LyricMaker/blob/develop/build.cake)看
.
首先,先產生`build.ps1`檔
詳細的方法可以參考[這邊](https://dotblogs.com.tw/mileslin/2016/04/23/124859)
.
自動產生出來的`build.ps1`不用動他
.
接下來新增`build.cake`
然後複製[這邊](https://github.com/osu-Karaoke/LyricMaker/blob/develop/build.cake)的內容過去
然後在修改成自己想要的樣子
.
這邊簡單說明一下這份`build.cake`工作方式是
平常PR時跑測試
如果在`master`上做事或是有東西合併進來,就佈署一份到`nuget.org`上
.
如果大家要做的事情也差不多
就只要修改`上面的參數名稱`就好了
```csharp
// 這邊不用管他,簡單來說當作要引用nuget的感覺
#tool "nuget:?package=coveralls.io&version=1.4.2"
#addin Cake.Git
#addin nuget:?package=Nuget.Core
#addin "nuget:?package=Cake.Coveralls&version=0.9.0"
// 因為要丟到nuget上所以using這個package
using NuGet;
// 預設要執行的項目
var target = Argument("target", "Default");
// 產生出來的nuget要放這個目錄
var artifactsDir = "./artifacts/";
// 方案位置,要改成自己的方案名稱
var solutionPath = "./LyricMaker.sln";
// 要包成nuget的專案,要改成自己的方案名稱
var project = "./LyricMaker/LyricMaker.csproj";
// 測試目錄,和對應需要測試的方案名稱,也是要改
var testFolder = "./LyricMaker.Tests/";
var testProject = testFolder + "LyricMaker.Tests.csproj";
// CodeCoverage清單,但不才暫時沒需要所以有註解調
var coverageResultsFileName = "coverage.xml";
// 從丟進來的參數中取得目前Branch名稱
var currentBranch = Argument("currentBranch", GitBranchCurrent("./").FriendlyName);
// 判斷是不是master
var isReleaseBuild = string.Equals(currentBranch, "master", StringComparison.OrdinalIgnoreCase);
// 預設是Release
var configuration = "Release";
// 從丟進來的參數中取得nuget金鑰和codecoverage(目前沒用到)的金鑰
var nugetApiKey = Argument("nugetApiKey", null);
var coverallsToken = Argument("coverallsToken", null);
// nuget.org網址
var nugetSource = "https://api.nuget.org/v3/index.json";
// 定義任務,把空間清乾淨
Task("Clean")
.Does(() => {
if (DirectoryExists(artifactsDir))
{
DeleteDirectory(
artifactsDir,
new DeleteDirectorySettings {
Recursive = true,
Force = true
}
);
}
CreateDirectory(artifactsDir);
DotNetCoreClean(solutionPath);
});
// 定義任務,載入nuget
Task("Restore")
.Does(() => {
DotNetCoreRestore(solutionPath);
});
// 定義任務,建置
Task("Build")
.IsDependentOn("Clean")
.IsDependentOn("Restore")
.Does(() => {
DotNetCoreBuild(
solutionPath,
new DotNetCoreBuildSettings
{
Configuration = configuration
}
);
});
// 定義任務,跑測試
Task("Test")
.Does(() => {
var settings = new DotNetCoreTestSettings
{
ArgumentCustomization = args => args.Append("/p:CollectCoverage=true")
.Append("/p:CoverletOutputFormat=opencover")
//.Append("/p:CoverletOutput=./" + coverageResultsFileName)
};
DotNetCoreTest(testProject, settings);
//MoveFile(testFolder + coverageResultsFileName, artifactsDir + coverageResultsFileName);
});
// 定義任務,上傳跑任務時產生的Code coverage結果
Task("UploadCoverage")
.IsDependentOn("Test")
.Does(() =>
{
CoverallsIo(artifactsDir + coverageResultsFileName, new CoverallsIoSettings()
{
RepoToken = coverallsToken
});
});
// 定義任務,包成nuget
Task("Package")
.Does(() => {
var settings = new DotNetCorePackSettings
{
OutputDirectory = artifactsDir,
NoBuild = true
};
DotNetCorePack(project, settings);
});
// 定義任務,把nuget上傳
Task("Publish")
.IsDependentOn("Package")
.Does(() => {
var pushSettings = new DotNetCoreNuGetPushSettings
{
Source = nugetSource,
ApiKey = nugetApiKey
};
var pkgs = GetFiles(artifactsDir + "*.nupkg");
foreach(var pkg in pkgs)
{
if(!IsNuGetPublished(pkg))
{
Information($"Publishing \"{pkg}\".");
DotNetCoreNuGetPush(pkg.FullPath, pushSettings);
}
else {
// 如果看到這個訊息,代表專案的nuget版本號在nuget.org上已經有了
Information($"Bypassing publishing \"{pkg}\" as it is already published.");
}
}
});
// Check nuget package is published
private bool IsNuGetPublished(FilePath packagePath) {
var package = new ZipPackage(packagePath.FullPath);
var latestPublishedVersions = NuGetList(
package.Id,
new NuGetListSettings
{
Prerelease = true
}
);
return latestPublishedVersions.Any(p => package.Version.Equals(new SemanticVersion(p.Version)));
}
// 定義任務,這個任務要完成編譯和測試
Task("BuildAndTest")
.IsDependentOn("Build")
.IsDependentOn("Test");
// 定義任務,這個任務要完成編譯,測試和上傳結果
Task("CompleteWithoutPublish")
.IsDependentOn("Build")
.IsDependentOn("Test");
//.IsDependentOn("UploadCoverage");
if(isReleaseBuild)
{
// 定義完成任務
// 玩成任務就是執行編譯,測試和佈署到nuget
Information("Release build");
Task("Complete")
.IsDependentOn("Build")
.IsDependentOn("Test")
//.IsDependentOn("UploadCoverage")
.IsDependentOn("Publish");
}
else
{
// 定義完成任務
// 完成任務就只需要跑編譯和測試
Information("Development build");
Task("Complete")
.IsDependentOn("Build")
.IsDependentOn("Test");
//.IsDependentOn("UploadCoverage");
}
// 定義預設任務是 完成任務
Task("Default")
.IsDependentOn("Complete");
// 執行預設任務
RunTarget(target);
```
# 腳本(appveyor.yml)
接下來新增`build.cake`
然後複製[這邊](https://github.com/osu-Karaoke/LyricMaker/blob/develop/build.cake)的內容過去
也是在修改成自己想要的樣子
.
也是說明一下專案格式
這樣比較好懂
```yml
# 建置版本
version: "{build}"
# 使用的環境
image: Visual Studio 2017
# 定義只有在那些Branch上Appveyor才做事
# 因為不才希望丟Pull Request也要跑CI,所以就註解掉了
#branches:
# only:
# - master
# - develop
# 環境
environment:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
NUGET_API_KEY:
# 金藥需要加密,下面會說明
secure: SCmDP3tOoIfO4zexfzu07xjBnv1KDMNDljU1iKZqU1VCTwyZ8pcAi5aLa5SMmwzh
# Appveyor要做的事情就是執行build.ps1,build.ps1就會執行build.cake
# 然後帶入參數
build_script:
- ps: .\build.ps1 --currentBranch=$env:APPVEYOR_REPO_BRANCH --nugetApiKey=$env:NUGET_API_KEY --coverallsToken=$env:COVERALLS_TOKEN
# 把內建的測試和佈署關掉
test: off #tests handled by cake script
deploy: off #deploy handled by cake script
```
.
在把Nuget自動上傳到`nuget.org`時,會需要一組金鑰
取得金鑰的教學在[這邊](https://docs.microsoft.com/zh-tw/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli#acquire-your-api-key)可以看到
.
直接把取得到的金鑰放在`appveyor.yml`
會讓所有取得金鑰的人
能夠直接用金鑰佈署專案,相當危險,所以需要加密
.
需要在[這邊](https://ci.appveyor.com/tools/encrypt)
把從`nuget.org`拿到的金鑰貼上後
會得到(比較長)加密後的金鑰
.
這組(比較長)加密後的金鑰
就可以任意丟在網路上沒問題了
.
# 後言
在摸了半天,知道整個運作流程後
就沒那麼難了
.
大家加油ㄅ
.
2019年9月2日 星期一
[開箱]少女終末旅行 千都 黏土人
前言 :
之前被問到要不要先到博弈遊戲公司幫忙
雖然算是有點逼不得已(?)結果不才居然答應了
三洨
.
然後第一次領到超級厚的薪水袋時
阿斯
.
之後就看著辦吧ODO
那邊好像是多角經營,想點辦法盡量不要去做博弈遊戲部分吧
.
是說就算真的只是普通的遊戲公司
好像也沒好到哪就是了
不才討厭做遊戲
.
寫遊戲又不好賺
薪水低
沒加班還要感謝公司感謝得五體投地
.
來寫後端多輕鬆
是不是呢(#
.
然後這次的黏土人一次買了兩隻
所以就分兩次開箱文吧
.
正文 :

開箱
一次開兩隻
.
有錢人的快樂
往往就是這麽樸實無華
且枯燥
.
ㄍ你角川
.
雖然說有兩隻
但這次開的是左邊的千都
.
開
.
正面配件
.
背面的頭盔
.
沒戴頭盔的正面
.
側面
.
背面
.
另外一個側面
.
戴上帽子的正面
看起來可愛多了
.
側面
.
背面
.
另外一個側面
.
不知道為什麼
支架很難安裝上去
.
背包
.
經過了幾百隻黏土人的進化
和喪女的背包比起來
這個好裝多了
.
只要往後卡就可以了
而且材質是軟的
不用像喪女的還要擔心會不會把背包的肩帶弄斷
.
然後有付上一根塑膠棒
插在背包上就可以固定黏土人了
.
但很詭異的,黏土人會懸空
.
最後還是決定打開說明書看看
確認之前安裝的方式沒有問題
.
除了原本的臉,還有另外付上兩張表情
.
不是不才在吐槽
把表情遮住的話
前面兩張臉根本看不出差別阿
.
原本的臉
.
嘴巴表情加上幾個pixel後的笑臉
.
額...好吧
.
然後上看智障的臉
.
這時候千續就派上用場了
.
ㄌㄨㄝ
.
哦幹幹幹最好不要過來喔
.
(千都)乾我以後絕對不要成為這種人
.
下一個就換你了
.
幹到的相機超讚的啦
.
千都的日記
.
腳配件
.
......
.
應該是這樣插下去吧?
.
雖然說說明書沒寫但不才直覺好像不是這樣
這個腳部配件應該是配合(DLC)半履帶型摩托車用的
.
然後意外的發現可以不需要配件就可以直立(!!!!!)
.
只是不知道為什麼
總覺得
突然想到植物大戰殭屍裡面的殭屍
.
換上喪女臉後
更像僵屍了
.
走開
.
總之今天的黏土人開箱就寫到這邊
下一篇是尤莉的黏土人開箱
之前被問到要不要先到博弈遊戲公司幫忙
雖然算是有點逼不得已(?)結果不才居然答應了
三洨
.
然後第一次領到超級厚的薪水袋時
阿斯
.
之後就看著辦吧ODO
那邊好像是多角經營,想點辦法盡量不要去做博弈遊戲部分吧
.
是說就算真的只是普通的遊戲公司
好像也沒好到哪就是了
不才討厭做遊戲
.
寫遊戲又不好賺
薪水低
沒加班還要感謝公司感謝得五體投地
.
來寫後端多輕鬆
是不是呢(#
.
然後這次的黏土人一次買了兩隻
所以就分兩次開箱文吧
.
正文 :
開箱
一次開兩隻
.
有錢人的快樂
往往就是這麽樸實無華
且枯燥
.
ㄍ你角川
.
雖然說有兩隻
但這次開的是左邊的千都
.
開
.
正面配件
.
背面的頭盔
沒戴頭盔的正面
.
側面
.
背面
.
另外一個側面
.
戴上帽子的正面
看起來可愛多了
.
側面
.
背面
.
另外一個側面
.
不知道為什麼
支架很難安裝上去
.
背包
.
經過了幾百隻黏土人的進化
和喪女的背包比起來
這個好裝多了
.
只要往後卡就可以了
而且材質是軟的
不用像喪女的還要擔心會不會把背包的肩帶弄斷
.
然後有付上一根塑膠棒
插在背包上就可以固定黏土人了
.
但很詭異的,黏土人會懸空
.
最後還是決定打開說明書看看
確認之前安裝的方式沒有問題
.
除了原本的臉,還有另外付上兩張表情
.
不是不才在吐槽
把表情遮住的話
前面兩張臉根本看不出差別阿
.
原本的臉
.
嘴巴表情加上幾個pixel後的笑臉
.
額...好吧
.
然後上看智障的臉
.
這時候千續就派上用場了
.
ㄌㄨㄝ
哦幹幹幹最好不要過來喔
.
(千都)乾我以後絕對不要成為這種人
.
下一個就換你了
.
幹到的相機超讚的啦
.
千都的日記
.
腳配件
.
......
.
應該是這樣插下去吧?
.
雖然說說明書沒寫但不才直覺好像不是這樣
這個腳部配件應該是配合(DLC)半履帶型摩托車用的
.
然後意外的發現可以不需要配件就可以直立(!!!!!)
.
只是不知道為什麼
總覺得
突然想到植物大戰殭屍裡面的殭屍
.
換上喪女臉後
更像僵屍了
.
走開
.
總之今天的黏土人開箱就寫到這邊
下一篇是尤莉的黏土人開箱
2019年7月16日 星期二
[Azure] asp.net core 專案出現 set 'CopyRefAssembliesToPublishDirectory' to true 錯誤
前言 :
最近被認識的人問到
給我原本薪水的1.5倍
然後過去他們那邊工作
.
如果只是跳槽的話
不才當然馬上去問老闆明天能不能不要來了
.
但很不巧的
是做博弈
.
有點好奇
如果可以增加一點五倍的薪水,大家會改去做博弈(的遊戲)嗎?
.
雖然站在不才的角度來想
不才只是提供你遊戲玩
恩,娛樂的一種
雖然不太好
.
嘛,就跟垃圾食物一樣嘛
雖然傷身體但大家都愛吃
.
但單把進來玩的人當羊宰
說真的有實在有點過意不去
而且會把手弄髒
.
後來和朋友聊到後
他提到了課金手游....
.
:thinking: :thinking: :thinking:
.
究竟賭博
和課金手游
到底有什麼不同呢
為啥不才會排斥博弈
卻不會排斥做手游
.
正文 :
回到正題
在使用azure的時候有時候會因為懶惰
直接把檔案按下右鍵publish到azure上
.
在某些程度上不才用得挺開心的
尤其在修改.cshtml時
真是方便(菸
.
但很不巧地今天踢到了鐵板
出現了這個畫面
.
恩,上面簡單是說
把 CopyRefAssembliesToPublishDirectory 打開
.
但不才試過根本沒用RRR
為啥只是在cshtml加上css然後按下publish就會變成這樣
.
後來發現
在有些專案中
例如這次不才改的grandnode
https://grandnode.com/
.
有些.cshtml是直接以檔案形式丟到azure上面的server
例如前台的佈景主題
.
另外有些則是包在dll內
例如Area裡面後台管理上的.cshtml
.
......
.
解決方式就是進到server內
把剛才丟上去的檔案(.cshtml)砍掉
就正常了
.
結論 :
白生氣了
.
最近被認識的人問到
給我原本薪水的1.5倍
然後過去他們那邊工作
.
如果只是跳槽的話
不才當然馬上去問老闆明天能不能不要來了
.
但很不巧的
是做博弈
.
有點好奇
如果可以增加一點五倍的薪水,大家會改去做博弈(的遊戲)嗎?
.
雖然站在不才的角度來想
不才只是提供你遊戲玩
恩,娛樂的一種
雖然不太好
.
嘛,就跟垃圾食物一樣嘛
雖然傷身體但大家都愛吃
.
但單把進來玩的人當羊宰
說真的有實在有點過意不去
而且會把手弄髒
.
後來和朋友聊到後
他提到了課金手游....
.
:thinking: :thinking: :thinking:
.
究竟賭博
和課金手游
到底有什麼不同呢
為啥不才會排斥博弈
卻不會排斥做手游
.
正文 :
回到正題
在使用azure的時候有時候會因為懶惰
直接把檔案按下右鍵publish到azure上
.
在某些程度上不才用得挺開心的
尤其在修改.cshtml時
真是方便(菸
.
但很不巧地今天踢到了鐵板
出現了這個畫面
.

恩,上面簡單是說
把 CopyRefAssembliesToPublishDirectory 打開
.
但不才試過根本沒用RRR
為啥只是在cshtml加上css然後按下publish就會變成這樣
.
後來發現
在有些專案中
例如這次不才改的grandnode
https://grandnode.com/
.
有些.cshtml是直接以檔案形式丟到azure上面的server
例如前台的佈景主題
.
另外有些則是包在dll內
例如Area裡面後台管理上的.cshtml
.
......
.
解決方式就是進到server內
把剛才丟上去的檔案(.cshtml)砍掉
就正常了
.
結論 :
白生氣了
.
2019年5月19日 星期日
[開箱] 980 邪神與廚二病少女 邪神醬黏土人
前言 :
終於狠心來換哀鳳了
換完後整個順到不行
感覺就像是從雨衣變成短裙
還是真空的那種
.
真不虧是蘋果
除了購買價格和維修價格和哀鳳難用到死的鍵盤
和2016年後的Macbook Pro系列外
沒讓我失望過
.
還有下次寫部落格換個地方好了
便利商店有夠吵
.
正文 :
開箱箱
.

這次月子大人表示有點興趣
希望能夠一起開箱
.
月子 : 關我屁事
.


首先是這個箱子
.


被打開後
哇,裡面有黏土人誒
讚讚
.

正面
.

側面
.

背面
.

另外一個側面
.
月子 : 啊所以是好了沒?
.

好ㄅ
月子去其他地方玩了
只能放在桌上開了
.

開開
.

將將
.
先看一下本體
.

架子方面除了老樣子外
多出根東西
.

可以把它插上去
然後黏土人就立在上面了
.
讚讚
.

黏土人正面
.

側面
.

背面
.

另外一個側面
.
不才發現打這幾段字的速度最快
.

然後其他的配件
.

臉有這兩個
.

不知道即將尾巴要被切掉的憨臉
.

還有meme臉
就是那個
很難描述的但第二格還是第三格的臉看起來87%像的meme
.
翻了半小時的好色龍還是沒有找到
算了,自己拍好了
.


還有這個尾巴是可以左右擺動的喔 <3
.

然後是奶子(轉頭看看FB在不在旁邊
.
雖然從一開始都很巧妙的被頭髮遮住
但實際上是有的喔
真的可以露出來的喔
.
而且感覺比動畫中還大
幾乎是たわわ等級的
.
唯一美中不足的
沒有設計得像たわわ一樣有觸感
就只是片
比較浮誇的塑膠
.

然後身體是可拆的
.

裝上另外一片尾巴
.

將將
.

然後
把原本的尾巴加上配件
.

恭喜
Buy one and get one free.
.
物超所值
感謝好微笑,讚嘆好微笑
.
反正都是被砍
哪邊噴血都沒差啦(X
.

尾巴正面
.

側面
.

背面
.

另外一個側面(誒
.

裝上另外一個尾巴的正面
.

側面
.

背面
.

另外一個側面
.



噴點血吧
.

然後很神奇的
這個噴血的配件
.

可以被拆開
.

應該是為了塑造那種
噴血但其實沒有真的噴很多
的那種感覺吧
.
額大概
.

(乾還是很痛好不好
.

蛇蛇 <3
.

幹幹幹幹幹這不是裙子RRRR
沒看到我痛死了嗎
.

快死掉了RRRR
.






然後是一些手手的動作
.

最後是那個一直都找不到的meme
.
恩....
到底是多少R
.

轉頭
.

(2啊,北漆)
.

應該是這樣吧
.

...好喔
.
以上
.
2019/5/21:
額終於找到了
後文 :

買一送一
物超所值
高雄發大財
.
然後發現圖被部落格壓糊了
幹
難怪不才以前寫文章時總覺得照片不管怎麼拍都覺得不夠銳利
雞掰
.
工程師 :
沒辦法,有一個奇怪的用戶每次寫文章都上傳好幾百MB的相片上來
.
好啦原圖就順便附上連結好了
感謝Google相片,讚嘆Google相片
https://photos.app.goo.gl/3TLoHw7qjPQE66tg6
.

最後新做好的逐格動畫專用拍攝櫃(半廢棄中)
終於有那麼一點點用處了
可喜可賀
.
這份轉載至 http://blog.udn.com/andy840119/126789987
先測試看看效果好不好ODO
.
終於狠心來換哀鳳了
換完後整個順到不行
感覺就像是從雨衣變成短裙
還是真空的那種
.
真不虧是蘋果
除了購買價格和維修價格和哀鳳難用到死的鍵盤
和2016年後的Macbook Pro系列外
沒讓我失望過
.
還有下次寫部落格換個地方好了
便利商店有夠吵
.
正文 :
開箱箱
.

這次月子大人表示有點興趣
希望能夠一起開箱
.
月子 : 關我屁事
.


首先是這個箱子
.


被打開後
哇,裡面有黏土人誒
讚讚
.

正面
.

側面
.

背面
.

另外一個側面
.
月子 : 啊所以是好了沒?
.

好ㄅ
月子去其他地方玩了
只能放在桌上開了
.

開開
.

將將
.
先看一下本體
.

架子方面除了老樣子外
多出根東西
.

可以把它插上去
然後黏土人就立在上面了
.
讚讚
.

黏土人正面
.

側面
.

背面
.

另外一個側面
.
不才發現打這幾段字的速度最快
.

然後其他的配件
.

臉有這兩個
.

不知道即將尾巴要被切掉的憨臉
.

還有meme臉
就是那個
很難描述的但第二格還是第三格的臉看起來87%像的meme
.
翻了半小時的好色龍還是沒有找到
算了,自己拍好了
.


還有這個尾巴是可以左右擺動的喔 <3
.

然後是奶子(轉頭看看FB在不在旁邊
.
雖然從一開始都很巧妙的被頭髮遮住
但實際上是有的喔
真的可以露出來的喔
.
而且感覺比動畫中還大
幾乎是たわわ等級的
.
唯一美中不足的
沒有設計得像たわわ一樣有觸感
就只是片
比較浮誇的塑膠
.

然後身體是可拆的
.

裝上另外一片尾巴
.

將將
.

然後
把原本的尾巴加上配件
.

恭喜
Buy one and get one free.
.
物超所值
感謝好微笑,讚嘆好微笑
.
反正都是被砍
哪邊噴血都沒差啦(X
.

尾巴正面
.

側面
.

背面
.

另外一個側面(誒
.

裝上另外一個尾巴的正面
.

側面
.

背面
.

另外一個側面
.



噴點血吧
.

然後很神奇的
這個噴血的配件
.

可以被拆開
.

應該是為了塑造那種
噴血但其實沒有真的噴很多
的那種感覺吧
.
額大概
.

(乾還是很痛好不好
.

蛇蛇 <3
.

幹幹幹幹幹這不是裙子RRRR
沒看到我痛死了嗎
.

快死掉了RRRR
.






然後是一些手手的動作
.

最後是那個一直都找不到的meme
.
恩....
到底是多少R
.

轉頭
.

(2啊,北漆)
.

應該是這樣吧
.

...好喔
.
以上
.
2019/5/21:
額終於找到了
後文 :

買一送一
物超所值
高雄發大財
.
然後發現圖被部落格壓糊了
幹
難怪不才以前寫文章時總覺得照片不管怎麼拍都覺得不夠銳利
雞掰
.
工程師 :
沒辦法,有一個奇怪的用戶每次寫文章都上傳好幾百MB的相片上來
.
好啦原圖就順便附上連結好了
感謝Google相片,讚嘆Google相片
https://photos.app.goo.gl/3TLoHw7qjPQE66tg6
.

最後新做好的逐格動畫專用拍攝櫃(半廢棄中)
終於有那麼一點點用處了
可喜可賀
.
這份轉載至 http://blog.udn.com/andy840119/126789987
先測試看看效果好不好ODO
.
訂閱:
意見 (Atom)

