Fix : 프로젝트 오류 제거 및 필요 리소스 업데이트
This commit is contained in:
parent
1130cce2f4
commit
09665783a5
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 gpsnmeajp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,38 +0,0 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 gpsnmeajp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EasyDeviceDiscoveryProtocolClient
|
||||
{
|
||||
[SerializeField]
|
||||
public class RequestJson {
|
||||
public const int protocolVersion = 1;
|
||||
//---------------------------------------------
|
||||
public int servicePort = 0;
|
||||
public string deviceName = "";
|
||||
public int version = 0; //初期値は無印版
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01d96cbabd46184458f5c46a2fe204c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,209 +0,0 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 gpsnmeajp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace EasyDeviceDiscoveryProtocolClient
|
||||
{
|
||||
public class Requester : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
public int discoverPort = 39500; //待受ポート
|
||||
|
||||
[Header("Properties")]
|
||||
public string deivceName = "mydevice_client";//自分のデバイス名
|
||||
public int servicePort = 11111;//自分が使ってほしいと思っているポート
|
||||
public string ignoreDeivceName = ""; //無視するデバイス名
|
||||
public bool desktopMode = false; //デスクトップモード(false: 非アクティブ時にポートを閉じる, true: 閉じない)
|
||||
|
||||
[Header("Response Info(Read only)")]
|
||||
public string responseIpAddress = ""; //応答帰ってきたアドレス
|
||||
private int responsePort = 0; //応答帰ってきたポート
|
||||
public int responseProtocolVersion = 0; //要求のプロトコルバージョン
|
||||
public int foundDevices = 0; //見つかった台数
|
||||
|
||||
[Header("Response Data(Read only)")]
|
||||
public string responseDeviceName = "";//データとして含まれるデバイス名
|
||||
public int responseServicePort = 0;//データとして含まれるポート
|
||||
|
||||
[Header("Test")]
|
||||
public bool exec = false;//テスト実行
|
||||
|
||||
public Action OnDeviceFound = null;
|
||||
|
||||
UdpClient udpClient = null;
|
||||
UTF8Encoding utf8 = new UTF8Encoding(false); //BOMなし
|
||||
|
||||
//探索開始(ボタン用)
|
||||
public void StartDiscover()
|
||||
{
|
||||
StartDiscover(() => { Debug.Log("[EDDP Requester]Found"); });
|
||||
}
|
||||
|
||||
//探索開始(外部からコールされる)
|
||||
public void StartDiscover(Action OnDeviceFound)
|
||||
{
|
||||
this.OnDeviceFound = OnDeviceFound;
|
||||
|
||||
//受信結果を初期化
|
||||
responseIpAddress = "";
|
||||
responsePort = 0;
|
||||
responseDeviceName = "";
|
||||
responseProtocolVersion = 0;
|
||||
foundDevices = 0;
|
||||
|
||||
//jsonデータ生成
|
||||
string data = JsonUtility.ToJson(new RequestJson
|
||||
{
|
||||
servicePort = servicePort,
|
||||
deviceName = deivceName,
|
||||
version = RequestJson.protocolVersion,
|
||||
});
|
||||
byte[] dat = utf8.GetBytes(data);
|
||||
|
||||
//通信を開始準備する
|
||||
TryOpen();
|
||||
|
||||
//通信を開始できる状態なら
|
||||
if (udpClient != null)
|
||||
{
|
||||
udpClient.EnableBroadcast = true; //ブロードキャスト有効
|
||||
udpClient.MulticastLoopback = true; //ループバック許可
|
||||
udpClient.Send(dat, dat.Length, "255.255.255.255", discoverPort);
|
||||
}
|
||||
}
|
||||
|
||||
//UDP通信の準備を行います
|
||||
void TryOpen() {
|
||||
//GameObjectが有効なときだけ開始する
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
if (udpClient == null)
|
||||
{
|
||||
udpClient = new UdpClient();
|
||||
Debug.Log("[EDDP Requester]UdpClient Open");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//UDP通信の停止を行います。
|
||||
void Close()
|
||||
{
|
||||
if (udpClient != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
udpClient?.Close();
|
||||
Debug.Log("[EDDP Requester]UdpClient Closed");
|
||||
}
|
||||
finally
|
||||
{
|
||||
udpClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//GameObjectがEnableになったとき開く
|
||||
private void OnEnable()
|
||||
{
|
||||
TryOpen();
|
||||
}
|
||||
|
||||
//GameObjectがDisableになったとき閉じる
|
||||
private void OnDisable()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//GameObjectが破棄されるとき閉じる
|
||||
private void OnDestroy()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//アプリケーションが終了するとき閉じる
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//アプリケーションが中断・復帰したとき(モバイルでバックグラウンドになった・エディタで別のフォーカスを当てられたとき)
|
||||
private void OnApplicationPause(bool pause)
|
||||
{
|
||||
//モバイルデバイス向けなので、デスクトップモードでは行わない
|
||||
if (!desktopMode)
|
||||
{
|
||||
if (pause)
|
||||
{
|
||||
//アプリが閉じられたら止める
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
//アプリが開かれたので開く
|
||||
TryOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//毎フレームループ。UDPパケットの受信処理を行う
|
||||
void Update()
|
||||
{
|
||||
if (exec) {
|
||||
exec = false;
|
||||
StartDiscover(() => { Debug.Log("[EDDP Requester]Found"); });
|
||||
}
|
||||
|
||||
if (udpClient != null)
|
||||
{
|
||||
while (udpClient.Available > 0)
|
||||
{
|
||||
IPEndPoint point = new IPEndPoint(IPAddress.Any, discoverPort);
|
||||
var r = udpClient.Receive(ref point);
|
||||
var res = JsonUtility.FromJson<RequestJson>(utf8.GetString(r));
|
||||
|
||||
//無視デバイス名と一致しない場合だけ処理する
|
||||
if (res.deviceName != ignoreDeivceName) {
|
||||
responseIpAddress = point.Address.ToString();
|
||||
responsePort = point.Port;
|
||||
responseProtocolVersion = res.version;
|
||||
|
||||
responseDeviceName = res.deviceName;
|
||||
responseServicePort = res.servicePort;
|
||||
|
||||
foundDevices++;
|
||||
OnDeviceFound?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e40f235f907169c44a67a3dfb3516301
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,176 +0,0 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 gpsnmeajp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace EasyDeviceDiscoveryProtocolClient
|
||||
{
|
||||
public class Responder : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
public int discoverPort = 39500; //待受ポート
|
||||
|
||||
[Header("Properties")]
|
||||
public string deivceName = "mydevice_server"; //自分のデバイス名
|
||||
public int servicePort = 22222; //自分が使ってほしいと思っているポート
|
||||
public string ignoreDeivceName = ""; //無視するデバイス名
|
||||
public bool desktopMode = false; //デスクトップモード(false: 非アクティブ時にポートを閉じる, true: 閉じない)
|
||||
|
||||
[Header("Request Info(Read only)")]
|
||||
public string requestIpAddress = ""; //要求来たアドレス
|
||||
private int requestPort = 0; //要求来たポート
|
||||
public int requestProtocolVersion = 0; //要求のプロトコルバージョン
|
||||
|
||||
[Header("Request Data(Read only)")]
|
||||
public string requestDeviceName = ""; //要求に含まれるデバイス名
|
||||
public int requestServicePort = 0; //要求に含まれるポート
|
||||
|
||||
UdpClient udpClient;
|
||||
UTF8Encoding utf8 = new UTF8Encoding(false);
|
||||
|
||||
public Action OnRequested = () => { Debug.Log("[EDDP Responder]On Request"); };
|
||||
|
||||
//UDP通信の準備を行います
|
||||
void TryOpen()
|
||||
{
|
||||
//GameObjectが有効なときだけ開始する
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
if (udpClient == null)
|
||||
{
|
||||
udpClient = new UdpClient(discoverPort);
|
||||
udpClient.EnableBroadcast = true; //ブロードキャスト有効
|
||||
udpClient.MulticastLoopback = true; //ループバック許可
|
||||
Debug.Log("[EDDP Responder]UdpClient Open " + discoverPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//UDP通信の停止を行います。
|
||||
void Close()
|
||||
{
|
||||
if (udpClient != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
udpClient?.Close();
|
||||
Debug.Log("[EDDP Responder]UdpClient Closed");
|
||||
}
|
||||
finally
|
||||
{
|
||||
udpClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//GameObjectがEnableになったとき開く
|
||||
private void OnEnable()
|
||||
{
|
||||
TryOpen();
|
||||
}
|
||||
|
||||
//GameObjectがDisableになったとき閉じる
|
||||
private void OnDisable()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//GameObjectが破棄されるとき閉じる
|
||||
private void OnDestroy()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//アプリケーションが終了するとき閉じる
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//アプリケーションが中断・復帰したとき(モバイルでバックグラウンドになった・エディタで別のフォーカスを当てられたとき)
|
||||
private void OnApplicationPause(bool pause)
|
||||
{
|
||||
//モバイルデバイス向けなので、デスクトップモードでは行わない
|
||||
if(!desktopMode)
|
||||
{
|
||||
if (pause)
|
||||
{
|
||||
//アプリが閉じられたら止める
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
//アプリが開かれたので開く
|
||||
TryOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (udpClient != null)
|
||||
{
|
||||
while (udpClient.Available > 0)
|
||||
{
|
||||
//応答を受信
|
||||
IPEndPoint point = new IPEndPoint(IPAddress.Any, discoverPort); //待受ポート兼応答先(変化後)
|
||||
var r = udpClient.Receive(ref point);
|
||||
var req = JsonUtility.FromJson<RequestJson>(utf8.GetString(r));
|
||||
|
||||
//無視デバイス名と一致しない場合だけ処理する
|
||||
if(req.deviceName != ignoreDeivceName)
|
||||
{
|
||||
//要求内容を表示
|
||||
requestIpAddress = point.Address.ToString();
|
||||
requestPort = point.Port;
|
||||
requestProtocolVersion = req.version;
|
||||
|
||||
requestDeviceName = req.deviceName;
|
||||
requestServicePort = req.servicePort;
|
||||
|
||||
//応答を送信
|
||||
string data = JsonUtility.ToJson(new RequestJson
|
||||
{
|
||||
servicePort = servicePort,
|
||||
deviceName = deivceName,
|
||||
version = RequestJson.protocolVersion,
|
||||
});
|
||||
byte[] dat = utf8.GetBytes(data);
|
||||
udpClient.Send(dat, dat.Length, point);
|
||||
|
||||
//コールバック送付
|
||||
OnRequested?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 682dbd80eb655474e985b5c32a929d40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,272 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Yashinut.VRoid
|
||||
{
|
||||
/// <summary>
|
||||
/// TextureTypeを変換するときに使用する
|
||||
/// </summary>
|
||||
public static class ChangeTextureType
|
||||
{
|
||||
//DefaultからNormalMapへ変換する際に利用
|
||||
//数式が導き出せなかったので、0~255の範囲で対応する値を取得するDictionaryを定義
|
||||
public static readonly Dictionary<int, int> DefaultToNormalMap = new Dictionary<int, int>()
|
||||
{
|
||||
{0, 0},
|
||||
{1, 13},
|
||||
{2, 22},
|
||||
{3, 28},
|
||||
{4, 34},
|
||||
{5, 38},
|
||||
{6, 42},
|
||||
{7, 46},
|
||||
{8, 50},
|
||||
{9, 53},
|
||||
{10, 56},
|
||||
{11, 59},
|
||||
{12, 61},
|
||||
{13, 64},
|
||||
{14, 66},
|
||||
{15, 69},
|
||||
{16, 71},
|
||||
{17, 73},
|
||||
{18, 75},
|
||||
{19, 77},
|
||||
{20, 79},
|
||||
{21, 81},
|
||||
{22, 83},
|
||||
{23, 85},
|
||||
{24, 86},
|
||||
{25, 88},
|
||||
{26, 90},
|
||||
{27, 91},
|
||||
{28, 93},
|
||||
{29, 95},
|
||||
{30, 96},
|
||||
{31, 98},
|
||||
{32, 99},
|
||||
{33, 101},
|
||||
{34, 102},
|
||||
{35, 104},
|
||||
{36, 105},
|
||||
{37, 106},
|
||||
{38, 108},
|
||||
{39, 109},
|
||||
{40, 110},
|
||||
{41, 112},
|
||||
{42, 113},
|
||||
{43, 114},
|
||||
{44, 115},
|
||||
{45, 117},
|
||||
{46, 118},
|
||||
{47, 119},
|
||||
{48, 120},
|
||||
{49, 121},
|
||||
{50, 122},
|
||||
{51, 124},
|
||||
{52, 125},
|
||||
{53, 126},
|
||||
{54, 127},
|
||||
{55, 128},
|
||||
{56, 129},
|
||||
{57, 130},
|
||||
{58, 131},
|
||||
{59, 132},
|
||||
{60, 133},
|
||||
{61, 134},
|
||||
{62, 135},
|
||||
{63, 136},
|
||||
{64, 137},
|
||||
{65, 138},
|
||||
{66, 139},
|
||||
{67, 140},
|
||||
{68, 141},
|
||||
{69, 142},
|
||||
{70, 143},
|
||||
{71, 144},
|
||||
{72, 145},
|
||||
{73, 146},
|
||||
{74, 147},
|
||||
{75, 148},
|
||||
{76, 148},
|
||||
{77, 149},
|
||||
{78, 150},
|
||||
{79, 151},
|
||||
{80, 152},
|
||||
{81, 153},
|
||||
{82, 154},
|
||||
{83, 155},
|
||||
{84, 155},
|
||||
{85, 156},
|
||||
{86, 157},
|
||||
{87, 158},
|
||||
{88, 159},
|
||||
{89, 160},
|
||||
{90, 160},
|
||||
{91, 161},
|
||||
{92, 162},
|
||||
{93, 163},
|
||||
{94, 163},
|
||||
{95, 164},
|
||||
{96, 165},
|
||||
{97, 166},
|
||||
{98, 167},
|
||||
{99, 167},
|
||||
{100, 168},
|
||||
{101, 169},
|
||||
{102, 170},
|
||||
{103, 170},
|
||||
{104, 171},
|
||||
{105, 172},
|
||||
{106, 173},
|
||||
{107, 173},
|
||||
{108, 174},
|
||||
{109, 175},
|
||||
{110, 175},
|
||||
{111, 176},
|
||||
{112, 177},
|
||||
{113, 178},
|
||||
{114, 178},
|
||||
{115, 179},
|
||||
{116, 180},
|
||||
{117, 180},
|
||||
{118, 181},
|
||||
{119, 182},
|
||||
{120, 182},
|
||||
{121, 183},
|
||||
{122, 184},
|
||||
{123, 184},
|
||||
{124, 185},
|
||||
{125, 186},
|
||||
{126, 186},
|
||||
{127, 187},
|
||||
{128, 188},
|
||||
{129, 189},
|
||||
{130, 189},
|
||||
{131, 190},
|
||||
{132, 190},
|
||||
{133, 191},
|
||||
{134, 192},
|
||||
{135, 192},
|
||||
{136, 193},
|
||||
{137, 194},
|
||||
{138, 194},
|
||||
{139, 195},
|
||||
{140, 196},
|
||||
{141, 196},
|
||||
{142, 197},
|
||||
{143, 197},
|
||||
{144, 198},
|
||||
{145, 199},
|
||||
{146, 199},
|
||||
{147, 200},
|
||||
{148, 200},
|
||||
{149, 201},
|
||||
{150, 202},
|
||||
{151, 202},
|
||||
{152, 203},
|
||||
{153, 203},
|
||||
{154, 204},
|
||||
{155, 205},
|
||||
{156, 205},
|
||||
{157, 206},
|
||||
{158, 206},
|
||||
{159, 207},
|
||||
{160, 208},
|
||||
{161, 208},
|
||||
{162, 209},
|
||||
{163, 209},
|
||||
{164, 210},
|
||||
{165, 210},
|
||||
{166, 211},
|
||||
{167, 211},
|
||||
{168, 212},
|
||||
{169, 213},
|
||||
{170, 213},
|
||||
{171, 214},
|
||||
{172, 214},
|
||||
{173, 215},
|
||||
{174, 215},
|
||||
{175, 216},
|
||||
{176, 217},
|
||||
{177, 217},
|
||||
{178, 218},
|
||||
{179, 218},
|
||||
{180, 219},
|
||||
{181, 219},
|
||||
{182, 220},
|
||||
{183, 220},
|
||||
{184, 221},
|
||||
{185, 221},
|
||||
{186, 222},
|
||||
{187, 222},
|
||||
{188, 223},
|
||||
{189, 223},
|
||||
{190, 224},
|
||||
{191, 224},
|
||||
{192, 225},
|
||||
{193, 226},
|
||||
{194, 226},
|
||||
{195, 227},
|
||||
{196, 227},
|
||||
{197, 228},
|
||||
{198, 228},
|
||||
{199, 229},
|
||||
{200, 229},
|
||||
{201, 230},
|
||||
{202, 230},
|
||||
{203, 231},
|
||||
{204, 231},
|
||||
{205, 232},
|
||||
{206, 232},
|
||||
{207, 233},
|
||||
{208, 233},
|
||||
{209, 234},
|
||||
{210, 234},
|
||||
{211, 235},
|
||||
{212, 235},
|
||||
{213, 236},
|
||||
{214, 236},
|
||||
{215, 236},
|
||||
{216, 237},
|
||||
{217, 237},
|
||||
{218, 238},
|
||||
{219, 238},
|
||||
{220, 239},
|
||||
{221, 239},
|
||||
{222, 240},
|
||||
{223, 240},
|
||||
{224, 241},
|
||||
{225, 241},
|
||||
{226, 242},
|
||||
{227, 242},
|
||||
{228, 243},
|
||||
{229, 243},
|
||||
{230, 244},
|
||||
{231, 244},
|
||||
{232, 245},
|
||||
{233, 245},
|
||||
{234, 245},
|
||||
{235, 246},
|
||||
{236, 246},
|
||||
{237, 247},
|
||||
{238, 247},
|
||||
{239, 248},
|
||||
{240, 248},
|
||||
{241, 249},
|
||||
{242, 249},
|
||||
{243, 250},
|
||||
{244, 250},
|
||||
{245, 251},
|
||||
{246, 251},
|
||||
{247, 252},
|
||||
{248, 252},
|
||||
{249, 252},
|
||||
{250, 253},
|
||||
{251, 253},
|
||||
{252, 254},
|
||||
{253, 254},
|
||||
{254, 255},
|
||||
{255, 255},
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbece9a30cc87494ea1e8568e0f2ae6a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,148 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Yashinut.VRoid
|
||||
{
|
||||
/// <summary>
|
||||
/// VRoid出力のVRMをランタイムで読み込んだときに、NormalMapを修正するクラス
|
||||
/// </summary>
|
||||
public class CorrectNormalMapImport{
|
||||
/// <summary>
|
||||
/// VRoid用VRMのNormalMapを修正する
|
||||
/// </summary>
|
||||
/// <param name="vrmForVRoid"></param>
|
||||
/// <param name="deleteHairNormalMap"></param>
|
||||
public static void CorrectNormalMap(GameObject vrmForVRoid,bool deleteHairNormalMap = true)
|
||||
{
|
||||
var skinnedMeshRenderers = vrmForVRoid.GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
var materials = new List<Material>();
|
||||
|
||||
//vrmデータ内で使用されているマテリアルを全て取得する
|
||||
foreach (var skinnedMesh in skinnedMeshRenderers)
|
||||
{
|
||||
materials.AddRange(skinnedMesh.materials);
|
||||
}
|
||||
|
||||
var normalTextures = new List<Texture>();
|
||||
|
||||
//全てのマテリアルからNormalMapに設定されているTextureを取得する。
|
||||
foreach (var material in materials)
|
||||
{
|
||||
//髪の毛のノーマルマップが入るとちらつきの症状が見られるため、deleteHairNormalMapがtrueのときは、髪の毛のみノーマルマップを削除する。
|
||||
if (deleteHairNormalMap && material.name.Contains("Hair_00"))
|
||||
{
|
||||
material.SetTexture("_BumpMap",null);
|
||||
continue;
|
||||
}
|
||||
|
||||
// VRM/MToonシェーダーのNormalMapを取得。
|
||||
var tex = material.GetTexture("_BumpMap");
|
||||
if (tex == null) continue;
|
||||
|
||||
var defaultNormalMapTexture = ToTexture2D(tex);
|
||||
|
||||
Object.Destroy(tex);
|
||||
//修正したNormalMapを取得
|
||||
var correctedNormalMapTexture = CorrectNormalMap(defaultNormalMapTexture);
|
||||
Object.Destroy(defaultNormalMapTexture);
|
||||
// 修正したNormalMapを設定
|
||||
material.SetTexture("_BumpMap", correctedNormalMapTexture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TextureをTexture2Dへ変換
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
/// <returns></returns>
|
||||
private static Texture2D ToTexture2D(Texture texture)
|
||||
{
|
||||
var resultTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false);
|
||||
var currentRenderTexture = RenderTexture.active;
|
||||
var renderTexture = new RenderTexture(texture.width, texture.height, 32);
|
||||
Graphics.Blit(texture, renderTexture);
|
||||
RenderTexture.active = renderTexture;
|
||||
resultTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
|
||||
resultTexture.Apply();
|
||||
RenderTexture.active = currentRenderTexture;
|
||||
|
||||
return resultTexture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TextureTypeがNormalMapのときと同等になるように修正
|
||||
/// </summary>
|
||||
/// <param name="defaultNormalTexture"></param>
|
||||
/// <returns></returns>
|
||||
private static Texture2D CorrectNormalMap(Texture2D defaultNormalTexture)
|
||||
{
|
||||
var pixels = defaultNormalTexture.GetPixels();
|
||||
|
||||
for (var i = 0; i < pixels.Length; i++)
|
||||
{
|
||||
//各ピクセルごとにNormalMap用の修正を行う。
|
||||
pixels[i] = DefaultToNormalPixel(pixels[i]);
|
||||
}
|
||||
|
||||
var resultTexture = new Texture2D(defaultNormalTexture.width,defaultNormalTexture.height,TextureFormat.RGBA32,false);
|
||||
resultTexture.SetPixels(pixels);
|
||||
resultTexture.Apply();
|
||||
return resultTexture;
|
||||
}
|
||||
|
||||
private static Color DefaultToNormalPixel(Color defaultPixel)
|
||||
{
|
||||
float x = 0f;
|
||||
float y = 0f;
|
||||
float z = 0f;
|
||||
float w = 0f;
|
||||
|
||||
//プラットフォーム及びColorSpaceによって変換方法が変わる。
|
||||
#if UNITY_ANDROID
|
||||
|
||||
switch (QualitySettings.activeColorSpace)
|
||||
{
|
||||
case ColorSpace.Gamma:
|
||||
x = defaultPixel.r;
|
||||
y = defaultPixel.g;
|
||||
z = defaultPixel.b;
|
||||
w = defaultPixel.r;
|
||||
break;
|
||||
case ColorSpace.Linear:
|
||||
x = ChangeTextureType.DefaultToNormalMap[(int) (defaultPixel.r * 255f)] / 255f;
|
||||
y = ChangeTextureType.DefaultToNormalMap[(int) (defaultPixel.g * 255f)] / 255f;
|
||||
z = ChangeTextureType.DefaultToNormalMap[(int) (defaultPixel.b * 255f)] / 255f;
|
||||
w = defaultPixel.r;
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("ColorSpaceが不正です");
|
||||
break;
|
||||
}
|
||||
|
||||
#elif UNITY_STANDALONE_WIN
|
||||
|
||||
switch (QualitySettings.activeColorSpace)
|
||||
{
|
||||
case ColorSpace.Gamma:
|
||||
x = 1f;
|
||||
y = defaultPixel.g;
|
||||
z = defaultPixel.g;
|
||||
w = defaultPixel.r;
|
||||
break;
|
||||
case ColorSpace.Linear:
|
||||
x = 1f;
|
||||
y = ChangeTextureType.DefaultToNormalMap[(int) (defaultPixel.g * 255f)] / 255f;
|
||||
z = ChangeTextureType.DefaultToNormalMap[(int) (defaultPixel.g * 255f)] / 255f;
|
||||
w = defaultPixel.r;
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("ColorSpaceが不正です");
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return new Color(x,y,z,w);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ea80cc182740e7499236304d2b7181e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 yashinut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
BIN
Assets/External/ExternalPlugins/CorrectNormalMapImport/README.md
(Stored with Git LFS)
vendored
BIN
Assets/External/ExternalPlugins/CorrectNormalMapImport/README.md
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 394aa99c63ffcfe4c8a0264e9ed1fb74
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -13,7 +13,7 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public static class UrpGltfPbrMaterialImporter
|
||||
{
|
||||
public const string ShaderName = "Universal Render Pipeline/Lit";
|
||||
public const string ShaderName = "Universal Render Pipeline/NiloToon/NiloToon_Environment";
|
||||
|
||||
private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend");
|
||||
private static readonly int DstBlend = Shader.PropertyToID("_DstBlend");
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e40964934a24b4b41b081f8dca0e4f03
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,60 +0,0 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public class Outline : MonoBehaviour
|
||||
{
|
||||
private OutlineQuickVolume m_outlineVolume;
|
||||
private float m_defaultSize;
|
||||
private float m_targetSize;
|
||||
private float m_alpha = 0;
|
||||
public float fadeSpeed = 5;
|
||||
public float highlightSpeed = 10;
|
||||
public float maxSize = 4;
|
||||
private void Awake()
|
||||
{
|
||||
tag = "Untagged";
|
||||
m_outlineVolume = FindObjectOfType<OutlineQuickVolume>();
|
||||
m_defaultSize = m_outlineVolume.size;
|
||||
}
|
||||
|
||||
private void OnMouseEnter()
|
||||
{
|
||||
tag = "Outline";
|
||||
StartCoroutine(FadeInColor());
|
||||
}
|
||||
private void OnMouseDown()
|
||||
{
|
||||
StartCoroutine(OnClickHighlihgt());
|
||||
}
|
||||
|
||||
private void OnMouseExit()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
tag = "Untagged";
|
||||
m_outlineVolume.size = m_defaultSize;
|
||||
}
|
||||
|
||||
private IEnumerator FadeInColor()
|
||||
{
|
||||
m_alpha = 0;
|
||||
while (m_alpha < 1)
|
||||
{
|
||||
m_alpha = Mathf.MoveTowards(m_alpha, 1, fadeSpeed * Time.deltaTime);
|
||||
var c = m_outlineVolume.color;
|
||||
m_outlineVolume.color = new Color(c.r, c.g, c.b, m_alpha);
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator OnClickHighlihgt()
|
||||
{
|
||||
m_targetSize = maxSize;
|
||||
while (true)
|
||||
{
|
||||
m_outlineVolume.size = Mathf.MoveTowards(m_outlineVolume.size, m_targetSize, highlightSpeed * Time.deltaTime);
|
||||
if (m_outlineVolume.size >= maxSize) m_targetSize = m_defaultSize;
|
||||
if (m_outlineVolume.size == m_defaultSize) break;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed8a543f2c18ef74c9b210b11c831e98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,119 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
|
||||
[Serializable]
|
||||
[PostProcess(typeof(OutlineRenderer), PostProcessEvent.AfterStack, "Custom/Outline")]
|
||||
public sealed class OutlineEffect : PostProcessEffectSettings
|
||||
{
|
||||
public UnityEngine.Rendering.PostProcessing.ColorParameter color = new UnityEngine.Rendering.PostProcessing.ColorParameter { value = Color.red };
|
||||
[Range(0f, 5f), Tooltip("Outline size.")]
|
||||
public UnityEngine.Rendering.PostProcessing.FloatParameter size = new UnityEngine.Rendering.PostProcessing.FloatParameter { value = 2f };
|
||||
[Range(0f, 1f), Tooltip("Outline softness.")]
|
||||
public UnityEngine.Rendering.PostProcessing.FloatParameter softness = new UnityEngine.Rendering.PostProcessing.FloatParameter { value = 0.5f };
|
||||
public UnityEngine.Rendering.PostProcessing.BoolParameter downSample = new UnityEngine.Rendering.PostProcessing.BoolParameter { value = false };
|
||||
public UnityEngine.Rendering.PostProcessing.BoolParameter drawOnTop = new UnityEngine.Rendering.PostProcessing.BoolParameter { value = true };
|
||||
public ParameterOverride<string> Tag = new ParameterOverride<string> { value = "Outline" };
|
||||
|
||||
public override bool IsEnabledAndSupported(PostProcessRenderContext context)
|
||||
{
|
||||
bool objectsExist = false;
|
||||
try
|
||||
{
|
||||
objectsExist = GameObject.FindWithTag(Tag) != null;
|
||||
}
|
||||
catch (Exception) { }
|
||||
return enabled.value && objectsExist;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class OutlineRenderer : PostProcessEffectRenderer<OutlineEffect>
|
||||
{
|
||||
private Material m_mat;
|
||||
private Shader m_SeparableBlurShader;
|
||||
private Shader m_DilateShader;
|
||||
private Shader m_OutlineShader;
|
||||
private int m_objectsID;
|
||||
private int m_outlineColorID;
|
||||
private int m_ztestID;
|
||||
private int m_blurredID;
|
||||
private int m_tempID;
|
||||
private int m_offsetsID;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
m_mat = new Material(Shader.Find("Hidden/Outline/UnlitColor"));
|
||||
m_mat.hideFlags = HideFlags.HideAndDontSave;
|
||||
m_SeparableBlurShader = Shader.Find("Hidden/Outline/SeparableBlur");
|
||||
m_DilateShader = Shader.Find("Hidden/Outline/Dilate");
|
||||
m_OutlineShader = Shader.Find("Hidden/Outline");
|
||||
m_objectsID = Shader.PropertyToID("_ObjectsTex");
|
||||
m_outlineColorID = Shader.PropertyToID("_OutlineColor");
|
||||
m_ztestID = Shader.PropertyToID("_ZTest");
|
||||
m_blurredID = Shader.PropertyToID("_BlurredTex");
|
||||
m_tempID = Shader.PropertyToID("_Temp");
|
||||
m_offsetsID = Shader.PropertyToID("_Offsets");
|
||||
}
|
||||
|
||||
public override void Render(PostProcessRenderContext context)
|
||||
{
|
||||
// 지정된 태그를 가진 모든 게임 오브젝트를 찾고 MeshRenderer가 있는지 확인
|
||||
var renderers = GameObject.FindGameObjectsWithTag(settings.Tag)
|
||||
.Select((g) => g.GetComponent<MeshRenderer>())
|
||||
.Where(r => r != null); // MeshRenderer가 null이 아닌 경우만 선택
|
||||
|
||||
// 임시 렌더 텍스처 생성
|
||||
context.command.GetTemporaryRT(m_objectsID, -1, -1, 24, FilterMode.Bilinear);
|
||||
var depthId = context.camera.actualRenderingPath == RenderingPath.Forward
|
||||
? BuiltinRenderTextureType.Depth : BuiltinRenderTextureType.ResolvedDepth;
|
||||
context.command.SetRenderTarget(color: m_objectsID, depth: depthId);
|
||||
context.command.ClearRenderTarget(false, true, Color.clear);
|
||||
context.command.SetGlobalColor(m_outlineColorID, settings.color);
|
||||
|
||||
int ztest = settings.drawOnTop ? (int)CompareFunction.Always : (int)CompareFunction.LessEqual;
|
||||
m_mat.SetInt(m_ztestID, ztest);
|
||||
|
||||
// 객체를 그리기
|
||||
foreach (var r in renderers)
|
||||
{
|
||||
context.command.DrawRenderer(r, m_mat);
|
||||
}
|
||||
|
||||
int sample = settings.downSample.value ? 2 : 1;
|
||||
context.command.GetTemporaryRT(m_blurredID, -sample, -sample, 0, FilterMode.Bilinear);
|
||||
context.command.GetTemporaryRT(m_tempID, -sample, -sample, 0, FilterMode.Bilinear);
|
||||
context.command.Blit(m_objectsID, m_blurredID);
|
||||
|
||||
// 수평 확장
|
||||
float dilateSize = settings.size * (1 - settings.softness);
|
||||
var dilate = context.propertySheets.Get(m_DilateShader);
|
||||
dilate.properties.SetVector(m_offsetsID, new Vector4(dilateSize / context.width, 0, 0, 0));
|
||||
context.command.BlitFullscreenTriangle(m_blurredID, m_tempID, dilate, 0);
|
||||
|
||||
// 수직 확장
|
||||
dilate.properties.SetVector(m_offsetsID, new Vector4(0, dilateSize / context.height, 0, 0));
|
||||
context.command.BlitFullscreenTriangle(m_tempID, m_blurredID, dilate, 0);
|
||||
|
||||
// 수평 블러
|
||||
float blurSize = settings.size - dilateSize;
|
||||
var blur = context.propertySheets.Get(m_SeparableBlurShader);
|
||||
blur.properties.SetVector(m_offsetsID, new Vector4(blurSize / context.width, 0, 0, 0));
|
||||
context.command.BlitFullscreenTriangle(m_blurredID, m_tempID, blur, 0);
|
||||
|
||||
// 수직 블러
|
||||
blur.properties.SetVector(m_offsetsID, new Vector4(0, blurSize / context.height, 0, 0));
|
||||
context.command.BlitFullscreenTriangle(m_tempID, m_blurredID, blur, 0);
|
||||
|
||||
var outline = context.propertySheets.Get(m_OutlineShader);
|
||||
context.command.BlitFullscreenTriangle(context.source, context.destination, outline, 0);
|
||||
}
|
||||
|
||||
public override void Release()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_mat);
|
||||
base.Release();
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75c15ac21e33eac448bc5b3227e721ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,45 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class OutlineQuickVolume : MonoBehaviour
|
||||
{
|
||||
private PostProcessVolume m_Volume;
|
||||
private OutlineEffect m_OutlineEffect;
|
||||
public Color color = Color.white;
|
||||
[Range(0,5)]
|
||||
public float size = 3f;
|
||||
[Range(0,1)]
|
||||
public float softness = 0.4f;
|
||||
public bool drawOnTop = true;
|
||||
public bool downSample = false;
|
||||
public string Tag = "Outline";
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
m_OutlineEffect = ScriptableObject.CreateInstance<OutlineEffect>();
|
||||
m_OutlineEffect.enabled.Override(true);
|
||||
m_OutlineEffect.color.Override(color);
|
||||
m_OutlineEffect.size.Override(size);
|
||||
m_OutlineEffect.softness.Override(softness);
|
||||
m_OutlineEffect.drawOnTop.Override(drawOnTop);
|
||||
m_OutlineEffect.downSample.Override(downSample);
|
||||
m_OutlineEffect.Tag.Override(Tag);
|
||||
m_Volume = PostProcessManager.instance.QuickVolume(gameObject.layer, 100f, m_OutlineEffect);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
m_OutlineEffect.size.value = size;
|
||||
m_OutlineEffect.softness.value = softness;
|
||||
m_OutlineEffect.color.value = color;
|
||||
m_OutlineEffect.drawOnTop.value = drawOnTop;
|
||||
m_OutlineEffect.downSample.value = downSample;
|
||||
m_OutlineEffect.Tag.value = Tag;
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
RuntimeUtilities.DestroyVolume(m_Volume, true, true);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55e00f37d24ce30468f6628ef1a258c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 704740c612bc0b445baf2818c777680a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,51 +0,0 @@
|
||||
Shader "Hidden/Outline/Dilate" {
|
||||
HLSLINCLUDE
|
||||
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 uv01 : TEXCOORD1;
|
||||
float4 uv23 : TEXCOORD2;
|
||||
};
|
||||
|
||||
float4 _Offsets;
|
||||
v2f vert(AttributesDefault v) {
|
||||
v2f o;
|
||||
o.pos = float4(v.vertex.xy, 0.0, 1.0);
|
||||
o.uv = TransformTriangleVertexToUV(v.vertex.xy);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.uv = o.uv * float2(1.0, -1.0) + float2(0.0, 1.0);
|
||||
#endif
|
||||
o.uv01 = o.uv.xyxy + _Offsets.xyxy * float4(1, 1, -1, -1);
|
||||
o.uv23 = o.uv.xyxy.xyxy + _Offsets.xyxy * float4(1, 1, -1, -1) * 2.0;
|
||||
return o;
|
||||
}
|
||||
|
||||
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
|
||||
|
||||
half4 frag(v2f i) : COLOR{
|
||||
half4 c1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
|
||||
half4 c2 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.xy);
|
||||
half4 c3 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.zw);
|
||||
half4 c4 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.xy);
|
||||
half4 c5 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.zw);
|
||||
c1 = max(c1, c2);
|
||||
c3 = max(c3, c4);
|
||||
c5 = max(c1, c5);
|
||||
return max(c3, c5);
|
||||
}
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
Shader "Hidden/Outline"
|
||||
{
|
||||
HLSLINCLUDE
|
||||
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
|
||||
|
||||
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
|
||||
TEXTURE2D_SAMPLER2D(_BlurredTex, sampler_BlurredTex);
|
||||
TEXTURE2D_SAMPLER2D(_ObjectsTex, sampler_ObjectsTex);
|
||||
float4 _OutlineColor;
|
||||
float4 Frag(VaryingsDefault i) : SV_Target
|
||||
{
|
||||
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
|
||||
float4 objects = SAMPLE_TEXTURE2D(_ObjectsTex, sampler_ObjectsTex, i.texcoord);
|
||||
float4 blurred = SAMPLE_TEXTURE2D(_BlurredTex, sampler_BlurredTex, i.texcoord);
|
||||
float4 outline = saturate(blurred - objects);
|
||||
|
||||
outline = outline.rgbr;
|
||||
outline.rgb *= _OutlineColor.rgb;
|
||||
outline *= _OutlineColor.a;
|
||||
return color * (1 - outline.a) + outline;
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex VertDefault
|
||||
#pragma fragment Frag
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c140a43677333a441a684d1f4ee2fdd2
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,56 +0,0 @@
|
||||
Shader "Hidden/Outline/SeparableBlur" {
|
||||
HLSLINCLUDE
|
||||
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 uv01 : TEXCOORD1;
|
||||
float4 uv23 : TEXCOORD2;
|
||||
float4 uv45 : TEXCOORD3;
|
||||
};
|
||||
|
||||
float4 _Offsets;
|
||||
v2f vert(AttributesDefault v) {
|
||||
|
||||
v2f o;
|
||||
o.pos = float4(v.vertex.xy, 0.0, 1.0);
|
||||
o.uv = TransformTriangleVertexToUV(v.vertex.xy);
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.uv = o.uv * float2(1.0, -1.0) + float2(0.0, 1.0);
|
||||
#endif
|
||||
|
||||
o.uv01 = o.uv.xyxy + _Offsets.xyxy * float4(1, 1, -1, -1);
|
||||
o.uv23 = o.uv.xyxy.xyxy + _Offsets.xyxy * float4(1, 1, -1, -1) * 2.0;
|
||||
o.uv45 = o.uv.xyxy.xyxy + _Offsets.xyxy * float4(1, 1, -1, -1) * 3.0;
|
||||
return o;
|
||||
}
|
||||
|
||||
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
|
||||
|
||||
half4 frag(v2f i) : COLOR{
|
||||
half4 color = float4 (0,0,0,0);
|
||||
color += 0.40 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
|
||||
color += 0.15 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.xy);
|
||||
color += 0.15 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv01.zw);
|
||||
color += 0.10 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.xy);
|
||||
color += 0.10 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv23.zw);
|
||||
color += 0.05 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.xy);
|
||||
color += 0.05 * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv45.zw);
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de1b0dd2cdf4ebe4cabe117da73d4363
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,31 +0,0 @@
|
||||
Shader "Hidden/Outline/UnlitColor"
|
||||
{
|
||||
Properties{
|
||||
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("Z test", Int) = 8
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
ZTest [_ZTest]
|
||||
ZWrite Off
|
||||
Fog { Mode off }
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma fragmentoption ARB_precision_hint_fastest
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
float4 vert (float4 v : POSITION) : SV_Position
|
||||
{
|
||||
return UnityObjectToClipPos(v);
|
||||
}
|
||||
|
||||
fixed4 frag (float4 i:SV_Position) : SV_Target
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4af285f136432da4984535d6f8896f39
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/External/UnityMemoryMappedFile.meta
vendored
8
Assets/External/UnityMemoryMappedFile.meta
vendored
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f0fc8b4ae874c945a14e63ee89446d7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public sealed class AsyncLock
|
||||
{
|
||||
private readonly System.Threading.SemaphoreSlim m_semaphore
|
||||
= new System.Threading.SemaphoreSlim(1, 1);
|
||||
private readonly Task<IDisposable> m_releaser;
|
||||
|
||||
public AsyncLock()
|
||||
{
|
||||
m_releaser = Task.FromResult((IDisposable)new Releaser(this));
|
||||
}
|
||||
|
||||
public Task<IDisposable> LockAsync()
|
||||
{
|
||||
var wait = m_semaphore.WaitAsync();
|
||||
return wait.IsCompleted ?
|
||||
m_releaser :
|
||||
wait.ContinueWith(
|
||||
(_, state) => (IDisposable)state,
|
||||
m_releaser.Result,
|
||||
System.Threading.CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously,
|
||||
TaskScheduler.Default
|
||||
);
|
||||
}
|
||||
private sealed class Releaser : IDisposable
|
||||
{
|
||||
private readonly AsyncLock m_toRelease;
|
||||
internal Releaser(AsyncLock toRelease) { m_toRelease = toRelease; }
|
||||
public void Dispose() { m_toRelease.m_semaphore.Release(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b68e4b62bbcdd5145982130488d0fec1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,50 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public class BinarySerializer
|
||||
{
|
||||
private static Dictionary<Type, DataContractSerializer> serializerCache = new Dictionary<Type, DataContractSerializer>();
|
||||
|
||||
public static object Deserialize(byte[] data, Type type)
|
||||
{
|
||||
using (var ms = new MemoryStream(data))
|
||||
using (var reader = XmlDictionaryReader.CreateBinaryReader(ms, null, new XmlDictionaryReaderQuotas() { MaxArrayLength = int.MaxValue }))
|
||||
{
|
||||
DataContractSerializer serializer;
|
||||
if (serializerCache.TryGetValue(type, out serializer) == false)
|
||||
{
|
||||
serializer = new DataContractSerializer(type);
|
||||
serializerCache[type] = serializer;
|
||||
}
|
||||
return serializer.ReadObject(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] Serialize(object target)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(ms))
|
||||
{
|
||||
var type = target.GetType();
|
||||
DataContractSerializer serializer;
|
||||
if (serializerCache.TryGetValue(type, out serializer) == false)
|
||||
{
|
||||
serializer = new DataContractSerializer(type);
|
||||
serializerCache[type] = serializer;
|
||||
}
|
||||
serializer.WriteObject(writer, target);
|
||||
writer.Flush();
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a192d8b8ec6ba2049af21ca98d6ba507
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public class DataReceivedEventArgs : EventArgs
|
||||
{
|
||||
public Type CommandType;
|
||||
public string RequestId;
|
||||
public object Data;
|
||||
public DataReceivedEventArgs(Type commandType, string requestId, object data)
|
||||
{
|
||||
CommandType = commandType; RequestId = requestId; Data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 824c1807e05e41f4ba43bf3de37f1654
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,233 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public class MemoryMappedFileBase : IDisposable
|
||||
{
|
||||
private const long capacity = 104857600L;
|
||||
|
||||
private MemoryMappedFile receiver;
|
||||
private MemoryMappedViewAccessor receiverAccessor;
|
||||
|
||||
private MemoryMappedFile sender;
|
||||
private MemoryMappedViewAccessor senderAccessor;
|
||||
|
||||
private CancellationTokenSource readCts;
|
||||
|
||||
private string currentPipeName = null;
|
||||
|
||||
public EventHandler<DataReceivedEventArgs> ReceivedEvent;
|
||||
|
||||
public bool IsConnected = false;
|
||||
|
||||
protected async void StartInternal(string pipeName, bool isServer)
|
||||
{
|
||||
currentPipeName = pipeName;
|
||||
readCts = new CancellationTokenSource();
|
||||
if (isServer)
|
||||
{
|
||||
receiver = MemoryMappedFile.CreateOrOpen(pipeName + "_receiver", capacity);
|
||||
sender = MemoryMappedFile.CreateOrOpen(pipeName + "_sender", capacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
receiver = MemoryMappedFile.OpenExisting(pipeName + "_sender"); //サーバーと逆方向
|
||||
sender = MemoryMappedFile.OpenExisting(pipeName + "_receiver"); //サーバーと逆方向
|
||||
break;
|
||||
}
|
||||
catch (System.IO.FileNotFoundException) { }
|
||||
if (readCts.Token.IsCancellationRequested) return;
|
||||
await Task.Delay(100);
|
||||
}
|
||||
}
|
||||
receiverAccessor = receiver.CreateViewAccessor();
|
||||
senderAccessor = sender.CreateViewAccessor();
|
||||
var t = Task.Run(() => ReadThread());
|
||||
IsConnected = true;
|
||||
}
|
||||
|
||||
public void ReadThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
while (receiverAccessor != null && receiverAccessor?.ReadByte(0) != 1)
|
||||
{
|
||||
if (readCts.Token.IsCancellationRequested) return;
|
||||
Thread.Sleep(1);// await Task.Delay(1);
|
||||
}
|
||||
if (receiverAccessor == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread DataReceived");
|
||||
long position = 1;
|
||||
//CommandType
|
||||
var length = receiverAccessor.ReadInt32(position);
|
||||
position += sizeof(int);
|
||||
var typeNameArray = new byte[length];
|
||||
receiverAccessor.ReadArray(position, typeNameArray, 0, typeNameArray.Length);
|
||||
position += typeNameArray.Length;
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread GetCommandType");
|
||||
//RequestID
|
||||
length = receiverAccessor.ReadInt32(position);
|
||||
position += sizeof(int);
|
||||
var requestIdArray = new byte[length];
|
||||
receiverAccessor.ReadArray(position, requestIdArray, 0, requestIdArray.Length);
|
||||
position += requestIdArray.Length;
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread GetRequestID");
|
||||
//Data
|
||||
length = receiverAccessor.ReadInt32(position);
|
||||
position += sizeof(int);
|
||||
var dataArray = new byte[length];
|
||||
receiverAccessor.ReadArray(position, dataArray, 0, dataArray.Length);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread GetData");
|
||||
//Write finish flag
|
||||
receiverAccessor.Write(0, (byte)0);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread Write finish flag");
|
||||
|
||||
var commandType = PipeCommands.GetCommandType(Encoding.UTF8.GetString(typeNameArray));
|
||||
var requestId = Encoding.UTF8.GetString(requestIdArray);
|
||||
var data = BinarySerializer.Deserialize(dataArray, commandType);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread Parsed Type:{commandType.Name} requestId = {requestId}");
|
||||
if (WaitReceivedDictionary.ContainsKey(requestId))
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread ContainsKey");
|
||||
WaitReceivedDictionary[requestId] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase ReadThread Raise Event");
|
||||
ReceivedEvent?.Invoke(this, new DataReceivedEventArgs(commandType, requestId, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException) { }
|
||||
}
|
||||
|
||||
protected ConcurrentDictionary<string, object> WaitReceivedDictionary = new ConcurrentDictionary<string, object>();
|
||||
|
||||
private AsyncLock SendLock = new AsyncLock();
|
||||
|
||||
public async Task<string> SendCommandAsync(object command, string requestId = null, bool needWait = false)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommandAsync WaitLock [{command.GetType().Name}]");
|
||||
return await Task.Run(async () =>
|
||||
{
|
||||
using (await SendLock.LockAsync())
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommandAsync EnterLock [{command.GetType().Name}]");
|
||||
return SendCommand(command, requestId, needWait);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public string SendCommand(object command, string requestId = null, bool needWait = false)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand Enter [{command.GetType().Name}]");
|
||||
if (IsConnected == false) return null;
|
||||
if (string.IsNullOrEmpty(requestId)) requestId = Guid.NewGuid().ToString();
|
||||
var typeNameArray = Encoding.UTF8.GetBytes(command.GetType().Name);
|
||||
var requestIdArray = Encoding.UTF8.GetBytes(requestId);
|
||||
var dataArray = BinarySerializer.Serialize(command);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand StartWait [{command.GetType().Name}]");
|
||||
while (senderAccessor.ReadByte(0) == 1) // Wait finish flag
|
||||
{
|
||||
if (readCts.Token.IsCancellationRequested) return null;
|
||||
Thread.Sleep(1);// await Task.Delay(1);
|
||||
}
|
||||
//Need to wait requestID before send (because sometime return data very fast)
|
||||
if (needWait) WaitReceivedDictionary.TryAdd(requestId, null);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand EndWait [{command.GetType().Name}]");
|
||||
long position = 1;
|
||||
//CommandType
|
||||
senderAccessor.Write(position, typeNameArray.Length);
|
||||
position += sizeof(int);
|
||||
senderAccessor.WriteArray(position, typeNameArray, 0, typeNameArray.Length);
|
||||
position += typeNameArray.Length;
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand WriteCommandType [{command.GetType().Name}]");
|
||||
//RequestID
|
||||
senderAccessor.Write(position, requestIdArray.Length);
|
||||
position += sizeof(int);
|
||||
senderAccessor.WriteArray(position, requestIdArray, 0, requestIdArray.Length);
|
||||
position += requestIdArray.Length;
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand WriteRequestID [{command.GetType().Name}]");
|
||||
//Data
|
||||
senderAccessor.Write(position, dataArray.Length);
|
||||
position += sizeof(int);
|
||||
senderAccessor.WriteArray(position, dataArray, 0, dataArray.Length);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand WriteData [{command.GetType().Name}]");
|
||||
//Write finish flag
|
||||
senderAccessor.Write(0, (byte)1);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommand Write finish flag [{command.GetType().Name}]");
|
||||
|
||||
return requestId;
|
||||
}
|
||||
|
||||
public async Task SendCommandWaitAsync(object command, Action<object> returnAction)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommandWaitAsync Enter [{command.GetType().Name}]");
|
||||
var requestId = await SendCommandAsync(command, null, true);
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommandWaitAsync Return SendCommandAsync [{command.GetType().Name}] id:{requestId}");
|
||||
if (requestId == null) return;
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommandWaitAsync StartWait [{command.GetType().Name}]");
|
||||
while (WaitReceivedDictionary[requestId] == null)
|
||||
{
|
||||
await Task.Delay(10);
|
||||
}
|
||||
System.Diagnostics.Debug.WriteLine($"MemoryMappedFileBase SendCommandWaitAsync WaitEnd [{command.GetType().Name}]");
|
||||
object value; //・・・・
|
||||
WaitReceivedDictionary.TryRemove(requestId, out value);
|
||||
returnAction(value);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
IsConnected = false;
|
||||
readCts?.Cancel();
|
||||
receiverAccessor?.Dispose();
|
||||
senderAccessor?.Dispose();
|
||||
receiver?.Dispose();
|
||||
sender?.Dispose();
|
||||
receiverAccessor = null;
|
||||
senderAccessor = null;
|
||||
receiver = null;
|
||||
sender = null;
|
||||
}
|
||||
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false; // 重複する呼び出しを検出するには
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 889195bf3a8feb54d901a242daddd474
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public class MemoryMappedFileClient : MemoryMappedFileBase
|
||||
{
|
||||
public void Start(string pipeName)
|
||||
{
|
||||
StartInternal(pipeName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5309b09f4dfbca14498bcfadbb2510cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public class MemoryMappedFileServer : MemoryMappedFileBase
|
||||
{
|
||||
public void Start(string pipeName)
|
||||
{
|
||||
StartInternal(pipeName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dabbef80550c42419454b5c7baf3794
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1506
Assets/External/UnityMemoryMappedFile/PipeCommands.cs
vendored
1506
Assets/External/UnityMemoryMappedFile/PipeCommands.cs
vendored
File diff suppressed because it is too large
Load Diff
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 114b33c9658d29441b2eefcc9c83224c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UnityMemoryMappedFile
|
||||
{
|
||||
public partial class PipeCommands
|
||||
{
|
||||
public class mocopi_GetSetting { }
|
||||
public class mocopi_SetSetting
|
||||
{
|
||||
public bool enable { get; set; }
|
||||
public int port { get; set; }
|
||||
|
||||
public bool ApplyRootPosition { get; set; }
|
||||
public bool ApplyRootRotation { get; set; }
|
||||
public bool ApplyChest { get; set; }
|
||||
public bool ApplySpine { get; set; }
|
||||
public bool ApplyHead { get; set; }
|
||||
public bool ApplyLeftArm { get; set; }
|
||||
public bool ApplyRightArm { get; set; }
|
||||
public bool ApplyLeftHand { get; set; }
|
||||
public bool ApplyRightHand { get; set; }
|
||||
public bool ApplyLeftLeg { get; set; }
|
||||
public bool ApplyRightLeg { get; set; }
|
||||
public bool ApplyLeftFoot { get; set; }
|
||||
public bool ApplyRightFoot { get; set; }
|
||||
public bool CorrectHipBone { get; set; }
|
||||
}
|
||||
public class mocopi_Recenter { }
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 115e66c92d7dc0e40aa2a3787d6eee05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7138c377056d61418632ce80ae673c0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
|
||||
// アセンブリに関連付けられている情報を変更するには、
|
||||
// これらの属性値を変更してください。
|
||||
[assembly: AssemblyTitle("UnityMemoryMappedFile")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("sh_akira")]
|
||||
[assembly: AssemblyProduct("UnityMemoryMappedFile")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019 sh_akira.")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから
|
||||
// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、
|
||||
// その型の ComVisible 属性を true に設定してください。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります
|
||||
[assembly: Guid("045efc7f-9cf6-4dce-83e1-3cac35d83383")]
|
||||
|
||||
// アセンブリのバージョン情報は次の 4 つの値で構成されています:
|
||||
//
|
||||
// メジャー バージョン
|
||||
// マイナー バージョン
|
||||
// ビルド番号
|
||||
// Revision
|
||||
//
|
||||
// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます
|
||||
// 以下のように '*' を使用します:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a069ad9038c7c24b8b703f1dcab32bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0ddbd505f5f46444b98a9285b7cdb8a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a01cd8c315597a4183f6a9b3753d53d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88951bc2f4dfe6a4d99f1251090de224
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04674152f9528c64a8870d39b7acc0ed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f4c64ba340e88a4e9c3ae77536daad5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
|
||||
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf7f059672b0ba6409045de917a8f716
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26ac5dd6d6900994c86edf143c96f4be
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b77b1bd7e32d6744299f768fd9fb6f01
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/External/VMCMOD.meta
vendored
8
Assets/External/VMCMOD.meta
vendored
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82798b971415f0040b45f80785d99179
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/External/VMCMOD/Attributes.meta
vendored
8
Assets/External/VMCMOD/Attributes.meta
vendored
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d7e84d9597393d4984a709a5e843717
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,11 +0,0 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace VMCMod
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class OnSettingAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cf08d66f6d1cb043b0ab26e6cd3aa0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,31 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace VMCMod
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class VMCPluginAttribute : Attribute
|
||||
{
|
||||
public VMCPluginAttribute(string Name, string Version, string Author, string Description = null, string AuthorURL = null, string PluginURL = null)
|
||||
{
|
||||
this.Name = Name;
|
||||
this.Version = Version;
|
||||
this.Author = Author;
|
||||
this.Description = Description;
|
||||
this.AuthorURL = AuthorURL;
|
||||
this.PluginURL = PluginURL;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string Version { get; }
|
||||
public string Author { get; }
|
||||
public string AuthorURL { get; }
|
||||
public string Description { get; }
|
||||
public string PluginURL { get; }
|
||||
|
||||
public string InstanceId { get; set; }
|
||||
public string AssemblyPath { get; set; }
|
||||
internal List<Action> OnSetting { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 358cf90c249a2974a97c280ee65a5d28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62
Assets/External/VMCMOD/ExampleMod.cs
vendored
62
Assets/External/VMCMOD/ExampleMod.cs
vendored
@ -1,62 +0,0 @@
|
||||
using UnityEngine;
|
||||
using VMC;
|
||||
using VMCMod;
|
||||
|
||||
[VMCPlugin(
|
||||
Name: "ExampleMod",
|
||||
Version: "1.0.0",
|
||||
Author: "sh_akira",
|
||||
Description: "サンプルModです。右手に球体を取り付けます。Settingボタンで色をランダムに変更します。",
|
||||
AuthorURL: "https://twitter.com/sh_akira",
|
||||
PluginURL: "http://mod.vmc.info/")]
|
||||
public class ExampleMod : MonoBehaviour
|
||||
{
|
||||
private Transform rightHandTransform;
|
||||
private GameObject sphere;
|
||||
private Material sphereMaterial;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
VMCEvents.OnModelLoaded += OnModelLoaded;
|
||||
VMCEvents.OnCameraChanged += OnCameraChanged;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
Debug.Log("Example Mod started.");
|
||||
|
||||
sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
sphere.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
|
||||
sphereMaterial = sphere.GetComponent<Renderer>().material;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (rightHandTransform != null)
|
||||
{
|
||||
sphere.transform.position = rightHandTransform.position;
|
||||
}
|
||||
}
|
||||
|
||||
[OnSetting]
|
||||
public void OnSetting()
|
||||
{
|
||||
if (sphereMaterial != null)
|
||||
{
|
||||
sphereMaterial.color = new Color(Random.value, Random.value, Random.value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnModelLoaded(GameObject currentModel)
|
||||
{
|
||||
if (currentModel == null) return;
|
||||
|
||||
var animator = currentModel.GetComponent<Animator>();
|
||||
rightHandTransform = animator.GetBoneTransform(HumanBodyBones.RightMiddleProximal); //右手中指のボーン
|
||||
}
|
||||
|
||||
private void OnCameraChanged(Camera currentCamera)
|
||||
{
|
||||
//カメラ切り替え時に現在のカメラを取得できます
|
||||
}
|
||||
}
|
||||
11
Assets/External/VMCMOD/ExampleMod.cs.meta
vendored
11
Assets/External/VMCMOD/ExampleMod.cs.meta
vendored
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb3e754e025c3684f911087d6e2f44b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
98
Assets/External/VMCMOD/ModManager.cs
vendored
98
Assets/External/VMCMOD/ModManager.cs
vendored
@ -1,98 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VMCMod
|
||||
{
|
||||
public class ModManager : MonoBehaviour
|
||||
{
|
||||
private string ModsPath;
|
||||
|
||||
private Dictionary<VMCPluginAttribute, Component> LoadedMods = new Dictionary<VMCPluginAttribute, Component>();
|
||||
|
||||
public Action OnBeforeModLoad;
|
||||
|
||||
public bool IsModLoaded => LoadedMods.Any();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
ModsPath = Application.dataPath + "/../Mods/";
|
||||
}
|
||||
|
||||
public void ImportMods()
|
||||
{
|
||||
if (Directory.Exists(ModsPath) == false)
|
||||
{
|
||||
Directory.CreateDirectory(ModsPath);
|
||||
}
|
||||
|
||||
Debug.Log("Start Loading Mods");
|
||||
var attributeTypesList = new Dictionary<List<Type>, string>();
|
||||
foreach (var dllFile in Directory.GetFiles(ModsPath, "*.dll", SearchOption.AllDirectories))
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly assembly = Assembly.LoadFrom(dllFile);
|
||||
var attributeTypes = assembly.GetTypes().Where(x => x.IsPublic && x.IsDefined(typeof(VMCPluginAttribute)));
|
||||
if (attributeTypes.Any())
|
||||
{
|
||||
attributeTypesList.Add(attributeTypes.ToList(), dllFile);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (attributeTypesList.Any())
|
||||
{
|
||||
OnBeforeModLoad?.Invoke();
|
||||
}
|
||||
|
||||
foreach (var attributeTypes in attributeTypesList)
|
||||
{
|
||||
foreach (Type t in attributeTypes.Key)
|
||||
{
|
||||
try
|
||||
{
|
||||
var attribute = (VMCPluginAttribute)Attribute.GetCustomAttribute(t, typeof(VMCPluginAttribute));
|
||||
attribute.InstanceId = Guid.NewGuid().ToString();
|
||||
attribute.AssemblyPath = attributeTypes.Value;
|
||||
var component = gameObject.AddComponent(t);
|
||||
attribute.OnSetting = new List<Action>();
|
||||
foreach (MethodInfo method in t.GetMethods().Where(x => x.IsDefined(typeof(OnSettingAttribute))))
|
||||
{
|
||||
attribute.OnSetting.Add(() => method.Invoke(component, null));
|
||||
}
|
||||
LoadedMods[attribute] = component;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<VMCPluginAttribute> GetModsList()
|
||||
{
|
||||
return LoadedMods.Keys.ToList();
|
||||
}
|
||||
|
||||
public void InvokeSetting(string instanceId)
|
||||
{
|
||||
var attribute = LoadedMods.Keys.FirstOrDefault(x => x.InstanceId == instanceId);
|
||||
if (attribute != null)
|
||||
{
|
||||
foreach (var settingAction in attribute.OnSetting)
|
||||
{
|
||||
settingAction?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/External/VMCMOD/ModManager.cs.meta
vendored
11
Assets/External/VMCMOD/ModManager.cs.meta
vendored
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dcc60cfbf22eb4408f2038656c46c10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/External/VMCMOD/VMCEvents.cs
vendored
17
Assets/External/VMCMOD/VMCEvents.cs
vendored
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VMC
|
||||
{
|
||||
public class VMCEvents
|
||||
{
|
||||
public static Action<GameObject> OnCurrentModelChanged = null;
|
||||
public static Action<GameObject> OnModelLoaded = null;
|
||||
public static Action<GameObject> OnModelUnloading = null;
|
||||
public static Action<Camera> OnCameraChanged = null;
|
||||
public static Action OnLightChanged = null;
|
||||
public static Action<string> OnLoadedConfigPathChanged = null;
|
||||
public static Action<GameObject> BeforeApplyMotion = null;
|
||||
public static Action<GameObject> AfterApplyMotion = null;
|
||||
}
|
||||
}
|
||||
11
Assets/External/VMCMOD/VMCEvents.cs.meta
vendored
11
Assets/External/VMCMOD/VMCEvents.cs.meta
vendored
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aef082aa1fee2ef4aab28e61ce0187a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/External/VMCMOD/VMCMod.asmdef
vendored
3
Assets/External/VMCMOD/VMCMod.asmdef
vendored
@ -1,3 +0,0 @@
|
||||
{
|
||||
"name": "VMCMod"
|
||||
}
|
||||
7
Assets/External/VMCMOD/VMCMod.asmdef.meta
vendored
7
Assets/External/VMCMOD/VMCMod.asmdef.meta
vendored
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a3e8c74b825bc4478e3752b559cc5c7
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/External/VRCDeveloperTool.meta
vendored
8
Assets/External/VRCDeveloperTool.meta
vendored
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f909532172455174fafe43aa05d8cae0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/External/VRCDeveloperTool/Editor.meta
vendored
9
Assets/External/VRCDeveloperTool/Editor.meta
vendored
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0567de9323ae234dbc4465a542d0be3
|
||||
folderAsset: yes
|
||||
timeCreated: 1536028717
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9adcb8c102e5f7948b0f7e44f6c4bf0e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,361 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
// ver 1.0
|
||||
// © 2019 gatosyocora
|
||||
|
||||
namespace VRCDeveloperTool
|
||||
{
|
||||
|
||||
public class AnimationPropertyConverter : EditorWindow
|
||||
{
|
||||
|
||||
private SkinnedMeshRenderer avatarMesh;
|
||||
|
||||
private List<AnimationClip> preAnimationClips;
|
||||
private List<AnimationProperty> animPropertyList;
|
||||
private string[] blendShapeNameList;
|
||||
|
||||
private string saveFolder = "Assets/";
|
||||
|
||||
private bool convertBlendShapeName = false;
|
||||
private bool isOpeningPreAnimationClips = true;
|
||||
private bool isOpeningAnimationPropertyList = true;
|
||||
private Vector2 propertyScrollPos = Vector2.zero;
|
||||
private bool isConvertAll = false;
|
||||
|
||||
public class AnimationProperty
|
||||
{
|
||||
public string propertyType;
|
||||
public string preName;
|
||||
public string posName;
|
||||
public bool isConvert;
|
||||
public int selectedBlendShapeIndex;
|
||||
public List<int> animIndexHavingThisProperty;
|
||||
|
||||
public AnimationProperty(string type, string name, int animIndex)
|
||||
{
|
||||
propertyType = type;
|
||||
preName = name;
|
||||
posName = preName;
|
||||
isConvert = false;
|
||||
selectedBlendShapeIndex = 0;
|
||||
|
||||
animIndexHavingThisProperty = new List<int>() { animIndex };
|
||||
}
|
||||
|
||||
public void AddAnimIndexHavingThisProperty(int animIndex)
|
||||
{
|
||||
animIndexHavingThisProperty.Add(animIndex);
|
||||
}
|
||||
|
||||
public bool RemoveAnimIndexHavingThisProperty(int animIndex)
|
||||
{
|
||||
return animIndexHavingThisProperty.Remove(animIndex);
|
||||
}
|
||||
|
||||
public bool existAnimHavingThisProperty()
|
||||
{
|
||||
return animIndexHavingThisProperty.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("VRCDeveloperTool/AnimationPropertyConverter")]
|
||||
private static void Create()
|
||||
{
|
||||
GetWindow<AnimationPropertyConverter>("AnimationProperty Converter");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
avatarMesh = null;
|
||||
|
||||
preAnimationClips = new List<AnimationClip>();
|
||||
preAnimationClips.Add(null);
|
||||
|
||||
animPropertyList = new List<AnimationProperty>();
|
||||
|
||||
blendShapeNameList = null;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
convertBlendShapeName = EditorGUILayout.ToggleLeft("Convert BlendShapeName", convertBlendShapeName);
|
||||
|
||||
if (convertBlendShapeName)
|
||||
{
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
avatarMesh = EditorGUILayout.ObjectField(
|
||||
"Avatar's SkinnedMeshRenderer",
|
||||
avatarMesh,
|
||||
typeof(SkinnedMeshRenderer),
|
||||
true
|
||||
) as SkinnedMeshRenderer;
|
||||
|
||||
if (check.changed && avatarMesh != null)
|
||||
blendShapeNameList = GetBlendShapeNameList(avatarMesh);
|
||||
}
|
||||
}
|
||||
|
||||
isOpeningPreAnimationClips = EditorGUILayout.Foldout(isOpeningPreAnimationClips, "Pre AnimationClips");
|
||||
if (isOpeningPreAnimationClips)
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("+"))
|
||||
{
|
||||
preAnimationClips.Add(null);
|
||||
}
|
||||
if (GUILayout.Button("-") && preAnimationClips.Count > 1)
|
||||
{
|
||||
var animIndex = preAnimationClips.Count - 1;
|
||||
|
||||
CheckAndRemoveAnimProperties(ref animPropertyList, animIndex);
|
||||
|
||||
preAnimationClips.RemoveAt(animIndex);
|
||||
}
|
||||
}
|
||||
using (new EditorGUI.IndentLevelScope())
|
||||
{
|
||||
for (int animIndex = 0; animIndex < preAnimationClips.Count; animIndex++)
|
||||
{
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
preAnimationClips[animIndex] = EditorGUILayout.ObjectField(
|
||||
"AnimationClip " + (animIndex + 1),
|
||||
preAnimationClips[animIndex],
|
||||
typeof(AnimationClip),
|
||||
true
|
||||
) as AnimationClip;
|
||||
|
||||
if (check.changed)
|
||||
{
|
||||
CheckAndRemoveAnimProperties(ref animPropertyList, animIndex);
|
||||
|
||||
if (preAnimationClips[animIndex] != null)
|
||||
UpdateAnimationPropertyNameList(preAnimationClips[animIndex], ref animPropertyList, animIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
|
||||
isOpeningAnimationPropertyList = EditorGUILayout.Foldout(isOpeningAnimationPropertyList, "AnimationPropertyList");
|
||||
if (isOpeningAnimationPropertyList)
|
||||
{
|
||||
using (new EditorGUI.IndentLevelScope())
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
isConvertAll = EditorGUILayout.Toggle(isConvertAll, GUILayout.Width(30f));
|
||||
|
||||
if (check.changed)
|
||||
ChangeAllIsConvertParams(isConvertAll, ref animPropertyList);
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("prePropertyName", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("posPropertyName", EditorStyles.boldLabel);
|
||||
}
|
||||
|
||||
using (var scrollPos = new GUILayout.ScrollViewScope(propertyScrollPos))
|
||||
{
|
||||
propertyScrollPos = scrollPos.scrollPosition;
|
||||
foreach (var animProperty in animPropertyList)
|
||||
{
|
||||
if (!convertBlendShapeName || animProperty.propertyType == "blendShape")
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
animProperty.isConvert = EditorGUILayout.Toggle(animProperty.isConvert, GUILayout.Width(30f));
|
||||
|
||||
if (convertBlendShapeName && avatarMesh != null)
|
||||
{
|
||||
EditorGUILayout.LabelField(animProperty.preName);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField(animProperty.propertyType + "." + animProperty.preName);
|
||||
}
|
||||
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
|
||||
if (convertBlendShapeName && avatarMesh != null)
|
||||
{
|
||||
animProperty.selectedBlendShapeIndex = EditorGUILayout.Popup(animProperty.selectedBlendShapeIndex, blendShapeNameList);
|
||||
}
|
||||
else
|
||||
{
|
||||
animProperty.posName = EditorGUILayout.TextField(animProperty.posName);
|
||||
}
|
||||
|
||||
if (check.changed)
|
||||
{
|
||||
if (convertBlendShapeName && avatarMesh != null)
|
||||
animProperty.posName = blendShapeNameList[animProperty.selectedBlendShapeIndex];
|
||||
|
||||
animProperty.isConvert = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.LabelField("AnimClipSaveFolder", saveFolder);
|
||||
|
||||
if (GUILayout.Button("Select Folder", GUILayout.Width(100)))
|
||||
{
|
||||
saveFolder = EditorUtility.OpenFolderPanel("Select saved folder", saveFolder, "");
|
||||
var match = Regex.Match(saveFolder, @"Assets/.*");
|
||||
saveFolder = match.Value + "/";
|
||||
if (saveFolder == "/") saveFolder = "Assets/";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Convert Property & Save as New File"))
|
||||
{
|
||||
ConvertAndCreateAnimationClips(preAnimationClips, animPropertyList, saveFolder, convertBlendShapeName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// アニメーションファイルのプロパティの名前を変更して新しいファイルとして書き出す
|
||||
/// </summary>
|
||||
/// <param name="baseAnimClips"></param>
|
||||
/// <param name="animPropertyList"></param>
|
||||
/// <param name="saveFolder"></param>
|
||||
/// <param name="convertBlendShapeName"></param>
|
||||
private void ConvertAndCreateAnimationClips(List<AnimationClip> baseAnimClips, List<AnimationProperty> animPropertyList, string saveFolder, bool convertBlendShapeName)
|
||||
{
|
||||
// 変換するプロパティ(isConvert == true)のものだけのリストをつくる
|
||||
var shoundConvertedPropertyList = animPropertyList.Where(x => x.isConvert).ToList<AnimationProperty>();
|
||||
|
||||
foreach (var baseAnimClip in baseAnimClips)
|
||||
{
|
||||
if (baseAnimClip == null) continue;
|
||||
|
||||
var convertedAnimClip = Object.Instantiate<AnimationClip>(baseAnimClip);
|
||||
|
||||
var bindings = AnimationUtility.GetCurveBindings(convertedAnimClip);
|
||||
|
||||
for (int i = 0; i < bindings.Length; i++)
|
||||
{
|
||||
// binding.propertyName == blendShape.vrc.v_silみたいになっている
|
||||
var propertyType = bindings[i].propertyName.Split('.')[0];
|
||||
var blendShapeName = bindings[i].propertyName.Replace(propertyType + ".", "");
|
||||
|
||||
// blendShapeだけ変更するモードだったらそれ以外の場合は処理しない
|
||||
if (convertBlendShapeName && propertyType != "blendShape") continue;
|
||||
|
||||
// 変換するプロパティのリストに含まれるプロパティだけ変換する
|
||||
var targetAnimProperty = shoundConvertedPropertyList.Find(x => x.propertyType == propertyType && x.preName == blendShapeName);
|
||||
if (targetAnimProperty != null)
|
||||
{
|
||||
var curve = AnimationUtility.GetEditorCurve(convertedAnimClip, bindings[i]);
|
||||
AnimationUtility.SetEditorCurve(convertedAnimClip, bindings[i], null);
|
||||
|
||||
bindings[i].propertyName = targetAnimProperty.propertyType + "." + targetAnimProperty.posName;
|
||||
|
||||
AnimationUtility.SetEditorCurve(convertedAnimClip, bindings[i], curve);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(convertedAnimClip, AssetDatabase.GenerateUniqueAssetPath(saveFolder + baseAnimClip.name + ".anim"));
|
||||
|
||||
}
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// アニメーションプロパティリストを更新する
|
||||
/// </summary>
|
||||
/// <param name="animClips"></param>
|
||||
/// <param name="animPropertyList"></param>
|
||||
private void UpdateAnimationPropertyNameList(AnimationClip animClips, ref List<AnimationProperty> animPropertyList, int animIndex)
|
||||
{
|
||||
var bindings = AnimationUtility.GetCurveBindings(animClips);
|
||||
|
||||
foreach (var binding in bindings)
|
||||
{
|
||||
// binding.propertyName == blendShape.vrc.v_silみたいになっている
|
||||
var propertyType = binding.propertyName.Split('.')[0];
|
||||
var blendShapeName = binding.propertyName.Replace(propertyType + ".", "");
|
||||
|
||||
// animPropertyListに含まれていないプロパティだけ追加する
|
||||
// すでに含まれている場合AnimIndexHavingThisPropertyに追加する
|
||||
var animProperty = animPropertyList.Find(x => x.propertyType == propertyType && x.preName == blendShapeName);
|
||||
if (animProperty == null)
|
||||
animPropertyList.Add(new AnimationProperty(propertyType, blendShapeName, animIndex));
|
||||
else
|
||||
animProperty.AddAnimIndexHavingThisProperty(animIndex);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ブレンドシェイプの名前一覧を取得する
|
||||
/// </summary>
|
||||
/// <param name="meshRenderer"></param>
|
||||
/// <returns></returns>
|
||||
private string[] GetBlendShapeNameList(SkinnedMeshRenderer meshRenderer)
|
||||
{
|
||||
var mesh = meshRenderer.sharedMesh;
|
||||
if (mesh == null) return null;
|
||||
|
||||
var blendShapeNameList = new string[mesh.blendShapeCount];
|
||||
|
||||
for (int i = 0; i < mesh.blendShapeCount; i++)
|
||||
blendShapeNameList[i] = mesh.GetBlendShapeName(i);
|
||||
|
||||
return blendShapeNameList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// すべてのプロパティリストのisConvertを変更する
|
||||
/// </summary>
|
||||
/// <param name="isConvertAll"></param>
|
||||
/// <param name="animPropertyList"></param>
|
||||
private void ChangeAllIsConvertParams(bool isConvertAll, ref List<AnimationProperty> animPropertyList)
|
||||
{
|
||||
foreach (var animProperty in animPropertyList)
|
||||
{
|
||||
animProperty.isConvert = isConvertAll;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// プロパティリストに含まれるすべてのプロパティのAnimIndexHavingThisPropertyからanimIndexを削除して
|
||||
/// リストに不要なプロパティか調べ、削除する
|
||||
/// </summary>
|
||||
/// <param name="animPropertyList"></param>
|
||||
/// <param name="animIndex"></param>
|
||||
private void CheckAndRemoveAnimProperties(ref List<AnimationProperty> animPropertyList, int animIndex)
|
||||
{
|
||||
foreach (var animProperty in animPropertyList.ToArray())
|
||||
{
|
||||
animProperty.RemoveAnimIndexHavingThisProperty(animIndex);
|
||||
if (!animProperty.existAnimHavingThisProperty())
|
||||
animPropertyList.Remove(animProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9826d703d0a307c478e8e2a69f9ec980
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b7d1dbc790667b4d96b794d9102bb06
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,262 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using VRCDeveloperTool;
|
||||
|
||||
// ver 1.0.1
|
||||
// Copyright (c) 2020 gatosyocora
|
||||
|
||||
namespace VRCDeveloperTool
|
||||
{
|
||||
public class AnimatorControllerDuplicator : EditorWindow
|
||||
{
|
||||
private RuntimeAnimatorController runtimeAnimatorController;
|
||||
private static RuntimeAnimatorController tempController;
|
||||
private List<ControllerAnimationClip> animationClips;
|
||||
|
||||
private string saveFolder;
|
||||
private string endKeyword;
|
||||
|
||||
private bool isOverrideController = true;
|
||||
|
||||
private Vector2 scrollPos = Vector2.zero;
|
||||
|
||||
public class ControllerAnimationClip
|
||||
{
|
||||
public AnimationClip clip;
|
||||
public List<int> controllerIndices;
|
||||
public bool isDuplicate;
|
||||
|
||||
public ControllerAnimationClip(AnimationClip clip, int index, bool isDuplicate = true)
|
||||
{
|
||||
this.clip = clip;
|
||||
controllerIndices = new List<int>();
|
||||
AddIndex(index);
|
||||
this.isDuplicate = isDuplicate;
|
||||
}
|
||||
|
||||
public void AddIndex(int index)
|
||||
{
|
||||
controllerIndices.Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/RuntimeAnimatorController/Duplicate Controller And Clips")]
|
||||
private static void GetSelectController(MenuCommand menuCommand)
|
||||
{
|
||||
tempController = menuCommand.context as RuntimeAnimatorController;
|
||||
Open();
|
||||
}
|
||||
|
||||
[MenuItem("VRCDeveloperTool/AnimatorControllerDuplicator")]
|
||||
public static void Open()
|
||||
{
|
||||
GetWindow<AnimatorControllerDuplicator>("AnimatorControllerDuplicator");
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (tempController != null)
|
||||
{
|
||||
runtimeAnimatorController = tempController;
|
||||
tempController = null;
|
||||
LoadRuntimeControllerInfo(runtimeAnimatorController);
|
||||
}
|
||||
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
runtimeAnimatorController = EditorGUILayout.ObjectField(
|
||||
"AnimatorController",
|
||||
runtimeAnimatorController,
|
||||
typeof(RuntimeAnimatorController),
|
||||
true) as RuntimeAnimatorController;
|
||||
|
||||
EditorGUILayout.HelpBox("複製したいAnimatorOverrideControllerを設定してください", MessageType.Info);
|
||||
|
||||
if (!isOverrideController)
|
||||
EditorGUILayout.HelpBox("まだAnimatorControllerは未対応です", MessageType.Error);
|
||||
|
||||
if (check.changed && runtimeAnimatorController != null)
|
||||
{
|
||||
LoadRuntimeControllerInfo(runtimeAnimatorController);
|
||||
}
|
||||
}
|
||||
|
||||
if (animationClips != null)
|
||||
{
|
||||
EditorGUILayout.LabelField("AnimaionClips", EditorStyles.boldLabel);
|
||||
|
||||
using (new EditorGUI.IndentLevelScope())
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.LabelField("複製", EditorStyles.boldLabel, GUILayout.Width(50f));
|
||||
EditorGUILayout.LabelField("AnimationClipの名前", EditorStyles.boldLabel);
|
||||
}
|
||||
|
||||
using (var scroll = new EditorGUILayout.ScrollViewScope(scrollPos))
|
||||
{
|
||||
scrollPos = scroll.scrollPosition;
|
||||
|
||||
foreach (var animationClip in animationClips)
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
animationClip.isDuplicate = EditorGUILayout.ToggleLeft(string.Empty, animationClip.isDuplicate, GUILayout.Width(50f));
|
||||
EditorGUILayout.LabelField(animationClip.clip.name);
|
||||
if (GUILayout.Button("Select"))
|
||||
{
|
||||
Selection.activeObject = animationClip.clip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveFolder = EditorGUILayout.TextField("保存先フォルダ", saveFolder);
|
||||
|
||||
endKeyword = EditorGUILayout.TextField("複製後Assetのキーワード", endKeyword);
|
||||
|
||||
EditorGUILayout.HelpBox("AnimatorControllerおよび選択したAnimationClipを複製します\n複製されると複製後のものがそれぞれ設定されます\n複製後Assetのキーワードに設定した文字がそれぞれの名前の末尾につきます", MessageType.Info);
|
||||
|
||||
using (new EditorGUI.DisabledGroupScope(runtimeAnimatorController == null || !isOverrideController))
|
||||
{
|
||||
if (GUILayout.Button("Duplicate AnimatorController & AnimationClips"))
|
||||
{
|
||||
DuplicateAnimatorControllerAndAnimationClips();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DuplicateAnimatorControllerAndAnimationClips()
|
||||
{
|
||||
var controllerPath = AssetDatabase.GetAssetPath(runtimeAnimatorController);
|
||||
var newControllerPath = AssetDatabase.GenerateUniqueAssetPath(
|
||||
saveFolder + "\\"
|
||||
+ GatoEditorUtility.AddKeywordToEnd(Path.GetFileNameWithoutExtension(controllerPath), endKeyword)
|
||||
+ Path.GetExtension(controllerPath));
|
||||
|
||||
var success = AssetDatabase.CopyAsset(controllerPath, newControllerPath);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Debug.LogError("AnimatorControllerの複製に失敗しました");
|
||||
return;
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
runtimeAnimatorController = AssetDatabase.LoadAssetAtPath(newControllerPath, typeof(RuntimeAnimatorController)) as RuntimeAnimatorController;
|
||||
|
||||
foreach (var animationClip in animationClips)
|
||||
{
|
||||
if (!animationClip.isDuplicate) continue;
|
||||
|
||||
var animClipPath = AssetDatabase.GetAssetPath(animationClip.clip);
|
||||
var newAnimClipPath = AssetDatabase.GenerateUniqueAssetPath(
|
||||
saveFolder + "\\"
|
||||
+ GatoEditorUtility.AddKeywordToEnd(Path.GetFileNameWithoutExtension(animClipPath), endKeyword)
|
||||
+ Path.GetExtension(animClipPath));
|
||||
|
||||
var successAnimClip = AssetDatabase.CopyAsset(animClipPath, newAnimClipPath);
|
||||
|
||||
if (!successAnimClip)
|
||||
{
|
||||
Debug.LogErrorFormat("AnimationClip:{0}の複製に失敗しました", animationClip.clip.name);
|
||||
return;
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
animationClip.clip = AssetDatabase.LoadAssetAtPath(newAnimClipPath, typeof(AnimationClip)) as AnimationClip;
|
||||
|
||||
foreach (var index in animationClip.controllerIndices)
|
||||
{
|
||||
runtimeAnimatorController.animationClips[index] = animationClip.clip;
|
||||
}
|
||||
}
|
||||
|
||||
if (isOverrideController)
|
||||
{
|
||||
var overrideController = runtimeAnimatorController as AnimatorOverrideController;
|
||||
var baseAnimClips = overrideController.runtimeAnimatorController.animationClips;
|
||||
|
||||
foreach (var animationClip in animationClips)
|
||||
{
|
||||
foreach (var index in animationClip.controllerIndices)
|
||||
{
|
||||
var baseAnimClipName = baseAnimClips[index].name;
|
||||
overrideController[baseAnimClipName] = animationClip.clip;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private List<ControllerAnimationClip> DistinctControllerAnimationClips(List<ControllerAnimationClip> animClips)
|
||||
{
|
||||
var distinctedAnimClips = new List<ControllerAnimationClip>();
|
||||
var animClipDictionary = new Dictionary<string, ControllerAnimationClip>();
|
||||
|
||||
for (int i = 0; i < animClips.Count; i++)
|
||||
{
|
||||
var animName = animClips[i].clip.name;
|
||||
if (!animClipDictionary.ContainsKey(animName))
|
||||
{
|
||||
animClipDictionary.Add(animName, animClips[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var animClipData = animClipDictionary[animName];
|
||||
animClipData.AddIndex(animClips[i].controllerIndices.First());
|
||||
}
|
||||
}
|
||||
|
||||
distinctedAnimClips = animClipDictionary.Select(x => x.Value).ToList();
|
||||
return distinctedAnimClips;
|
||||
}
|
||||
|
||||
private void LoadRuntimeControllerInfo(RuntimeAnimatorController runtimeAnimatorController)
|
||||
{
|
||||
AnimatorController controller = runtimeAnimatorController as AnimatorController;
|
||||
AnimatorOverrideController overrideController = runtimeAnimatorController as AnimatorOverrideController;
|
||||
|
||||
if (controller != null)
|
||||
{
|
||||
isOverrideController = false;
|
||||
// AnimatorControllerからAnimationClipの取得
|
||||
}
|
||||
else if (overrideController != null)
|
||||
{
|
||||
isOverrideController = true;
|
||||
// AnimatorOverrideControllerからAnimationClipの取得
|
||||
// OverrideされたAnimationClipのみ取得
|
||||
var baseAnimationController = overrideController.runtimeAnimatorController as AnimatorController;
|
||||
animationClips = overrideController.animationClips
|
||||
.Select((x, index) => new { Value = x, Index = index })
|
||||
.Where(x => baseAnimationController.animationClips[x.Index].name != x.Value.name)
|
||||
.Select(x => new ControllerAnimationClip(x.Value, x.Index))
|
||||
.ToList();
|
||||
|
||||
animationClips = DistinctControllerAnimationClips(animationClips);
|
||||
|
||||
}
|
||||
|
||||
saveFolder = Path.GetDirectoryName(AssetDatabase.GetAssetPath(runtimeAnimatorController));
|
||||
endKeyword = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b31bd1421b78b1e46b35ab56873af04e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ecf1e763fda23f48a947d07940662a5
|
||||
folderAsset: yes
|
||||
timeCreated: 1537791342
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,268 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using VRCSDK2;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
|
||||
// ver 1.2.2
|
||||
// © 2018 gatosyocora
|
||||
|
||||
namespace VRCDeveloperTool
|
||||
{
|
||||
public class ComponentAdder : EditorWindow
|
||||
{
|
||||
|
||||
GameObject targetObject = null;
|
||||
|
||||
private enum AddType
|
||||
{
|
||||
Current_Children_Only,
|
||||
All_Childrens,
|
||||
};
|
||||
|
||||
AddType addType;
|
||||
|
||||
private bool isRigidbody = false;
|
||||
private bool useGravityFlag = true;
|
||||
private bool isKinematicFlag = false;
|
||||
private bool freezePosFlag = false;
|
||||
private bool freezeRotFlag = false;
|
||||
|
||||
private bool isObjectSync = false;
|
||||
|
||||
private bool isPickup = false;
|
||||
|
||||
private bool isBoxCollider = false;
|
||||
private bool isTriggerFlag = false;
|
||||
|
||||
[MenuItem("VRCDeveloperTool/Component Adder")]
|
||||
private static void Create()
|
||||
{
|
||||
GetWindow<ComponentAdder>("Component Adder");
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
targetObject = EditorGUILayout.ObjectField(
|
||||
"ParentObject",
|
||||
targetObject,
|
||||
typeof(GameObject),
|
||||
true
|
||||
) as GameObject;
|
||||
|
||||
addType = (AddType)EditorGUILayout.EnumPopup("Add Type", addType);
|
||||
|
||||
guiRigidbody();
|
||||
|
||||
guiObjectSync();
|
||||
|
||||
guiPickup();
|
||||
|
||||
guiBoxCollider();
|
||||
|
||||
guiAction();
|
||||
|
||||
}
|
||||
|
||||
// 指定オブジェクトの直接的な子オブジェクトをすべて取得する
|
||||
private List<GameObject> getCurrentChildrens(GameObject parentObj)
|
||||
{
|
||||
List<GameObject> objs = new List<GameObject>(parentObj.transform.childCount);
|
||||
|
||||
foreach (Transform child in parentObj.transform)
|
||||
{
|
||||
objs.Add(child.gameObject);
|
||||
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
// 指定オブジェクトの子オブジェクト以降をすべて取得する
|
||||
private List<GameObject> getAllChildrens(GameObject parentObj)
|
||||
{
|
||||
List<GameObject> objs = new List<GameObject>();
|
||||
|
||||
var childTransform = parentObj.GetComponentsInChildren<Transform>();
|
||||
|
||||
foreach (Transform child in childTransform)
|
||||
{
|
||||
objs.Add(child.gameObject);
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
// 特定のオブジェクトにコンポーネントを追加する
|
||||
private void AddComponentObject(GameObject obj)
|
||||
{
|
||||
if (isRigidbody)
|
||||
{
|
||||
var rigid = obj.GetComponent<Rigidbody>();
|
||||
if (rigid == null)
|
||||
rigid = obj.AddComponent<Rigidbody>();
|
||||
rigid.isKinematic = isKinematicFlag;
|
||||
rigid.useGravity = useGravityFlag;
|
||||
rigid.constraints = 0;
|
||||
if (freezePosFlag) rigid.constraints |= RigidbodyConstraints.FreezePosition;
|
||||
if (freezeRotFlag) rigid.constraints |= RigidbodyConstraints.FreezeRotation;
|
||||
}
|
||||
if (isObjectSync)
|
||||
{
|
||||
#if VRC_SDK_VRCSDK2
|
||||
if (obj.GetComponent<VRC_ObjectSync>() == null)
|
||||
{
|
||||
var com = obj.AddComponent<VRC_ObjectSync>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (isPickup)
|
||||
{
|
||||
#if VRC_SDK_VRCSDK2
|
||||
if (obj.GetComponent<VRC_Pickup>() == null)
|
||||
{
|
||||
var com = obj.AddComponent<VRC_Pickup>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (isBoxCollider)
|
||||
{
|
||||
if (obj.GetComponent<Collider>() == null || obj.GetComponent<BoxCollider>() != null)
|
||||
{
|
||||
var com = obj.GetComponent<BoxCollider>();
|
||||
if (com == null)
|
||||
com = obj.AddComponent<BoxCollider>();
|
||||
com.isTrigger = isTriggerFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 特定のオブジェクトのコンポーネントを削除する
|
||||
private void DeleteComponentObject(GameObject obj)
|
||||
{
|
||||
if (isPickup)
|
||||
{
|
||||
#if VRC_SDK_VRCSDK2
|
||||
var com = obj.GetComponent<VRC_Pickup>();
|
||||
if (com != null) DestroyImmediate(com);
|
||||
#endif
|
||||
}
|
||||
if (isRigidbody)
|
||||
{
|
||||
var com = obj.GetComponent<Rigidbody>();
|
||||
if (com != null) DestroyImmediate(com);
|
||||
}
|
||||
if (isObjectSync)
|
||||
{
|
||||
#if VRC_SDK_VRCSDK2
|
||||
var com = obj.GetComponent<VRC_ObjectSync>();
|
||||
if (com != null) DestroyImmediate(com);
|
||||
#endif
|
||||
}
|
||||
if (isBoxCollider)
|
||||
{
|
||||
var com = obj.GetComponent<BoxCollider>();
|
||||
if (com != null) DestroyImmediate(com);
|
||||
}
|
||||
}
|
||||
|
||||
private void guiRigidbody()
|
||||
{
|
||||
isRigidbody = EditorGUILayout.BeginToggleGroup("Rigidbody", isRigidbody);
|
||||
if (isRigidbody)
|
||||
{
|
||||
useGravityFlag = EditorGUILayout.Toggle("useGravity", useGravityFlag);
|
||||
isKinematicFlag = EditorGUILayout.Toggle("isKinematic", isKinematicFlag);
|
||||
freezePosFlag = EditorGUILayout.Toggle("Freeze Positions", freezePosFlag);
|
||||
freezeRotFlag = EditorGUILayout.Toggle("Freeze Rotations", freezeRotFlag);
|
||||
}
|
||||
EditorGUILayout.EndToggleGroup();
|
||||
}
|
||||
|
||||
private void guiObjectSync()
|
||||
{
|
||||
isObjectSync = EditorGUILayout.BeginToggleGroup("VRC_ObjectSync", isObjectSync);
|
||||
//syncPhysicsFlag = EditorGUILayout.Toggle("Synchronize Physics", syncPhysicsFlag);
|
||||
//collisionTransferFlag = EditorGUILayout.Toggle("Collision Transfer", collisionTransferFlag);
|
||||
#if VRC_SDK_VRCSDK2
|
||||
#else
|
||||
if (isObjectSync)
|
||||
{
|
||||
EditorGUILayout.HelpBox("VRCSDK2をインポートしてください", MessageType.Error);
|
||||
}
|
||||
#endif
|
||||
EditorGUILayout.EndToggleGroup();
|
||||
}
|
||||
|
||||
private void guiPickup()
|
||||
{
|
||||
isPickup = EditorGUILayout.BeginToggleGroup("VRC_Pickup", isPickup);
|
||||
#if VRC_SDK_VRCSDK2
|
||||
#else
|
||||
if (isPickup)
|
||||
{
|
||||
EditorGUILayout.HelpBox("VRCSDK2をインポートしてください", MessageType.Error);
|
||||
}
|
||||
#endif
|
||||
EditorGUILayout.EndToggleGroup();
|
||||
}
|
||||
|
||||
private void guiBoxCollider()
|
||||
{
|
||||
isBoxCollider = EditorGUILayout.BeginToggleGroup("BoxCollider", isBoxCollider);
|
||||
if (isBoxCollider)
|
||||
{
|
||||
isTriggerFlag = EditorGUILayout.Toggle("isTrigger", isTriggerFlag);
|
||||
}
|
||||
EditorGUILayout.EndToggleGroup();
|
||||
}
|
||||
|
||||
private void guiAction()
|
||||
{
|
||||
|
||||
EditorGUI.BeginDisabledGroup(targetObject == null);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Add/Change Components"))
|
||||
{
|
||||
List<GameObject> objs;
|
||||
|
||||
if (addType == AddType.Current_Children_Only)
|
||||
{
|
||||
objs = getCurrentChildrens(targetObject);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
objs = getAllChildrens(targetObject);
|
||||
}
|
||||
|
||||
foreach (GameObject obj in objs)
|
||||
{
|
||||
AddComponentObject(obj);
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Delete Components"))
|
||||
{
|
||||
List<GameObject> objs;
|
||||
|
||||
if (addType == AddType.Current_Children_Only)
|
||||
{
|
||||
objs = getCurrentChildrens(targetObject);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
objs = getAllChildrens(targetObject);
|
||||
}
|
||||
|
||||
foreach (GameObject obj in objs)
|
||||
{
|
||||
DeleteComponentObject(obj);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5f0ce7345f2dcb4b9c8d9a0f1a9de10
|
||||
timeCreated: 1537079080
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38b7d06e6faf6454ba07c362e80890d1
|
||||
folderAsset: yes
|
||||
timeCreated: 1537791366
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4451bc762558274ea722d45840a70a0
|
||||
folderAsset: yes
|
||||
timeCreated: 1537791379
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d6aa19a0d34987449b69a30397c0171
|
||||
timeCreated: 1537791431
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf1036ae4731baf41b35d98e03686f41
|
||||
timeCreated: 1537791411
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea99b4a464dafa541b7d326a128bb5af
|
||||
timeCreated: 1537791431
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 188c432963af8ea4fab44ea681a8df5d
|
||||
timeCreated: 1537791431
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d13ab5ba79c432547ab955ad1343f36d
|
||||
timeCreated: 1537791431
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc63fb35bd0032944a05af79bb27fa14
|
||||
timeCreated: 1537791431
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user