forked from sin365/AxibugEmuOnline
Compare commits
12 Commits
629cd16016
...
1a526b10f6
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a526b10f6 | |||
| a7807194ed | |||
| cd4163d9fe | |||
| c36adccbde | |||
| e1d7ef2d13 | |||
| 0f27fa328c | |||
| 33283a9a34 | |||
| 0a45c4fbbd | |||
| a1db47ab4b | |||
| ebb4cb401c | |||
| 57c4947623 | |||
| 8afcbce6b1 |
@ -0,0 +1,42 @@
|
|||||||
|
#if UNITY_EDITOR
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class AxiProjectTools_AssetsAutoSetting : EditorWindow
|
||||||
|
{
|
||||||
|
[MenuItem("Axibug移植工具/AssetsAutoSetting/自动设置TextureMaxSize为图片大小1倍")]
|
||||||
|
public static void AutoSettTextureSize_1x() { SetTextureSite(1f); }
|
||||||
|
|
||||||
|
[MenuItem("Axibug移植工具/AssetsAutoSetting/自动设置TextureMaxSize为图片大小2分之1倍")]
|
||||||
|
public static void AutoSettTextureSize_1_2x() { SetTextureSite(1f / 2f); }
|
||||||
|
[MenuItem("Axibug移植工具/AssetsAutoSetting/自动设置TextureMaxSize为图片大小4分之1倍")]
|
||||||
|
public static void AutoSettTextureSize_1_4x() { SetTextureSite(1f / 4f); }
|
||||||
|
|
||||||
|
public static void SetTextureSite(float Scale)
|
||||||
|
{
|
||||||
|
Texture2D[] textures = Selection.GetFiltered<Texture2D>(SelectionMode.DeepAssets);
|
||||||
|
if (textures.Length == 0)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("请先选择目录,或者Texture资源");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetDatabase.StartAssetEditing(); // 开启批量编辑模式
|
||||||
|
foreach (var texture in textures)
|
||||||
|
{
|
||||||
|
string path = AssetDatabase.GetAssetPath(texture);
|
||||||
|
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
|
||||||
|
if (importer != null)
|
||||||
|
{
|
||||||
|
int size = Mathf.Max(texture.width, texture.height);
|
||||||
|
int maxsize = Mathf.ClosestPowerOfTwo((int)(size * Scale)); // Unity内置方法适配2的幂次方
|
||||||
|
importer.maxTextureSize = maxsize;
|
||||||
|
importer.SaveAndReimport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssetDatabase.StopAssetEditing(); // 结束批量编辑
|
||||||
|
Debug.Log($"Updated {textures.Length} textures.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dc0741a79e74f96449a260406f239066
|
||||||
@ -0,0 +1,840 @@
|
|||||||
|
#if UNITY_EDITOR && UNITY_2020_1_OR_NEWER
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class AxiProjectToolsStatistics : EditorWindow
|
||||||
|
{
|
||||||
|
static string cachecfgPath = "Assets/AxiStatisticsDatas.asset";
|
||||||
|
static Dictionary<string, AxiStatisticsDatas> dictTempData = new Dictionary<string, AxiStatisticsDatas>();
|
||||||
|
|
||||||
|
static void ClearTempData()
|
||||||
|
{
|
||||||
|
dictTempData.Clear();
|
||||||
|
}
|
||||||
|
static string GetRootTempKey(int type, string rootName)
|
||||||
|
{
|
||||||
|
return type + "_" + rootName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 添加Hierarchy右键菜单项
|
||||||
|
[MenuItem("GameObject/AxiStatistics/GetAxiNodeHash", false, 10)]
|
||||||
|
public static void GetAxiNodeHash()
|
||||||
|
{
|
||||||
|
// 获取当前右键选中的Transform
|
||||||
|
Transform selectedTransform = Selection.activeTransform;
|
||||||
|
if (selectedTransform != null)
|
||||||
|
{
|
||||||
|
Debug.Log("选中的对象"+selectedTransform.name+",Hash=>"+ GetNodeDataHash(selectedTransform,true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetNodeDataHash(Transform trans,bool bLog = false)
|
||||||
|
{
|
||||||
|
long hashplus = 0;
|
||||||
|
hashplus += trans.position.GetHashCode();
|
||||||
|
hashplus += trans.localPosition.GetHashCode();
|
||||||
|
|
||||||
|
|
||||||
|
#if UNITY_2017_1_OR_NEWER
|
||||||
|
int count = trans.childCount;
|
||||||
|
#else
|
||||||
|
int count = trans.GetChildCount();
|
||||||
|
#endif
|
||||||
|
hashplus += count;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
hashplus += trans.GetChild(i).name.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (bLog)
|
||||||
|
{
|
||||||
|
//Debug.Log("trans.position.GetHashCode()=>" + trans.position.GetHashCode());
|
||||||
|
//Debug.Log("trans.localPosition.GetHashCode()=>" + trans.localPosition.GetHashCode());
|
||||||
|
//Debug.Log("childCount =>" + count);
|
||||||
|
//Debug.Log("hashplus =>" + hashplus);
|
||||||
|
//Debug.Log("hashplus.GetHashCode() =>" + hashplus.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashplus.GetHashCode();
|
||||||
|
}
|
||||||
|
static int GetNodeLinkListHash(List<AxiStatistics_Node_Link> nodes)
|
||||||
|
{
|
||||||
|
string hashplus = string.Empty;
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
hashplus += node.Name;
|
||||||
|
hashplus += node.Idx.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashplus.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetNodeLinkListStr(List<AxiStatistics_Node_Link> nodes)
|
||||||
|
{
|
||||||
|
string linkstr = string.Empty;
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
linkstr += "/";
|
||||||
|
linkstr += node.Name;
|
||||||
|
linkstr += "[" + node.Idx + "]";
|
||||||
|
}
|
||||||
|
return linkstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddComponentData(int _type, string _rootPath, AxiStatistics_Node_Component _comdata, string _nodepath, Component lastcom)
|
||||||
|
{
|
||||||
|
string rootKey = GetRootTempKey(_type, _rootPath);
|
||||||
|
|
||||||
|
if (!dictTempData.ContainsKey(rootKey))
|
||||||
|
{
|
||||||
|
dictTempData[rootKey] = new AxiStatisticsDatas() { type = _type, FullPath = _rootPath, nodes = new List<AxiStatistics_Node>() };
|
||||||
|
}
|
||||||
|
AxiStatisticsDatas rootData = dictTempData[rootKey];
|
||||||
|
|
||||||
|
List<AxiStatistics_Node_Link> link = new List<AxiStatistics_Node_Link>();
|
||||||
|
if (lastcom.transform.parent != null)
|
||||||
|
{
|
||||||
|
Transform currNode = lastcom.transform;
|
||||||
|
while (currNode != null)
|
||||||
|
{
|
||||||
|
//最顶层了
|
||||||
|
if (currNode.parent == null)
|
||||||
|
{
|
||||||
|
link.Insert(0, new AxiStatistics_Node_Link()
|
||||||
|
{
|
||||||
|
NodeHash = GetNodeDataHash(currNode),
|
||||||
|
Idx = 0,
|
||||||
|
OnlyOne = true,
|
||||||
|
Name = currNode.gameObject.name
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thisNameAllCount = 0;
|
||||||
|
int thisNodeIdx = -1;
|
||||||
|
#if UNITY_2017_1_OR_NEWER
|
||||||
|
int count = currNode.parent.childCount;
|
||||||
|
#else
|
||||||
|
int count = currNode.parent.GetChildCount();
|
||||||
|
#endif
|
||||||
|
bool bFind = false;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
GameObject checkGobj = currNode.parent.GetChild(i).gameObject;
|
||||||
|
if (checkGobj.name == currNode.name)
|
||||||
|
{
|
||||||
|
thisNameAllCount++;
|
||||||
|
if (checkGobj == currNode.gameObject)
|
||||||
|
{
|
||||||
|
thisNodeIdx = thisNameAllCount - 1;
|
||||||
|
bFind = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bFind)
|
||||||
|
{
|
||||||
|
link.Insert(0, new AxiStatistics_Node_Link()
|
||||||
|
{
|
||||||
|
NodeHash = GetNodeDataHash(currNode),
|
||||||
|
Idx = thisNodeIdx,
|
||||||
|
OnlyOne = thisNameAllCount == 1,
|
||||||
|
Name = currNode.gameObject.name
|
||||||
|
});
|
||||||
|
currNode = currNode.parent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
link.Insert(0, new AxiStatistics_Node_Link()
|
||||||
|
{
|
||||||
|
NodeHash = GetNodeDataHash(lastcom.transform),
|
||||||
|
Idx = 0,
|
||||||
|
OnlyOne = true,
|
||||||
|
Name = lastcom.gameObject.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int linkhash = GetNodeLinkListHash(link);
|
||||||
|
AxiStatistics_Node nodeData = rootData.nodes.Where(w => w.LinkHash == linkhash).FirstOrDefault();
|
||||||
|
if (nodeData == null)
|
||||||
|
{
|
||||||
|
nodeData = new AxiStatistics_Node();
|
||||||
|
nodeData.Name = Path.GetFileName(_nodepath);
|
||||||
|
//nodeData.NodeFullPath = _nodepath;
|
||||||
|
nodeData.components = new List<AxiStatistics_Node_Component>();
|
||||||
|
//nodeData.NodeIdx = thisNodeIdx;
|
||||||
|
//nodeData.NodeIdxOnlyOne = bNodeIdxOnlyOne;
|
||||||
|
|
||||||
|
nodeData.link = link;
|
||||||
|
nodeData.LinkHash = linkhash;
|
||||||
|
nodeData.LinkFullStr = GetNodeLinkListStr(link);
|
||||||
|
|
||||||
|
rootData.nodes.Add(nodeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeData.components.Add(_comdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckCom(Component[] allcoms, int comRealIdx, int _type, string _rootPath, Component com, string nodepath)
|
||||||
|
{
|
||||||
|
if (com is BoxCollider2D)
|
||||||
|
{
|
||||||
|
BoxCollider2D bc = com as BoxCollider2D;
|
||||||
|
#if UNITY_2017_1_OR_NEWER
|
||||||
|
Debug.Log(nodepath + "BoxCollider2D->center=>(" + bc.offset.x + "," + bc.offset.y + ") size=>(" + bc.size.x + "," + bc.size.y + "");
|
||||||
|
#else
|
||||||
|
Debug.Log(nodepath +"BoxCollider2D->center=>("+ bc.center.x+","+bc.center.y+") size=>("+ bc.size.x+","+bc.size.y+"");
|
||||||
|
#endif
|
||||||
|
AxiStatistics_Node_Component _com = new AxiStatistics_Node_Component();
|
||||||
|
_com.type = typeof(BoxCollider2D).ToString();
|
||||||
|
#if UNITY_2017_1_OR_NEWER
|
||||||
|
_com.center = bc.offset;
|
||||||
|
#else
|
||||||
|
_com.center = bc.center;
|
||||||
|
#endif
|
||||||
|
_com.size = bc.size;
|
||||||
|
SetCompnentIdxNum<BoxCollider2D>(_com, allcoms, comRealIdx, bc);
|
||||||
|
AddComponentData(_type, _rootPath, _com, nodepath, com);
|
||||||
|
}
|
||||||
|
if (com is Rigidbody2D)
|
||||||
|
{
|
||||||
|
Rigidbody2D rig2d = com as Rigidbody2D;
|
||||||
|
Debug.Log(_rootPath + "Rigidbody2D->simulated=>(" + rig2d.simulated + ")");
|
||||||
|
Debug.Log(_rootPath + "Rigidbody2D->IsSleeping=>(" + rig2d.isKinematic.ToString() + ")");
|
||||||
|
|
||||||
|
AxiStatistics_Node_Component _com = new AxiStatistics_Node_Component();
|
||||||
|
_com.type = typeof(Rigidbody2D).ToString();
|
||||||
|
_com.isKinematic = rig2d.isKinematic;
|
||||||
|
_com.simulated = rig2d.simulated;
|
||||||
|
_com.gravityScale = rig2d.gravityScale;
|
||||||
|
SetCompnentIdxNum<Rigidbody2D>(_com, allcoms, comRealIdx, rig2d);
|
||||||
|
AddComponentData(_type, _rootPath, _com, nodepath, com);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 找出同类Idx
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="allcoms"></param>
|
||||||
|
/// <param name="comRealIdx"></param>
|
||||||
|
/// <param name="com"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static void SetCompnentIdxNum<T>(AxiStatistics_Node_Component _comData, Component[] allcoms, int comRealIdx, T com) where T : Component
|
||||||
|
{
|
||||||
|
int ComIdxNum;
|
||||||
|
bool ComTypeIsOnlyOne = false;
|
||||||
|
int TCount = com.transform.GetComponents<T>().Length;
|
||||||
|
if (TCount == 1)
|
||||||
|
{
|
||||||
|
ComIdxNum = 0;
|
||||||
|
ComTypeIsOnlyOne = true;
|
||||||
|
}
|
||||||
|
else if (TCount < 1)
|
||||||
|
{
|
||||||
|
Debug.LogError("找不到,不应该");
|
||||||
|
ComIdxNum = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComIdxNum = -1;
|
||||||
|
for (int i = 0; i < allcoms.Length; i++)
|
||||||
|
{
|
||||||
|
//他自己自然是了
|
||||||
|
if (i == comRealIdx)
|
||||||
|
{
|
||||||
|
ComIdxNum++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (allcoms[i] is T)
|
||||||
|
ComIdxNum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_comData.ComIdxNum = ComIdxNum;
|
||||||
|
_comData.ComTypeOnlyOne = ComTypeIsOnlyOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Axibug移植工具/Statistics/[1]统计所有预制体和场景下的Collider和RigBody")]
|
||||||
|
|
||||||
|
public static void StatisticsCollider()
|
||||||
|
{
|
||||||
|
ClearTempData();
|
||||||
|
StatisticsCollider<BoxCollider2D>();
|
||||||
|
StatisticsCollider<Rigidbody2D>();
|
||||||
|
|
||||||
|
AxiStatisticsCache cache = ScriptableObject.CreateInstance<AxiStatisticsCache>();
|
||||||
|
foreach (var data in dictTempData)
|
||||||
|
cache.caches.Add(data.Value);
|
||||||
|
AssetDatabase.CreateAsset(cache, cachecfgPath);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StatisticsCollider<T>() where T : Component
|
||||||
|
{
|
||||||
|
AxiProjectTools.GoTAxiProjectToolsSence();
|
||||||
|
|
||||||
|
string[] sceneGuids = AssetDatabase.FindAssets("t:scene");
|
||||||
|
foreach (string guid in sceneGuids)
|
||||||
|
{
|
||||||
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
|
if (path.Contains(AxiProjectTools.toolSenceName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#if UNITY_4_6
|
||||||
|
EditorApplication.OpenScene(path);
|
||||||
|
#else
|
||||||
|
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 创建一个列表来存储根节点
|
||||||
|
List<GameObject> rootNodes = new List<GameObject>();
|
||||||
|
|
||||||
|
// 遍历场景中的所有对象
|
||||||
|
GameObject[] allObjects = FindObjectsOfType<GameObject>();
|
||||||
|
foreach (GameObject obj in allObjects)
|
||||||
|
{
|
||||||
|
// 检查对象是否有父对象
|
||||||
|
if (obj.transform.parent == null)
|
||||||
|
{
|
||||||
|
// 如果没有父对象,则它是一个根节点
|
||||||
|
rootNodes.Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var node in rootNodes)
|
||||||
|
LoopPrefabNode<T>(0, path, path, node, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab");
|
||||||
|
foreach (string guid in prefabGuids)
|
||||||
|
{
|
||||||
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
|
GetPrefab<T>(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
AxiProjectTools.GoTAxiProjectToolsSence();
|
||||||
|
Debug.Log("<Color=#FFF333>处理完毕 统计所有预制体和场景下的" + typeof(T).FullName + "</color>");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetPrefab<T>(string path) where T : Component
|
||||||
|
{
|
||||||
|
#if UNITY_4_6
|
||||||
|
GameObject prefab = AssetDatabase.LoadAssetAtPath(path,typeof(GameObject)) as GameObject;
|
||||||
|
#else
|
||||||
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LoopPrefabNode<T>(1, path, path, prefab.gameObject, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoopPrefabNode<T>(int _type, string _rootPath, string noderootPath, GameObject trans, int depth) where T : Component
|
||||||
|
{
|
||||||
|
// #if UNITY_2018_4_OR_NEWER
|
||||||
|
string nodename = noderootPath + "/" + trans.name;
|
||||||
|
GameObject prefabRoot = trans.gameObject;
|
||||||
|
|
||||||
|
Component[] components = prefabRoot.GetComponents<Component>();
|
||||||
|
for (int i = 0; i < components.Length; i++)
|
||||||
|
{
|
||||||
|
var com = components[i];
|
||||||
|
|
||||||
|
if (com == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
T comobj = com as T;
|
||||||
|
if (comobj == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (CheckCom(components, i, _type, _rootPath, comobj, nodename))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历
|
||||||
|
foreach (Transform child in trans.transform)
|
||||||
|
LoopPrefabNode<T>(_type, _rootPath, nodename, child.gameObject, depth + 1);
|
||||||
|
//#else
|
||||||
|
// Debug.Log("低版本不要执行本函数");
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_2017_1_OR_NEWER
|
||||||
|
[MenuItem("Axibug移植工具/Statistics/[2]通过记录,对组件进行修补")]
|
||||||
|
public static void RepairRigBodyByStatistics()
|
||||||
|
{
|
||||||
|
List<string> errLog = new List<string>();
|
||||||
|
List<string> doneLog = new List<string>();
|
||||||
|
List<ValueTuple<string, string>> NeedRepair = new List<ValueTuple<string, string>>();
|
||||||
|
List<ValueTuple<string, string>> FinishRepair = new List<ValueTuple<string, string>>();
|
||||||
|
string CurrScenePath = string.Empty;
|
||||||
|
AxiProjectTools.GoTAxiProjectToolsSence();
|
||||||
|
#if UNITY_4_6
|
||||||
|
AxiStatisticsCache data = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiStatisticsCache)) as AxiStatisticsCache;
|
||||||
|
#else
|
||||||
|
AxiStatisticsCache data = AssetDatabase.LoadAssetAtPath<AxiStatisticsCache>(cachecfgPath);
|
||||||
|
#endif
|
||||||
|
string[] sceneGuids = AssetDatabase.FindAssets("t:scene");
|
||||||
|
List<string> ScenePath = new List<string>();
|
||||||
|
List<string> SceneName = new List<string>();
|
||||||
|
foreach (string guid in sceneGuids)
|
||||||
|
{
|
||||||
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
|
if (path.Contains(AxiProjectTools.toolSenceName))
|
||||||
|
continue;
|
||||||
|
ScenePath.Add(path);
|
||||||
|
SceneName.Add(Path.GetFileName(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] prefabGuids = AssetDatabase.FindAssets("t:prefab");
|
||||||
|
List<string> prefabPath = new List<string>();
|
||||||
|
List<string> prefabName = new List<string>();
|
||||||
|
foreach (string guid in prefabGuids)
|
||||||
|
{
|
||||||
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
|
prefabPath.Add(path);
|
||||||
|
prefabName.Add(Path.GetFileName(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var cache in data.caches.OrderBy(w => w.type))
|
||||||
|
{
|
||||||
|
//场景
|
||||||
|
if (cache.type == 0)
|
||||||
|
{
|
||||||
|
#region 场景加载
|
||||||
|
string targetName = Path.GetFileName(cache.FullPath);
|
||||||
|
int Idx = SceneName.IndexOf(targetName);
|
||||||
|
if (Idx < 0)
|
||||||
|
{
|
||||||
|
Debug.LogError(targetName + "[Repair]找不到对应资源");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
string targetpath = ScenePath[Idx];
|
||||||
|
|
||||||
|
//保证场景切换
|
||||||
|
if (!string.Equals(CurrScenePath, targetpath))
|
||||||
|
{
|
||||||
|
#if UNITY_4_6
|
||||||
|
EditorApplication.OpenScene(targetpath);
|
||||||
|
#else
|
||||||
|
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(targetpath);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
CurrScenePath = targetpath;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
int DirtyCount = 0;
|
||||||
|
foreach (var node in cache.nodes)
|
||||||
|
{
|
||||||
|
GameObject targetNodePathObj = GetNodeByLink(cache.FullPath, node.link, out string errStr);
|
||||||
|
if (targetNodePathObj == null)
|
||||||
|
{
|
||||||
|
errLog.Add(errStr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
string targetNodePath = node.NodeFullPath.Substring(cache.FullPath.Length, node.NodeFullPath.Length - cache.FullPath.Length);
|
||||||
|
|
||||||
|
//GameObject targetNodePathObj = GameObject.Find(targetNodePath);
|
||||||
|
GameObject targetNodePathObj = GetNodeByIdx(node, targetNodePath);
|
||||||
|
|
||||||
|
if (targetNodePathObj == null)
|
||||||
|
{
|
||||||
|
string err = "[Repair]" + node.NodeFullPath + "找不到对应节点";
|
||||||
|
errLog.Add(err);
|
||||||
|
Debug.LogError(err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
foreach (var com in node.components)
|
||||||
|
{
|
||||||
|
if (RepairComponent(node.LinkFullStr, targetNodePathObj, com, out var errlog))
|
||||||
|
{
|
||||||
|
NeedRepair.Add(new ValueTuple<string, string>($"{cache.FullPath}:{node.LinkFullStr}", $"{com.type}[{com.ComIdxNum}]"));
|
||||||
|
DirtyCount++;
|
||||||
|
}
|
||||||
|
errLog.AddRange(errlog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DirtyCount > 0)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Repair][场景处理]{cache.FullPath}共{DirtyCount}个需要处理");
|
||||||
|
|
||||||
|
|
||||||
|
// 获取当前打开的场景
|
||||||
|
var activeScene = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene();
|
||||||
|
|
||||||
|
// 保存场景
|
||||||
|
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(activeScene);
|
||||||
|
|
||||||
|
Debug.Log("场景已保存: " + activeScene.path);
|
||||||
|
string donestr = $"[Repair][场景处理成功]{targetpath},共{DirtyCount}个";
|
||||||
|
doneLog.Add(donestr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cache.type == 1)
|
||||||
|
{
|
||||||
|
string targetpath = cache.FullPath;
|
||||||
|
|
||||||
|
//来到空场景
|
||||||
|
if (!string.IsNullOrEmpty(CurrScenePath))
|
||||||
|
{
|
||||||
|
AxiProjectTools.GoTAxiProjectToolsSence();
|
||||||
|
CurrScenePath = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GameObject prefabInstance = AssetDatabase.LoadAssetAtPath<GameObject>(targetpath);
|
||||||
|
if (prefabInstance == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[Repair]Failed to load prefab at path: {prefabPath}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = GameObject.Instantiate(prefabInstance, null);
|
||||||
|
|
||||||
|
int DirtyCount = 0;
|
||||||
|
foreach (var node in cache.nodes)
|
||||||
|
{
|
||||||
|
GameObject targetNodePathObj = GetNodeByLink(cache.FullPath, node.link, out string errStr, obj);
|
||||||
|
|
||||||
|
if (targetNodePathObj == null)
|
||||||
|
{
|
||||||
|
errLog.Add(errStr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//if (node.NodeFullPath == targetpath + "/" + Path.GetFileNameWithoutExtension(targetpath))
|
||||||
|
//{
|
||||||
|
// //预制体自己就是目标
|
||||||
|
// targetNodePathObj = obj;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// string targetNodePath = node.NodeFullPath.Substring(cache.FullPath.Length + prefabInstance.name.Length + 2, node.NodeFullPath.Length - cache.FullPath.Length - prefabInstance.name.Length - 2);
|
||||||
|
// //targetNodePathObj = obj.transform.Find(targetNodePath)?.gameObject;
|
||||||
|
// targetNodePathObj = GetNodeByIdx(node, targetNodePath, obj);
|
||||||
|
|
||||||
|
// if (targetNodePathObj == null)
|
||||||
|
// {
|
||||||
|
// Debug.LogError("[Repair]" + targetNodePath + "找不到对应节点");
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var com in node.components)
|
||||||
|
{
|
||||||
|
if (RepairComponent(node.LinkFullStr, targetNodePathObj, com, out var errlog))
|
||||||
|
{
|
||||||
|
NeedRepair.Add(new ValueTuple<string, string>($"{cache.FullPath}:{node.LinkFullStr}", $"{com.type}[{com.ComIdxNum}]"));
|
||||||
|
DirtyCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
errLog.AddRange(errlog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DirtyCount > 0)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Repair][预制体处理]{targetpath}共{DirtyCount}个需要处理");
|
||||||
|
PrefabUtility.SaveAsPrefabAsset(obj, targetpath);
|
||||||
|
string donestr = $"[Repair][预制体处理成功]{targetpath},共{DirtyCount}个";
|
||||||
|
doneLog.Add(donestr);
|
||||||
|
}
|
||||||
|
GameObject.DestroyImmediate(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AxiProjectTools.GoTAxiProjectToolsSence();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine("[Repair][统计]:");
|
||||||
|
sb.AppendLine("----处理成功----");
|
||||||
|
foreach (var val in doneLog.OrderBy(w => w))
|
||||||
|
{
|
||||||
|
sb.AppendLine(val);
|
||||||
|
}
|
||||||
|
sb.AppendLine("----异常统计----");
|
||||||
|
foreach (var val in errLog.OrderBy(w => w))
|
||||||
|
{
|
||||||
|
sb.AppendLine(val);
|
||||||
|
}
|
||||||
|
sb.AppendLine("----需要处理----");
|
||||||
|
foreach (var val in NeedRepair.OrderBy(w => w.Item1))
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{val.Item1}=>{val.Item2}");
|
||||||
|
}
|
||||||
|
Debug.Log($"{sb}");
|
||||||
|
|
||||||
|
File.WriteAllText("Assets/AxiNeedRepair.txt", sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static GameObject GetNodeByIdx(AxiStatistics_Node nodedata, string targetNodePath, GameObject root = null)
|
||||||
|
// {
|
||||||
|
// GameObject targetNodePathObj;
|
||||||
|
|
||||||
|
// if (root == null)
|
||||||
|
// targetNodePathObj = GameObject.Find(targetNodePath);
|
||||||
|
// else
|
||||||
|
// targetNodePathObj = root.transform.Find(targetNodePath)?.gameObject;
|
||||||
|
|
||||||
|
// if (targetNodePathObj == null)
|
||||||
|
// return null;
|
||||||
|
|
||||||
|
// string targetName = targetNodePathObj.name;
|
||||||
|
// int currIdx = -1;
|
||||||
|
// if (!nodedata.NodeIdxOnlyOne)
|
||||||
|
// {
|
||||||
|
// if (targetNodePathObj.transform.parent != null)
|
||||||
|
// {
|
||||||
|
//#if UNITY_2017_1_OR_NEWER
|
||||||
|
// int count = targetNodePathObj.transform.parent.childCount;
|
||||||
|
//#else
|
||||||
|
// int count = targetNodePathObj.transform.parent.GetChildCount();
|
||||||
|
//#endif
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// GameObject checkGobj = targetNodePathObj.transform.parent.GetChild(i).gameObject;
|
||||||
|
// if (checkGobj.name == targetName)
|
||||||
|
// {
|
||||||
|
// currIdx++;
|
||||||
|
// if (nodedata.NodeIdx == currIdx)
|
||||||
|
// {
|
||||||
|
// targetNodePathObj = checkGobj;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return targetNodePathObj;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
static GameObject GetNodeByLink(string rootPath, List<AxiStatistics_Node_Link> linklist, out string errStr, GameObject PrefabRoot = null)
|
||||||
|
{
|
||||||
|
List<AxiStatistics_Node_Link> temp_useddlink = new List<AxiStatistics_Node_Link>();
|
||||||
|
if (linklist.Count < 1)
|
||||||
|
{
|
||||||
|
errStr = $"[Repair] Link 为空";
|
||||||
|
Debug.LogError(errStr);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_useddlink.Add(linklist[0]);
|
||||||
|
GameObject currRoot;
|
||||||
|
|
||||||
|
if (PrefabRoot == null)
|
||||||
|
currRoot = GameObject.Find(linklist[0].Name);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currRoot = PrefabRoot;
|
||||||
|
//currRoot = PrefabRoot.transform.Find(linklist[0].Name)?.gameObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currRoot == null)
|
||||||
|
{
|
||||||
|
errStr = $"[Repair] 根节点找不到{rootPath}:{GetNodeLinkListStr(linklist)} => null";
|
||||||
|
Debug.LogError(errStr);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int link_i = 1; link_i < linklist.Count; link_i++)
|
||||||
|
{
|
||||||
|
AxiStatistics_Node_Link targetLink = linklist[link_i];
|
||||||
|
temp_useddlink.Add(targetLink);
|
||||||
|
GameObject findNode = null;
|
||||||
|
#if UNITY_2017_1_OR_NEWER
|
||||||
|
int count = currRoot.transform.childCount;
|
||||||
|
#else
|
||||||
|
int count = currNode.transform.GetChildCount();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (targetLink.OnlyOne)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
GameObject checkGobj = currRoot.transform.GetChild(i).gameObject;
|
||||||
|
if (checkGobj.name == targetLink.Name)
|
||||||
|
{
|
||||||
|
findNode = checkGobj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
Dictionary<int, GameObject> tempHash2Node = new Dictionary<int, GameObject>();
|
||||||
|
List<GameObject> tempGobjList = new List<GameObject>();
|
||||||
|
bool HashDrity = false;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
GameObject checkGobj = currRoot.transform.GetChild(i).gameObject;
|
||||||
|
if (checkGobj.name == targetLink.Name)
|
||||||
|
{
|
||||||
|
int temphash = GetNodeDataHash(checkGobj.transform);
|
||||||
|
if (!tempHash2Node.ContainsKey(temphash))
|
||||||
|
{
|
||||||
|
tempHash2Node.Add(GetNodeDataHash(checkGobj.transform), checkGobj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HashDrity = true;
|
||||||
|
}
|
||||||
|
tempGobjList.Add(checkGobj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hash严格模式
|
||||||
|
if (!HashDrity && tempHash2Node.TryGetValue(targetLink.NodeHash, out var val))
|
||||||
|
{
|
||||||
|
findNode = val;
|
||||||
|
}
|
||||||
|
//下标模式
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (targetLink.Idx < 0 || tempGobjList.Count == 0 || (tempGobjList.Count != 0 && targetLink.Idx >= tempGobjList.Count))
|
||||||
|
{
|
||||||
|
errStr = $"[Repair]link 下标模式 找不到=>{rootPath}:{GetNodeLinkListStr(temp_useddlink)}[{targetLink.Idx}] => 完整链路{rootPath}:{GetNodeLinkListStr(linklist)}";
|
||||||
|
Debug.LogError(errStr);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
findNode = tempGobjList[targetLink.Idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
currRoot = findNode;
|
||||||
|
if (currRoot == null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currRoot == null)
|
||||||
|
{
|
||||||
|
errStr = $"[Repair]link 找不到[{rootPath}:{GetNodeLinkListStr(temp_useddlink)}] => 完整链路{rootPath}:{GetNodeLinkListStr(linklist)}";
|
||||||
|
Debug.LogError(errStr);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errStr = string.Empty;
|
||||||
|
return currRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool RepairComponent(string NodePath, GameObject targetNodePathObj, AxiStatistics_Node_Component comdata, out List<string> Errlog)
|
||||||
|
{
|
||||||
|
Errlog = new List<string>();
|
||||||
|
string err;
|
||||||
|
bool Dirty = false;
|
||||||
|
if (comdata.type == typeof(Rigidbody2D).ToString())
|
||||||
|
{
|
||||||
|
Rigidbody2D rg2d = GetCompnentById<Rigidbody2D>(targetNodePathObj, comdata);
|
||||||
|
if (rg2d == null)
|
||||||
|
{
|
||||||
|
err = $"[Repair]{NodePath}=> Rigidbody2D[{comdata.ComIdxNum}] == null";
|
||||||
|
Debug.LogError(err);
|
||||||
|
Errlog.Add(err);
|
||||||
|
Dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
与新版Unity的差异
|
||||||
|
无BodyType选项:Unity 4.6.7中所有Rigidbody2D默认等效于新版的Dynamic类型(受重力影响),但无法设置为Static或Kinematic。
|
||||||
|
无Simulated选项:只要物体启用了Rigidbody2D组件且Gravity Scale > 0,就会受重力作用。
|
||||||
|
|
||||||
|
所以,一旦老版本gravityScale > 0,就受重力作用,直接设置新版本这边:simulated = true;bodyType = RigidbodyType2D.Dynamic;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (rg2d.gravityScale != comdata.gravityScale)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Repair]{NodePath}=> Rigidbody2D[{comdata.ComIdxNum}] simulated:{rg2d.gravityScale} != :{comdata.gravityScale} rg2d.bodyType => {rg2d.bodyType} ");
|
||||||
|
|
||||||
|
rg2d.gravityScale = comdata.gravityScale;
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (rg2d.gravityScale > 0 && (!rg2d.simulated || rg2d.bodyType != RigidbodyType2D.Dynamic))
|
||||||
|
if (!rg2d.simulated || rg2d.bodyType != RigidbodyType2D.Dynamic)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Repair]{NodePath}=> Rigidbody2D[{comdata.ComIdxNum}] simulated:{rg2d.simulated} != :{comdata.simulated} rg2d.bodyType => {rg2d.bodyType} ");
|
||||||
|
|
||||||
|
rg2d.simulated = true;
|
||||||
|
rg2d.bodyType = RigidbodyType2D.Dynamic;
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (comdata.type == typeof(BoxCollider2D).ToString())
|
||||||
|
{
|
||||||
|
BoxCollider2D bc = GetCompnentById<BoxCollider2D>(targetNodePathObj, comdata);
|
||||||
|
if (bc == null)
|
||||||
|
{
|
||||||
|
err = $"[Repair]{NodePath}=> BoxCollider2D[{comdata.ComIdxNum}] == null";
|
||||||
|
Debug.LogError(err);
|
||||||
|
Errlog.Add(err);
|
||||||
|
Dirty = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bc.size != comdata.size)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Repair]{NodePath} BoxCollider2D[{comdata.ComIdxNum}] => size:{bc.size} != {comdata.size} ");
|
||||||
|
bc.size = comdata.size;
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
if (bc.offset != comdata.center)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Repair]{NodePath} BoxCollider2D[{comdata.ComIdxNum}] => offset:{bc.offset} != center{comdata.center} ");
|
||||||
|
bc.offset = comdata.center;
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dirty)
|
||||||
|
{
|
||||||
|
bc.size = comdata.size;
|
||||||
|
bc.offset = comdata.center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return Dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T GetCompnentById<T>(GameObject gobj, AxiStatistics_Node_Component node) where T : Component
|
||||||
|
{
|
||||||
|
if (node.ComIdxNum == 0)
|
||||||
|
return gobj.GetComponent<T>();
|
||||||
|
else if (node.ComIdxNum > 0)
|
||||||
|
{
|
||||||
|
T[] coms = gobj.GetComponents<T>();
|
||||||
|
if (node.ComIdxNum < coms.Length)
|
||||||
|
return coms[node.ComIdxNum];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 32aabdd304d2c4d47b8ef660f672ead1
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
@ -3,19 +3,18 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.SceneManagement;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
|
|
||||||
public class AxiProjectTools : EditorWindow
|
public class AxiProjectTools : EditorWindow
|
||||||
{
|
{
|
||||||
static string cachecfgPath = "Assets/AxiComToolCache.asset";
|
static string cachecfgPath = "Assets/AxiComToolCache.asset";
|
||||||
static string toolSenceName = "AxiProjectTools";
|
public static string toolSenceName = "AxiProjectTools";
|
||||||
static string outCsDir = Application.dataPath + "/AxiCom/";
|
public static string outCsDir = Application.dataPath + "/AxiCom/";
|
||||||
static Dictionary<string, AxiPrefabCache_Com2GUID> ComType2GUID = new Dictionary<string, AxiPrefabCache_Com2GUID>();
|
public static Dictionary<string, AxiPrefabCache_Com2GUID> ComType2GUID = new Dictionary<string, AxiPrefabCache_Com2GUID>();
|
||||||
|
|
||||||
static void GoTAxiProjectToolsSence()
|
public static void GoTAxiProjectToolsSence()
|
||||||
{
|
{
|
||||||
string[] sceneGuids = AssetDatabase.FindAssets("t:scene");
|
string[] sceneGuids = AssetDatabase.FindAssets("t:scene");
|
||||||
foreach (string guid in sceneGuids)
|
foreach (string guid in sceneGuids)
|
||||||
@ -23,7 +22,11 @@ public class AxiProjectTools : EditorWindow
|
|||||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
if (path.Contains(toolSenceName))
|
if (path.Contains(toolSenceName))
|
||||||
{
|
{
|
||||||
EditorSceneManager.OpenScene(path);
|
#if UNITY_4_6
|
||||||
|
EditorApplication.OpenScene(path);
|
||||||
|
#else
|
||||||
|
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +44,11 @@ public class AxiProjectTools : EditorWindow
|
|||||||
if (path.Contains(toolSenceName))
|
if (path.Contains(toolSenceName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
EditorSceneManager.OpenScene(path);
|
#if UNITY_4_6
|
||||||
|
EditorApplication.OpenScene(path);
|
||||||
|
#else
|
||||||
|
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 创建一个列表来存储根节点
|
// 创建一个列表来存储根节点
|
||||||
List<GameObject> rootNodes = new List<GameObject>();
|
List<GameObject> rootNodes = new List<GameObject>();
|
||||||
@ -82,18 +89,25 @@ public class AxiProjectTools : EditorWindow
|
|||||||
|
|
||||||
static void GetPrefab(string path)
|
static void GetPrefab(string path)
|
||||||
{
|
{
|
||||||
|
#if UNITY_4_6
|
||||||
|
GameObject prefab = AssetDatabase.LoadAssetAtPath(path,typeof(GameObject)) as GameObject;
|
||||||
|
#else
|
||||||
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
||||||
|
#endif
|
||||||
|
|
||||||
LoopPrefabNode(path, prefab.gameObject, 0);
|
LoopPrefabNode(path, prefab.gameObject, 0);
|
||||||
}
|
}
|
||||||
static void LoopPrefabNode(string rootPath, GameObject trans, int depth)
|
static void LoopPrefabNode(string rootPath, GameObject trans, int depth)
|
||||||
{
|
{
|
||||||
string nodename = $"{rootPath}>{trans.name}";
|
// #if UNITY_2018_4_OR_NEWER
|
||||||
#if UNITY_2018_4_OR_NEWER
|
string nodename = rootPath + trans.name;
|
||||||
GameObject prefabRoot = trans.gameObject;
|
GameObject prefabRoot = trans.gameObject;
|
||||||
int comCount = prefabRoot.GetComponentCount();
|
|
||||||
for (int i = 0; i < comCount; i++)
|
Component[] components = prefabRoot.GetComponents<Component>();
|
||||||
|
for (int i = 0; i < components.Length; i++)
|
||||||
{
|
{
|
||||||
var com = prefabRoot.GetComponentAtIndex(i);
|
var com = components[i];
|
||||||
|
|
||||||
if (com == null)
|
if (com == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -109,7 +123,7 @@ public class AxiProjectTools : EditorWindow
|
|||||||
{
|
{
|
||||||
// 获取MonoScript资源的GUID
|
// 获取MonoScript资源的GUID
|
||||||
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(monoScript));
|
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(monoScript));
|
||||||
Debug.Log($"{nodename} | <color=#FFF333>[{monoType.Name}]</color> <color=#FF0000>{guid}</color><color=#00FF00>({monoType.FullName})</color>");
|
Debug.Log(nodename+" | <color=#FFF333>["+monoType.Name+"]</color> <color=#FF0000>"+guid+"</color><color=#00FF00>("+monoType.FullName+")</color>");
|
||||||
ComType2GUID[monoType.FullName] =
|
ComType2GUID[monoType.FullName] =
|
||||||
new AxiPrefabCache_Com2GUID()
|
new AxiPrefabCache_Com2GUID()
|
||||||
{
|
{
|
||||||
@ -127,18 +141,33 @@ public class AxiProjectTools : EditorWindow
|
|||||||
//遍历
|
//遍历
|
||||||
foreach (Transform child in trans.transform)
|
foreach (Transform child in trans.transform)
|
||||||
LoopPrefabNode(nodename, child.gameObject, depth + 1);
|
LoopPrefabNode(nodename, child.gameObject, depth + 1);
|
||||||
#else
|
//#else
|
||||||
Debug.Log("低版本不要执行本函数");
|
// Debug.Log("低版本不要执行本函数");
|
||||||
#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Axibug移植工具/ToLowVersionUnity/[2]生成中间脚本代码")]
|
[MenuItem("Axibug移植工具/ToLowVersionUnity/[2]生成中间脚本代码")]
|
||||||
public static void Part2()
|
public static void Part2()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if UNITY_4_6
|
||||||
|
if(System.IO.Directory.Exists(outCsDir))
|
||||||
|
System.IO.Directory.Delete(outCsDir);
|
||||||
|
#else
|
||||||
if (UnityEngine.Windows.Directory.Exists(outCsDir))
|
if (UnityEngine.Windows.Directory.Exists(outCsDir))
|
||||||
UnityEngine.Windows.Directory.Delete(outCsDir);
|
UnityEngine.Windows.Directory.Delete(outCsDir);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Directory.CreateDirectory(outCsDir);
|
Directory.CreateDirectory(outCsDir);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if UNITY_4_6
|
||||||
|
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiPrefabCache)) as AxiPrefabCache;
|
||||||
|
#else
|
||||||
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath<AxiPrefabCache>(cachecfgPath);
|
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath<AxiPrefabCache>(cachecfgPath);
|
||||||
|
#endif
|
||||||
foreach (var data in cache.caches)
|
foreach (var data in cache.caches)
|
||||||
{
|
{
|
||||||
string toName = "Axi" + data.SrcName;
|
string toName = "Axi" + data.SrcName;
|
||||||
@ -164,8 +193,14 @@ public class AxiProjectTools : EditorWindow
|
|||||||
[MenuItem("Axibug移植工具/ToLowVersionUnity/[3]收集生成的脚本")]
|
[MenuItem("Axibug移植工具/ToLowVersionUnity/[3]收集生成的脚本")]
|
||||||
public static void Part3()
|
public static void Part3()
|
||||||
{
|
{
|
||||||
|
#if UNITY_4_6
|
||||||
|
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiPrefabCache)) as AxiPrefabCache;
|
||||||
|
MonoScript[] allMonoScripts = (MonoScript[])Resources.FindObjectsOfTypeAll(typeof(MonoScript));
|
||||||
|
#else
|
||||||
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath<AxiPrefabCache>(cachecfgPath);
|
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath<AxiPrefabCache>(cachecfgPath);
|
||||||
List<MonoScript> allMonoScripts = FindAllAssetsOfType<MonoScript>();
|
List<MonoScript> allMonoScripts = FindAllAssetsOfType<MonoScript>();
|
||||||
|
#endif
|
||||||
|
|
||||||
foreach (var data in cache.caches)
|
foreach (var data in cache.caches)
|
||||||
{
|
{
|
||||||
MonoScript monoScript = allMonoScripts.FirstOrDefault(w => w.name == data.ToName);
|
MonoScript monoScript = allMonoScripts.FirstOrDefault(w => w.name == data.ToName);
|
||||||
@ -194,7 +229,12 @@ public class AxiProjectTools : EditorWindow
|
|||||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
if (path.EndsWith(".cs") || path.EndsWith(".js") || path.EndsWith(".boo")) // Unity支持多种脚本语言,但现代Unity主要使用C#
|
if (path.EndsWith(".cs") || path.EndsWith(".js") || path.EndsWith(".boo")) // Unity支持多种脚本语言,但现代Unity主要使用C#
|
||||||
{
|
{
|
||||||
|
#if UNITY_4_6
|
||||||
|
T asset = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(T)) as T;
|
||||||
|
#else
|
||||||
T asset = AssetDatabase.LoadAssetAtPath<T>(path);
|
T asset = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
{
|
{
|
||||||
assets.Add(asset);
|
assets.Add(asset);
|
||||||
@ -208,7 +248,13 @@ public class AxiProjectTools : EditorWindow
|
|||||||
[MenuItem("Axibug移植工具/ToLowVersionUnity/[4]替换所有预制体和场景中的组件")]
|
[MenuItem("Axibug移植工具/ToLowVersionUnity/[4]替换所有预制体和场景中的组件")]
|
||||||
public static void Part4()
|
public static void Part4()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if UNITY_4_6
|
||||||
|
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiPrefabCache)) as AxiPrefabCache;
|
||||||
|
#else
|
||||||
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath<AxiPrefabCache>(cachecfgPath);
|
AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath<AxiPrefabCache>(cachecfgPath);
|
||||||
|
#endif
|
||||||
|
|
||||||
Dictionary<string, string> tempReplaceDict = new Dictionary<string, string>();
|
Dictionary<string, string> tempReplaceDict = new Dictionary<string, string>();
|
||||||
foreach (var data in cache.caches)
|
foreach (var data in cache.caches)
|
||||||
{
|
{
|
||||||
@ -286,8 +332,8 @@ public class AxiProjectTools : EditorWindow
|
|||||||
if (path.Contains(toolSenceName))
|
if (path.Contains(toolSenceName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
EditorSceneManager.OpenScene(path);
|
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path);
|
||||||
Scene currentScene = SceneManager.GetActiveScene();
|
UnityEngine.SceneManagement.Scene currentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
||||||
GameObject[] rootObjects = currentScene.GetRootGameObjects();
|
GameObject[] rootObjects = currentScene.GetRootGameObjects();
|
||||||
foreach (GameObject rootObj in rootObjects)
|
foreach (GameObject rootObj in rootObjects)
|
||||||
{
|
{
|
||||||
@ -295,9 +341,9 @@ public class AxiProjectTools : EditorWindow
|
|||||||
TraverseHierarchy(rootObj);
|
TraverseHierarchy(rootObj);
|
||||||
}
|
}
|
||||||
// Save the scene // 获取当前打开的场景
|
// Save the scene // 获取当前打开的场景
|
||||||
currentScene = EditorSceneManager.GetActiveScene();
|
currentScene = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene();
|
||||||
// 保存场景到文件(默认路径和名称)
|
// 保存场景到文件(默认路径和名称)
|
||||||
bool success = EditorSceneManager.SaveScene(currentScene, currentScene.path);
|
bool success = UnityEditor.SceneManagement.EditorSceneManager.SaveScene(currentScene, currentScene.path);
|
||||||
|
|
||||||
Debug.Log($"{currentScene.name}场景中 所有物体Unpack");
|
Debug.Log($"{currentScene.name}场景中 所有物体Unpack");
|
||||||
}
|
}
|
||||||
@ -413,5 +459,48 @@ public class AxiProjectTools : EditorWindow
|
|||||||
textureImporter.SaveAndReimport();
|
textureImporter.SaveAndReimport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MenuItem("Axibug移植工具/ToLowVersionUnity/[7]导入后低版本执行:修复组件挂载预制体依赖丢失")]
|
||||||
|
static void FixPrefabRefs()
|
||||||
|
{
|
||||||
|
// 1. 扫描所有预制体
|
||||||
|
string[] prefabPaths = Directory.GetFiles("Assets", "*.prefab", SearchOption.AllDirectories);
|
||||||
|
foreach (var path in prefabPaths) FixRefTypeInFile(path);
|
||||||
|
|
||||||
|
// 2. 处理场景文件
|
||||||
|
string[] scenePaths = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories);
|
||||||
|
foreach (var path in scenePaths) FixRefTypeInFile(path);
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
Debug.Log("<Color=#FFF333>处理完毕 [5]导入低版本后:修复预制体依赖丢失</color>");
|
||||||
|
Debug.Log("修复完成!已处理" + prefabPaths.Length + "个预制体");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FixRefTypeInFile(string filePath)
|
||||||
|
{
|
||||||
|
string content = File.ReadAllText(filePath);
|
||||||
|
// 匹配所有 {fileID: X, guid: Y, type: Z} 结构
|
||||||
|
string pattern = @"(\{[^}]*guid:\s*(\w+)[^}]*type:\s*)3(\s*[^}]*\})";
|
||||||
|
string newContent = Regex.Replace(content, pattern, match => {
|
||||||
|
string guid = match.Groups[2].Value;
|
||||||
|
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
|
// 仅当资源类型为 GameObject 时修改 type
|
||||||
|
if (AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(GameObject))
|
||||||
|
// if (assetPath.ToLower().EndsWith(".prefab")
|
||||||
|
////&& assetPath.Contains("/sound/")
|
||||||
|
//&& assetPath.Contains("/level")
|
||||||
|
// )
|
||||||
|
{
|
||||||
|
Debug.Log("已处理被引用项=>"+assetPath+" ,引用到=>"+ filePath);
|
||||||
|
Debug.Log("原值=>" + match.Value + " ,处理值=>"+ match.Groups[1].Value + "2" + match.Groups[3].Value);
|
||||||
|
//return match.Value;
|
||||||
|
return match.Groups[1].Value + "2" + match.Groups[3].Value; // type:3→2
|
||||||
|
}
|
||||||
|
return match.Value;
|
||||||
|
});
|
||||||
|
File.WriteAllText(filePath, newContent);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
#if UNITY_EDITOR
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
public class AxiStatisticsCache : ScriptableObject
|
||||||
|
{
|
||||||
|
public List<AxiStatisticsDatas> caches = new List<AxiStatisticsDatas>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class AxiStatisticsDatas
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// [0]Sence [1]Prefab
|
||||||
|
/// </summary>
|
||||||
|
public int type;
|
||||||
|
public string FullPath;
|
||||||
|
public List<AxiStatistics_Node> nodes = new List<AxiStatistics_Node>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class AxiStatistics_Node
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public List<AxiStatistics_Node_Link> link = new List<AxiStatistics_Node_Link>();
|
||||||
|
public int LinkHash;
|
||||||
|
public string LinkFullStr;
|
||||||
|
//public string NodeFullPath;
|
||||||
|
// /// <summary>
|
||||||
|
// /// 表示相同路径只有一个
|
||||||
|
// /// </summary>
|
||||||
|
// public bool NodeIdxOnlyOne;
|
||||||
|
/// <summary>
|
||||||
|
/// 表示相同路径是第几个下标
|
||||||
|
/// </summary>
|
||||||
|
//public int NodeIdx;
|
||||||
|
public List<AxiStatistics_Node_Component> components = new List<AxiStatistics_Node_Component>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class AxiStatistics_Node_Link
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public bool OnlyOne;
|
||||||
|
public int Idx;
|
||||||
|
public int NodeHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class AxiStatistics_Node_Component
|
||||||
|
{
|
||||||
|
public string type;
|
||||||
|
/// <summary>
|
||||||
|
/// 表示相同组件只有一个
|
||||||
|
/// </summary>
|
||||||
|
public bool ComTypeOnlyOne;
|
||||||
|
/// <summary>
|
||||||
|
/// 表示相同组件是第几个下标
|
||||||
|
/// </summary>
|
||||||
|
public int ComIdxNum;
|
||||||
|
//Rigboody
|
||||||
|
public bool simulated;
|
||||||
|
public float gravityScale;
|
||||||
|
public bool isKinematic;
|
||||||
|
//BoxCollider2D
|
||||||
|
public Vector2 center;
|
||||||
|
public Vector2 size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e4cee4feffb506b4c833262e779424f6
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
@ -15,6 +15,11 @@ public class AxiNS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 延迟提交是否使用多线程
|
||||||
|
/// </summary>
|
||||||
|
public static bool usedmultithreading = false;
|
||||||
|
|
||||||
public AxiNSUser user;
|
public AxiNSUser user;
|
||||||
public AxiNSMount mount;
|
public AxiNSMount mount;
|
||||||
public AxiNSIO io;
|
public AxiNSIO io;
|
||||||
|
|||||||
@ -309,12 +309,15 @@ public class AxiNSIO
|
|||||||
}
|
}
|
||||||
public byte[] LoadSwitchDataFile(string filename)
|
public byte[] LoadSwitchDataFile(string filename)
|
||||||
{
|
{
|
||||||
LoadSwitchDataFile(filename, out byte[] outputData);
|
byte[] outputData;
|
||||||
|
LoadSwitchDataFile(filename, out outputData);
|
||||||
return outputData;
|
return outputData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms)
|
public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms)
|
||||||
{
|
{
|
||||||
if (LoadSwitchDataFile(filename, out byte[] outputData))
|
byte[] outputData;
|
||||||
|
if (LoadSwitchDataFile(filename, out outputData))
|
||||||
{
|
{
|
||||||
using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms))
|
using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms))
|
||||||
{
|
{
|
||||||
@ -383,6 +386,7 @@ public class AxiNSIO
|
|||||||
AxiNS.instance.wait.AddWait(wait);
|
AxiNS.instance.wait.AddWait(wait);
|
||||||
return wait;
|
return wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetDirectoryFiles(string path, out string[] entrys)
|
public bool GetDirectoryFiles(string path, out string[] entrys)
|
||||||
{
|
{
|
||||||
#if !UNITY_SWITCH || UNITY_EDITOR
|
#if !UNITY_SWITCH || UNITY_EDITOR
|
||||||
@ -393,6 +397,7 @@ public class AxiNSIO
|
|||||||
return GetDirectoryEntrys(path,nn.fs.OpenDirectoryMode.File,out entrys);
|
return GetDirectoryEntrys(path,nn.fs.OpenDirectoryMode.File,out entrys);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetDirectoryDirs(string path, out string[] entrys)
|
public bool GetDirectoryDirs(string path, out string[] entrys)
|
||||||
{
|
{
|
||||||
#if !UNITY_SWITCH || UNITY_EDITOR
|
#if !UNITY_SWITCH || UNITY_EDITOR
|
||||||
@ -430,6 +435,7 @@ public class AxiNSIO
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys)
|
public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys)
|
||||||
{
|
{
|
||||||
#if UNITY_SWITCH
|
#if UNITY_SWITCH
|
||||||
@ -462,7 +468,7 @@ public class AxiNSIO
|
|||||||
entrys = temp.ToArray();
|
entrys = temp.ToArray();
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
entrys = default;
|
entrys = null;
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -597,16 +603,83 @@ public class AxiNSIO
|
|||||||
return CommitSave();
|
return CommitSave();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_SWITCH
|
|
||||||
public AxiNSWait_DeletePathDirRecursively DeletePathDirRecursivelyAsync(string filename)
|
public AxiNSWait_DeletePathDirRecursively DeletePathDirRecursivelyAsync(string filename)
|
||||||
{
|
{
|
||||||
var wait = new AxiNSWait_DeletePathDirRecursively(filename);
|
var wait = new AxiNSWait_DeletePathDirRecursively(filename);
|
||||||
AxiNS.instance.wait.AddWait(wait);
|
AxiNS.instance.wait.AddWait(wait);
|
||||||
return wait;
|
return wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// µÝ¹éɾ³ýĿ¼
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool DeleteRecursivelyPathDir(string filename)
|
||||||
|
{
|
||||||
|
#if !UNITY_SWITCH
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if UNITY_SWITCH && !UNITY_EDITOR
|
||||||
|
// This next line prevents the user from quitting the game while saving.
|
||||||
|
// This is required for Nintendo Switch Guideline 0080
|
||||||
|
UnityEngine.Switch.Notification.EnterExitRequestHandlingSection();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (CheckPathNotFound(filename))
|
||||||
|
return false;
|
||||||
|
nn.Result result;
|
||||||
|
result = nn.fs.Directory.DeleteRecursively(filename);
|
||||||
|
if (result.IsSuccess() == false)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively ʧ°Ü {filename} : result=>{result.GetErrorInfo()}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_SWITCH && !UNITY_EDITOR
|
||||||
|
// End preventing the user from quitting the game while saving.
|
||||||
|
UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection();
|
||||||
|
#endif
|
||||||
|
return CommitSave();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// µÝ¹éɾ³ýÇé¿ö
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool CleanRecursivelyPathDir(string filename)
|
||||||
|
{
|
||||||
|
#if !UNITY_SWITCH
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if UNITY_SWITCH && !UNITY_EDITOR
|
||||||
|
// This next line prevents the user from quitting the game while saving.
|
||||||
|
// This is required for Nintendo Switch Guideline 0080
|
||||||
|
UnityEngine.Switch.Notification.EnterExitRequestHandlingSection();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (CheckPathNotFound(filename))
|
||||||
|
return false;
|
||||||
|
nn.Result result;
|
||||||
|
result = nn.fs.Directory.CleanRecursively(filename);
|
||||||
|
if (result.IsSuccess() == false)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively ʧ°Ü {filename} : result=>{result.GetErrorInfo()}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_SWITCH && !UNITY_EDITOR
|
||||||
|
// End preventing the user from quitting the game while saving.
|
||||||
|
UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection();
|
||||||
|
#endif
|
||||||
|
return CommitSave();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
public bool RenameDir(string oldpath, string newpath)
|
public bool RenameDir(string oldpath, string newpath)
|
||||||
{
|
{
|
||||||
#if !UNITY_SWITCH
|
#if !UNITY_SWITCH
|
||||||
|
|||||||
41
AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMono.cs
Normal file
41
AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMono.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class AxiNSMono : MonoBehaviour
|
||||||
|
{
|
||||||
|
Action act;
|
||||||
|
float waittime;
|
||||||
|
float lastinvokeTime;
|
||||||
|
|
||||||
|
public static void SetInvoke(Action _act, int _waitsec)
|
||||||
|
{
|
||||||
|
GameObject gobj = GameObject.Find($"[{nameof(AxiNSMono)}]");
|
||||||
|
if (gobj == null)
|
||||||
|
{
|
||||||
|
gobj = new GameObject();
|
||||||
|
gobj.name = $"[{nameof(AxiNSMono)}]";
|
||||||
|
GameObject.DontDestroyOnLoad(gobj);
|
||||||
|
}
|
||||||
|
AxiNSMono com = gobj.GetComponent<AxiNSMono>();
|
||||||
|
if (com == null)
|
||||||
|
{
|
||||||
|
com = gobj.AddComponent<AxiNSMono>();
|
||||||
|
}
|
||||||
|
com.act = _act;
|
||||||
|
com.waittime = _waitsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEnable()
|
||||||
|
{
|
||||||
|
Debug.Log("AxiNSMono Enable");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (Time.time - lastinvokeTime < waittime)
|
||||||
|
return;
|
||||||
|
lastinvokeTime = Time.time;
|
||||||
|
if (act != null)
|
||||||
|
act.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 23d5745b8989af04d8a871b5c7b65d50
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -117,3 +117,18 @@ public class AxiNSWait_DeletePathDir : AxiNSWaitBase
|
|||||||
result = AxiNS.instance.io.DeletePathDir(req.filePath);
|
result = AxiNS.instance.io.DeletePathDir(req.filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AxiNSWait_DeletePathDirRecursively : AxiNSWaitBase
|
||||||
|
{
|
||||||
|
S_NSWAIT_Path req;
|
||||||
|
public bool result;
|
||||||
|
public AxiNSWait_DeletePathDirRecursively(string filePath)
|
||||||
|
{
|
||||||
|
req = new S_NSWAIT_Path() { filePath = filePath };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Invoke()
|
||||||
|
{
|
||||||
|
result = AxiNS.instance.io.DeletePathDirRecursively(req.filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,21 +4,30 @@ using System.Threading;
|
|||||||
|
|
||||||
public class AxiNSWaitHandle
|
public class AxiNSWaitHandle
|
||||||
{
|
{
|
||||||
static AutoResetEvent autoEvent = new AutoResetEvent(false);
|
|
||||||
static Thread waitThread = new Thread(Loop);
|
|
||||||
static bool bSingleInit = false;
|
|
||||||
static Queue<AxiNSWaitBase> m_QueueReady = new Queue<AxiNSWaitBase>();
|
static Queue<AxiNSWaitBase> m_QueueReady = new Queue<AxiNSWaitBase>();
|
||||||
static Queue<AxiNSWaitBase> m_QueueWork = new Queue<AxiNSWaitBase>();
|
static Queue<AxiNSWaitBase> m_QueueWork = new Queue<AxiNSWaitBase>();
|
||||||
public void AddWait(AxiNSWaitBase wait)
|
public void AddWait(AxiNSWaitBase wait)
|
||||||
{
|
{
|
||||||
InitInternalThread();
|
|
||||||
lock (m_QueueReady)
|
lock (m_QueueReady)
|
||||||
{
|
{
|
||||||
m_QueueReady.Enqueue(wait);
|
m_QueueReady.Enqueue(wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AxiNS.usedmultithreading)
|
||||||
|
{
|
||||||
|
InitInternalThread();
|
||||||
autoEvent.Set();
|
autoEvent.Set();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InitMonoInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 多线程实现
|
||||||
|
static AutoResetEvent autoEvent = new AutoResetEvent(false);
|
||||||
|
static Thread waitThread = new Thread(Loop);
|
||||||
|
static bool bSingleInit = false;
|
||||||
static void InitInternalThread()
|
static void InitInternalThread()
|
||||||
{
|
{
|
||||||
if (bSingleInit) return;
|
if (bSingleInit) return;
|
||||||
@ -29,6 +38,23 @@ public class AxiNSWaitHandle
|
|||||||
static void Loop()
|
static void Loop()
|
||||||
{
|
{
|
||||||
while (autoEvent.WaitOne())
|
while (autoEvent.WaitOne())
|
||||||
|
{
|
||||||
|
Do();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 主线程时间间隔实现
|
||||||
|
static bool bMonoInit = false;
|
||||||
|
static void InitMonoInit()
|
||||||
|
{
|
||||||
|
if (bMonoInit) return;
|
||||||
|
AxiNSMono.SetInvoke(Do,15);
|
||||||
|
bMonoInit = true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
static void Do()
|
||||||
{
|
{
|
||||||
lock (m_QueueReady)
|
lock (m_QueueReady)
|
||||||
{
|
{
|
||||||
@ -53,4 +79,3 @@ public class AxiNSWaitHandle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 25ea535c006d6544d9b301a2dcde95b9
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"timestamp": 1648458313,
|
||||||
|
"signature": "DWppfmRE13R6S+n/9p1BkuJhH8i4OF2aZu3uXd+7pP8L9LaFr+oymbRCxdy+8l1IFlQzQbQL1ewVCMnKQIonn36dYoZpneipJbUa4CBvwiDObtwD1WSasTq8d9smbhOmeBewyLfkHsGmI4z0WvSJFyq11ISeMXe8pCVoq/PNi5gKfxwvOh4Cy49Y65MZOGAI0MOcOyfQjRS7cR5oPEtAQJysVRtcJPcbPSgr5tjbM9dLf7h5/J6AWXCBav4m6h6932umoOv5FsBQhNQquKqbC984E5ku8G45UKX7t7V0pJFBQe0y1++MN8aSVyJ08IV6h206tTOfIyZVRwswMGGyoAvbF5SF0CmL12QbkW7giZJTa23fvOv09sM3nlA2JpyVSvPWgMmv5HGsLvaboXxSVAp6HcN1M83rMPiQaS34YW/f+JgrHumKa/TTwpzml7kG5xdk3dOACLHRlyDag3oHYmC1OpaI1rnlt7r+z3gCYz5dGTavkHHnNRBukliZYft/",
|
||||||
|
"publicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to the input system package will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||||
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
Due to package verification, the latest version below is the unpublished version and the date is meaningless.
|
||||||
|
however, it has to be formatted properly to pass verification tests.
|
||||||
|
|
||||||
|
## [0.1.0-preview] - 2019-9-2
|
||||||
|
|
||||||
|
First release from develop branch.
|
||||||
|
|
||||||
|
## [0.1.1-preview] - 2019-10-29
|
||||||
|
|
||||||
|
Updated package dependencies to use latest `com.unity.inputsystem` package version 1.0.0-preview.1
|
||||||
|
|
||||||
|
## [0.1.2-preview] - 2021-05-17
|
||||||
|
|
||||||
|
Updated package dependencies to `com.unity.inputsystem` package version 1.1.0-preview.2 and Unity 2019.4
|
||||||
|
|
||||||
|
Overrides added for aButton, bButton, xButton, yButton functions to map to north, south, east, west buttons correctly for Nintendo layout.
|
||||||
|
Fixed incorrect shortDisplayName values inherited from Gamepad.cs
|
||||||
|
Added "Submit" & "Cancel" UI usage tags to A and B buttons.
|
||||||
|
Added Joy-Con attrbutes to NPad.cs as a bit field, with accessors to get connected and wired states.
|
||||||
|
Minium Unity versions for checking m_Attributes functions (IsWired/IsConnected)
|
||||||
|
2021.2.0a10, 2021.1.1f1, 2020.3.4f1, 2019.4.24f1
|
||||||
|
Added code to parse the Unity application version string and test for NPad attributes support (Assert if attempting to use attributes and Unity version is below minimum required).
|
||||||
|
|
||||||
|
## [0.1.3-pre] - 2021-07-06
|
||||||
|
|
||||||
|
Updated package dependencies to use `com.unity.inputsystem` package 1.1.0-pre.5
|
||||||
|
This fixes an issue where earlier 'com.unity.inputsystem' packages (1.1.0-preview.X) were considered more recent than 1.1.0-pre.5 due to the Semantic Versioning spec and that prevented upgrading to 1.1.0-pre.5 or later.
|
||||||
|
Updated the package name to the use the "Pre-release" label following the new package lifecycle naming convention & patch version increased.
|
||||||
|
|
||||||
|
## [0.1.4-pre] - 2021-11-03
|
||||||
|
|
||||||
|
Fixed logic error in minimum version check (IsVersionOrHigher) for checking support for m_Attributes.
|
||||||
|
The Unity version type (alpha, beta, final etc) should be checked ahead of the revision, so 2021.2.0f1 (final 1) is recognised as a later version than 2021.2.0a10 (alpha 10)
|
||||||
|
|
||||||
|
## [0.1.5-pre] - 2021-11-15
|
||||||
|
|
||||||
|
The package is now signed.
|
||||||
|
|
||||||
|
## [0.1.6-pre] - 2022-03-55
|
||||||
|
|
||||||
|
Fixed a bug where ResetHaptics and PauseHaptics functions were not specifying a RumblePosition flag (Was None, should be All) and so had no effect when called.
|
||||||
|
NPadDeviceIOCTLOutputCommand Create function now takes RumblePosition as an argument (defaulting to All)
|
||||||
|
Fixed a bug in NPadRumbleValues.Reset() where frequencyHigh was not being reset.
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2fe913aba0c6c104ca6b05e2a1def256
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3b3482582c1bb9341aacbb0a24c53938
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aaa7ef903a2a1a041b6888d1a259bda3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9177521509a3da24cb1e37e9eb8d7248
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
#if UNITY_EDITOR || UNITY_SWITCH
|
||||||
|
using UnityEngine.InputSystem.Haptics;
|
||||||
|
|
||||||
|
namespace UnityEngine.InputSystem.Switch
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extended dual motor gamepad that adds seperate controls for rumble frequency and amplitude.
|
||||||
|
/// </summary>
|
||||||
|
public interface INPadRumble : IDualMotorRumble
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Set rumble for all motors
|
||||||
|
/// </summary>
|
||||||
|
void SetMotorSpeeds(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set rumble for left motor
|
||||||
|
/// </summary>
|
||||||
|
void SetMotorSpeedLeft(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set rumble for right motor
|
||||||
|
/// </summary>
|
||||||
|
void SetMotorSpeedRight(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f7abf5d9c0bddda4cb82a5d0b3525c0b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,746 @@
|
|||||||
|
#if UNITY_EDITOR || UNITY_SWITCH || PACKAGE_DOCS_GENERATION
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using UnityEngine.InputSystem.Controls;
|
||||||
|
using UnityEngine.InputSystem.Layouts;
|
||||||
|
using UnityEngine.InputSystem.LowLevel;
|
||||||
|
using UnityEngine.InputSystem.Switch.LowLevel;
|
||||||
|
using UnityEngine.InputSystem.Utilities;
|
||||||
|
|
||||||
|
////REVIEW: The Switch controller can be used to point at things; can we somehow help leverage that?
|
||||||
|
|
||||||
|
namespace UnityEngine.InputSystem.Switch.LowLevel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Structure of native input reports for Switch NPad controllers.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso href="http://en-americas-support.nintendo.com/app/answers/detail/a_id/22634/~/joy-con-controller-diagram"/>
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = 60)]
|
||||||
|
internal struct NPadInputState : IInputStateTypeInfo
|
||||||
|
{
|
||||||
|
public FourCC format
|
||||||
|
{
|
||||||
|
get { return new FourCC('N', 'P', 'A', 'D'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[InputControl(name = "dpad")]
|
||||||
|
[InputControl(name = "buttonNorth", displayName = "X", shortDisplayName = "X", bit = (uint)Button.North)]
|
||||||
|
[InputControl(name = "buttonSouth", displayName = "B", shortDisplayName = "B", bit = (uint)Button.South, usages = new[] { "Back", "Cancel" })]
|
||||||
|
[InputControl(name = "buttonWest", displayName = "Y", shortDisplayName = "Y", bit = (uint)Button.West, usage = "SecondaryAction")]
|
||||||
|
[InputControl(name = "buttonEast", displayName = "A", shortDisplayName = "A", bit = (uint)Button.East, usages = new[] { "PrimaryAction", "Submit" })]
|
||||||
|
[InputControl(name = "leftStickPress", displayName = "Left Stick", bit = (uint)Button.StickL)]
|
||||||
|
[InputControl(name = "rightStickPress", displayName = "Right Stick", bit = (uint)Button.StickR)]
|
||||||
|
[InputControl(name = "leftShoulder", displayName = "L", shortDisplayName = "L", bit = (uint)Button.L)]
|
||||||
|
[InputControl(name = "rightShoulder", displayName = "R", shortDisplayName = "R", bit = (uint)Button.R)]
|
||||||
|
[InputControl(name = "leftTrigger", displayName = "ZL", shortDisplayName = "ZL", format = "BIT", bit = (uint)Button.ZL)]
|
||||||
|
[InputControl(name = "rightTrigger", displayName = "ZR", shortDisplayName = "ZR", format = "BIT", bit = (uint)Button.ZR)]
|
||||||
|
[InputControl(name = "start", displayName = "Plus", bit = (uint)Button.Plus, usage = "Menu")]
|
||||||
|
[InputControl(name = "select", displayName = "Minus", bit = (uint)Button.Minus)]
|
||||||
|
[InputControl(name = "leftSL", displayName = "SL (Left)", shortDisplayName = "LSL", layout = "Button", bit = (uint)Button.LSL)]
|
||||||
|
[InputControl(name = "leftSR", displayName = "SR (Left)", shortDisplayName = "LSR", layout = "Button", bit = (uint)Button.LSR)]
|
||||||
|
[InputControl(name = "rightSL", displayName = "SL (Right)", shortDisplayName = "RSL", layout = "Button", bit = (uint)Button.RSL)]
|
||||||
|
[InputControl(name = "rightSR", displayName = "SR (Right)", shortDisplayName = "RSR", layout = "Button", bit = (uint)Button.RSR)]
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public uint buttons;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public Vector2 leftStick;
|
||||||
|
|
||||||
|
[FieldOffset(12)]
|
||||||
|
public Vector2 rightStick;
|
||||||
|
|
||||||
|
[InputControl(name = "acceleration", noisy = true)]
|
||||||
|
[FieldOffset(20)]
|
||||||
|
public Vector3 acceleration;
|
||||||
|
|
||||||
|
[InputControl(name = "attitude", noisy = true)]
|
||||||
|
[FieldOffset(32)]
|
||||||
|
public Quaternion attitude;
|
||||||
|
|
||||||
|
[InputControl(name = "angularVelocity", noisy = true)]
|
||||||
|
[FieldOffset(48)]
|
||||||
|
public Vector3 angularVelocity;
|
||||||
|
|
||||||
|
public float leftTrigger => ((buttons & (1 << (int)Button.ZL)) != 0) ? 1f : 0f;
|
||||||
|
|
||||||
|
public float rightTrigger => ((buttons & (1 << (int)Button.ZR)) != 0) ? 1f : 0f;
|
||||||
|
|
||||||
|
public enum Button
|
||||||
|
{
|
||||||
|
// Dpad buttons. Important to be first in the bitfield as we'll
|
||||||
|
// point the DpadControl to it.
|
||||||
|
// IMPORTANT: Order has to match what is expected by DpadControl.
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
|
||||||
|
North,
|
||||||
|
South,
|
||||||
|
West,
|
||||||
|
East,
|
||||||
|
|
||||||
|
StickL,
|
||||||
|
StickR,
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
|
||||||
|
ZL,
|
||||||
|
ZR,
|
||||||
|
Plus,
|
||||||
|
Minus,
|
||||||
|
|
||||||
|
LSL,
|
||||||
|
LSR,
|
||||||
|
RSL,
|
||||||
|
RSR,
|
||||||
|
|
||||||
|
X = North,
|
||||||
|
B = South,
|
||||||
|
Y = West,
|
||||||
|
A = East,
|
||||||
|
}
|
||||||
|
|
||||||
|
public NPadInputState WithButton(Button button, bool value = true)
|
||||||
|
{
|
||||||
|
var bit = (uint)1 << (int)button;
|
||||||
|
if (value)
|
||||||
|
buttons |= bit;
|
||||||
|
else
|
||||||
|
buttons &= ~bit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch output report sent as command to the backend.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NPadStatusReport : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type => new FourCC('N', 'P', 'D', 'S');
|
||||||
|
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize + 24;
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
|
||||||
|
public NPad.NpadId npadId;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 1)]
|
||||||
|
public NPad.Orientation orientation;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 2)]
|
||||||
|
public NPad.Attributes attributes;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 3)]
|
||||||
|
public char padding0;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
|
||||||
|
public NPad.NpadStyles styleMask;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 8)]
|
||||||
|
public int colorLeftMain;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 12)]
|
||||||
|
public int colorLeftSub;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 16)]
|
||||||
|
public int colorRightMain;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 20)]
|
||||||
|
public int colorRightSub;
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NPadStatusReport Create()
|
||||||
|
{
|
||||||
|
return new NPadStatusReport
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NPadControllerSupportCommand : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type => new FourCC('N', 'P', 'D', 'U');
|
||||||
|
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize + 8;
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
|
||||||
|
public int command;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
|
||||||
|
public int option;
|
||||||
|
|
||||||
|
public enum Command : int
|
||||||
|
{
|
||||||
|
kShowUI,
|
||||||
|
kSetHorizontalLayout,
|
||||||
|
kStartSixAxisSensor,
|
||||||
|
kStopSixAxisSensor,
|
||||||
|
}
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NPadControllerSupportCommand Create(NPadControllerSupportCommand.Command command, int option = 0)
|
||||||
|
{
|
||||||
|
return new NPadControllerSupportCommand
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
command = (int)command,
|
||||||
|
option = option,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NpadDeviceIOCTLShowUI : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type => new FourCC("NSUI");
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize;
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NpadDeviceIOCTLShowUI Create()
|
||||||
|
{
|
||||||
|
return new NpadDeviceIOCTLShowUI
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NpadDeviceIOCTLSetOrientation : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type => new FourCC("NSOR");
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize + 1;
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
|
||||||
|
public NPad.Orientation orientation;
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NpadDeviceIOCTLSetOrientation Create(NPad.Orientation orientation)
|
||||||
|
{
|
||||||
|
return new NpadDeviceIOCTLSetOrientation
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
orientation = orientation,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NpadDeviceIOCTLStartSixAxisSensor : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type => new FourCC("SXST");
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize;
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NpadDeviceIOCTLStartSixAxisSensor Create()
|
||||||
|
{
|
||||||
|
return new NpadDeviceIOCTLStartSixAxisSensor
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NpadDeviceIOCTLStopSixAxisSensor : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type => new FourCC("SXSP");
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize;
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NpadDeviceIOCTLStopSixAxisSensor Create()
|
||||||
|
{
|
||||||
|
return new NpadDeviceIOCTLStopSixAxisSensor
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Switch output report sent as command to backend.
|
||||||
|
/// </summary>
|
||||||
|
// IMPORTANT: Struct must match the NpadDeviceIOCTLOutputReport in native
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||||
|
internal struct NPadDeviceIOCTLOutputCommand : IInputDeviceCommandInfo
|
||||||
|
{
|
||||||
|
public static FourCC Type { get { return new FourCC('N', 'P', 'G', 'O'); } }
|
||||||
|
|
||||||
|
internal const int kSize = InputDeviceCommand.BaseCommandSize + 20;
|
||||||
|
public const float DefaultFrequencyLow = 160.0f;
|
||||||
|
public const float DefaultFrequencyHigh = 320.0f;
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Need to match native struct data size")]
|
||||||
|
public enum NPadRumblePostion : byte
|
||||||
|
{
|
||||||
|
Left = 0x02,
|
||||||
|
Right = 0x04,
|
||||||
|
All = 0xFF,
|
||||||
|
None = 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldOffset(0)] public InputDeviceCommand baseCommand;
|
||||||
|
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
|
||||||
|
public byte positions;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
|
||||||
|
public float amplitudeLow;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 8)]
|
||||||
|
public float frequencyLow;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 12)]
|
||||||
|
public float amplitudeHigh;
|
||||||
|
[FieldOffset(InputDeviceCommand.BaseCommandSize + 16)]
|
||||||
|
public float frequencyHigh;
|
||||||
|
|
||||||
|
public FourCC typeStatic
|
||||||
|
{
|
||||||
|
get { return Type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NPadDeviceIOCTLOutputCommand Create(NPadRumblePostion rumblePos = NPadRumblePostion.All)
|
||||||
|
{
|
||||||
|
return new NPadDeviceIOCTLOutputCommand()
|
||||||
|
{
|
||||||
|
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||||
|
positions = (byte)rumblePos,
|
||||||
|
amplitudeLow = 0,
|
||||||
|
frequencyLow = DefaultFrequencyLow,
|
||||||
|
amplitudeHigh = 0,
|
||||||
|
frequencyHigh = DefaultFrequencyHigh
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace UnityEngine.InputSystem.Switch
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An NPad controller for Switch, which can be a Joy-Con.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="NPadInputState"/>
|
||||||
|
[InputControlLayout(stateType = typeof(NPadInputState), displayName = "Switch Controller (on Switch)")]
|
||||||
|
[Scripting.Preserve]
|
||||||
|
public class NPad : Gamepad, INPadRumble
|
||||||
|
{
|
||||||
|
public ButtonControl leftSL { get; private set; }
|
||||||
|
public ButtonControl leftSR { get; private set; }
|
||||||
|
public ButtonControl rightSL { get; private set; }
|
||||||
|
public ButtonControl rightSR { get; private set; }
|
||||||
|
|
||||||
|
public Vector3Control acceleration { get; private set; }
|
||||||
|
public QuaternionControl attitude { get; private set; }
|
||||||
|
public Vector3Control angularVelocity { get; private set; }
|
||||||
|
|
||||||
|
// Override inherited a/b/x/y mappings to match the JoyCon layout
|
||||||
|
public new ButtonControl bButton => buttonSouth;
|
||||||
|
public new ButtonControl aButton => buttonEast;
|
||||||
|
public new ButtonControl yButton => buttonWest;
|
||||||
|
public new ButtonControl xButton => buttonNorth;
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Need to match native struct data size")]
|
||||||
|
public enum Orientation : byte
|
||||||
|
{
|
||||||
|
Vertical,
|
||||||
|
Horizontal,
|
||||||
|
Default = Vertical,
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Need to match native struct data size")]
|
||||||
|
public enum NpadId : byte
|
||||||
|
{
|
||||||
|
No1 = 0x00,
|
||||||
|
No2 = 0x01,
|
||||||
|
No3 = 0x02,
|
||||||
|
No4 = 0x03,
|
||||||
|
No5 = 0x04,
|
||||||
|
No6 = 0x05,
|
||||||
|
No7 = 0x06,
|
||||||
|
No8 = 0x07,
|
||||||
|
Handheld = 0x20,
|
||||||
|
Debug = 0xF0,
|
||||||
|
Invalid = 0xFF,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum Attributes
|
||||||
|
{
|
||||||
|
IsConnected = 0x01,
|
||||||
|
IsWired = 0x02,
|
||||||
|
IsLeftConnected = 0x04,
|
||||||
|
IsLeftWired = 0x08,
|
||||||
|
IsRightConnected = 0x10,
|
||||||
|
IsRightWired = 0x20,
|
||||||
|
}
|
||||||
|
|
||||||
|
//orientation matters for stick axes!!!!
|
||||||
|
|
||||||
|
//there's a touchpad and 90% of games don't support it
|
||||||
|
|
||||||
|
//each person could play with a different style
|
||||||
|
[Flags]
|
||||||
|
public enum NpadStyles
|
||||||
|
{
|
||||||
|
FullKey = 1 << 0,//separate;or pro controller;only one accel
|
||||||
|
Handheld = 1 << 1,//docked to switch
|
||||||
|
JoyDual = 1 << 2,//separate; one accel per joycon
|
||||||
|
JoyLeft = 1 << 3,//just one; orientation matters
|
||||||
|
JoyRight = 1 << 4,//just one; orientation matters
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct JoyConColor
|
||||||
|
{
|
||||||
|
public Color32 Main;
|
||||||
|
public Color32 Sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Orientation orientation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return m_Orientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public NpadId npadId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return m_NpadId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public NpadStyles styleMask
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return m_StyleMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JoyConColor leftControllerColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return m_LeftControllerColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JoyConColor rightControllerColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return m_RightControllerColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isConnected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return (m_Attributes & Attributes.IsConnected) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isLeftConnected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return (m_Attributes & Attributes.IsLeftConnected) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isRightConnected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(),k_StringAttributesNotSupported);
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return (m_Attributes & Attributes.IsRightConnected) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isWired
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return (m_Attributes & Attributes.IsWired) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isLeftWired
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return (m_Attributes & Attributes.IsLeftWired) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isRightWired
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
|
||||||
|
RefreshConfigurationIfNeeded();
|
||||||
|
return (m_Attributes & Attributes.IsRightWired) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Orientation m_Orientation;
|
||||||
|
private NpadId m_NpadId = NpadId.Invalid;
|
||||||
|
private NpadStyles m_StyleMask;
|
||||||
|
private JoyConColor m_LeftControllerColor;
|
||||||
|
private JoyConColor m_RightControllerColor;
|
||||||
|
private Attributes m_Attributes;
|
||||||
|
|
||||||
|
private const string k_StringAttributesNotSupported = "Attributes not supported in this Unity version! Requires 2021.2.0a10, 2021.1.1f1, 2020.3.4f1, 2019.4.24f1 or higher";
|
||||||
|
|
||||||
|
private struct NPadRumbleValues
|
||||||
|
{
|
||||||
|
public float? amplitudeLow;
|
||||||
|
public float? frequencyLow;
|
||||||
|
public float? amplitudeHigh;
|
||||||
|
public float? frequencyHigh;
|
||||||
|
|
||||||
|
public bool HasValues => amplitudeLow.HasValue && frequencyLow.HasValue && amplitudeHigh.HasValue && frequencyHigh.HasValue;
|
||||||
|
|
||||||
|
public void SetRumbleValues(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
|
||||||
|
{
|
||||||
|
amplitudeLow = Mathf.Clamp01(lowAmplitude);
|
||||||
|
frequencyLow = lowFrequency;
|
||||||
|
amplitudeHigh = Mathf.Clamp01(highAmplitude);
|
||||||
|
frequencyHigh = highFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
amplitudeLow = null;
|
||||||
|
frequencyLow = null;
|
||||||
|
amplitudeHigh = null;
|
||||||
|
frequencyHigh = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyRumbleValues(ref NPadDeviceIOCTLOutputCommand cmd)
|
||||||
|
{
|
||||||
|
cmd.amplitudeLow = (float)amplitudeLow;
|
||||||
|
cmd.frequencyLow = (float)frequencyLow;
|
||||||
|
cmd.amplitudeHigh = (float)amplitudeHigh;
|
||||||
|
cmd.frequencyHigh = (float)frequencyHigh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NPadRumbleValues m_leftRumbleValues;
|
||||||
|
private NPadRumbleValues m_rightRumbleValues;
|
||||||
|
|
||||||
|
protected override void RefreshConfiguration()
|
||||||
|
{
|
||||||
|
base.RefreshConfiguration();
|
||||||
|
|
||||||
|
var command = NPadStatusReport.Create();
|
||||||
|
|
||||||
|
if (ExecuteCommand(ref command) > 0)
|
||||||
|
{
|
||||||
|
m_NpadId = command.npadId;
|
||||||
|
m_Orientation = command.orientation;
|
||||||
|
m_StyleMask = command.styleMask;
|
||||||
|
m_Attributes = command.attributes;
|
||||||
|
ReadNNColorIntoJoyConColor(ref m_LeftControllerColor, command.colorLeftMain, command.colorLeftSub);
|
||||||
|
ReadNNColorIntoJoyConColor(ref m_RightControllerColor, command.colorRightMain, command.colorRightSub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This function should be static
|
||||||
|
public long SetOrientationToSingleJoyCon(Orientation orientation)
|
||||||
|
{
|
||||||
|
var supportCommand = NpadDeviceIOCTLSetOrientation.Create(orientation);
|
||||||
|
|
||||||
|
return ExecuteCommand(ref supportCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long StartSixAxisSensor()
|
||||||
|
{
|
||||||
|
var supportCommand = NpadDeviceIOCTLStartSixAxisSensor.Create();
|
||||||
|
|
||||||
|
return ExecuteCommand(ref supportCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long StopSixAxisSensor()
|
||||||
|
{
|
||||||
|
var supportCommand = NpadDeviceIOCTLStopSixAxisSensor.Create();
|
||||||
|
|
||||||
|
return ExecuteCommand(ref supportCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void FinishSetup()
|
||||||
|
{
|
||||||
|
base.FinishSetup();
|
||||||
|
|
||||||
|
leftSL = GetChildControl<ButtonControl>("leftSL");
|
||||||
|
leftSR = GetChildControl<ButtonControl>("leftSR");
|
||||||
|
rightSL = GetChildControl<ButtonControl>("rightSL");
|
||||||
|
rightSR = GetChildControl<ButtonControl>("rightSR");
|
||||||
|
|
||||||
|
acceleration = GetChildControl<Vector3Control>("acceleration");
|
||||||
|
attitude = GetChildControl<QuaternionControl>("attitude");
|
||||||
|
angularVelocity = GetChildControl<Vector3Control>("angularVelocity");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ReadNNColorIntoJoyConColor(ref JoyConColor controllerColor, int mainColor, int subColor)
|
||||||
|
{
|
||||||
|
controllerColor.Main = ConvertNNColorToColor32(mainColor);
|
||||||
|
controllerColor.Sub = ConvertNNColorToColor32(subColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color32 ConvertNNColorToColor32(int color)
|
||||||
|
{
|
||||||
|
return new Color32((byte)(color & 0xFF), (byte)((color >> 8) & 0xFF), (byte)((color >> 16) & 0xFF), (byte)((color >> 24) & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PauseHaptics()
|
||||||
|
{
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create();
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ResetHaptics()
|
||||||
|
{
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create();
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
m_leftRumbleValues.Reset();
|
||||||
|
m_rightRumbleValues.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ResumeHaptics()
|
||||||
|
{
|
||||||
|
if (m_leftRumbleValues.Equals(m_rightRumbleValues) && m_leftRumbleValues.HasValues)
|
||||||
|
{
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create();
|
||||||
|
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_leftRumbleValues.HasValues)
|
||||||
|
{
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Left);
|
||||||
|
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rightRumbleValues.HasValues)
|
||||||
|
{
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Right);
|
||||||
|
m_rightRumbleValues.ApplyRumbleValues(ref cmd);
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set rummble intensity for all low and high frequency rumble motors
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lowFrequency">Low frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="highFrequency">High frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
public override void SetMotorSpeeds(float lowFrequency, float highFrequency)
|
||||||
|
{
|
||||||
|
SetMotorSpeeds(lowFrequency, NPadDeviceIOCTLOutputCommand.DefaultFrequencyLow, highFrequency, NPadDeviceIOCTLOutputCommand.DefaultFrequencyHigh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the intensity and vibration frequency for all low and high frequency rumble motors
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lowAmplitude">Low frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="lowFrequency">Low frequency motor's vibration frequency in Hz</param>
|
||||||
|
/// <param name="highAmplitude">High frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="highFrequency">High frequency motor's vibration frequency in Hz</param>
|
||||||
|
public void SetMotorSpeeds(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
|
||||||
|
{
|
||||||
|
m_leftRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
|
||||||
|
m_rightRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
|
||||||
|
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create();
|
||||||
|
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the intensity and vibration frequency for the left low and high frequency rumble motors
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lowAmplitude">Low frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="lowFrequency">Low frequency motor's vibration frequency in Hz</param>
|
||||||
|
/// <param name="highAmplitude">High frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="highFrequency">High frequency motor's vibration frequency in Hz</param>
|
||||||
|
public void SetMotorSpeedLeft(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
|
||||||
|
{
|
||||||
|
m_leftRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
|
||||||
|
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Left);
|
||||||
|
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the intensity and vibration frequency for the right low and high frequency rumble motors
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lowAmplitude">Low frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="lowFrequency">Low frequency motor's vibration frequency in Hz</param>
|
||||||
|
/// <param name="highAmplitude">High frequency motor's vibration intensity, 0..1 range</param>
|
||||||
|
/// <param name="highFrequency">High frequency motor's vibration frequency in Hz</param>
|
||||||
|
public void SetMotorSpeedRight(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
|
||||||
|
{
|
||||||
|
m_rightRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
|
||||||
|
|
||||||
|
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Right);
|
||||||
|
m_rightRumbleValues.ApplyRumbleValues(ref cmd);
|
||||||
|
ExecuteCommand(ref cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // UNITY_EDITOR || UNITY_SWITCH
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 10b79550bec1ec546ac93d5768427df9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,189 @@
|
|||||||
|
|
||||||
|
#if UNITY_EDITOR || UNITY_SWITCH
|
||||||
|
using UnityEngine.InputSystem.Layouts;
|
||||||
|
using UnityEngine.Scripting;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
using UnityEditor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[assembly: AlwaysLinkAssembly]
|
||||||
|
|
||||||
|
namespace UnityEngine.InputSystem.Switch
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds support for Switch NPad controllers.
|
||||||
|
/// </summary>
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[InitializeOnLoad]
|
||||||
|
#endif
|
||||||
|
#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
static class SwitchConsoleSupport
|
||||||
|
{
|
||||||
|
static SwitchConsoleSupport()
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR || UNITY_SWITCH
|
||||||
|
InputSystem.RegisterLayout<NPad>(
|
||||||
|
matches: new InputDeviceMatcher()
|
||||||
|
.WithInterface("Switch")
|
||||||
|
.WithManufacturer("Nintendo")
|
||||||
|
.WithProduct("Wireless Controller"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[RuntimeInitializeOnLoadMethod]
|
||||||
|
private static void InitializeInPlayer()
|
||||||
|
{
|
||||||
|
s_UnityVersion.ParseUnityVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UnityVersion
|
||||||
|
{
|
||||||
|
public enum EType
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Alpha,
|
||||||
|
Beta,
|
||||||
|
Final,
|
||||||
|
Patch,
|
||||||
|
Experimental
|
||||||
|
}
|
||||||
|
|
||||||
|
// [Version].[Major].[Minor][Type][Revision][Suffix]
|
||||||
|
// Example 2020.3.1f1
|
||||||
|
// Type being one of:
|
||||||
|
// a: alpha
|
||||||
|
// b: beta
|
||||||
|
// f: public ("final") release
|
||||||
|
// p: patch release(after final)
|
||||||
|
// x: experimental
|
||||||
|
private int Version { get; set; } // Main version (2018, 2019, 2020, 2021 etc)
|
||||||
|
private int Major { get; set; } // Tech-stream or LTS, e.g .1, .2, .3, .4
|
||||||
|
private int Minor { get; set; }
|
||||||
|
private int Revision { get; set; }
|
||||||
|
private EType Type{ get; set; }
|
||||||
|
|
||||||
|
// Must match main version
|
||||||
|
public bool IsVersionOrHigher(int versionIn, int majorIn = 0, int minorIn = 0, EType typeIn = EType.Unknown, int revisionIn = 0)
|
||||||
|
{
|
||||||
|
return Version == versionIn && Major >= majorIn && Minor >= minorIn && ((Type > typeIn || Type == typeIn && Revision >= revisionIn) || Type == EType.Unknown);
|
||||||
|
}
|
||||||
|
public bool IsMainVersionOrLater(int versionIn)
|
||||||
|
{
|
||||||
|
return Version >= versionIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Package min Unity version compatibility is 2019.4 LTS so we don't expect to parse older version strings
|
||||||
|
public void ParseUnityVersion()
|
||||||
|
{
|
||||||
|
string unityVer = Application.unityVersion;
|
||||||
|
|
||||||
|
// Parse up to first '.' to read Unity version (year)
|
||||||
|
var startIdx = 0;
|
||||||
|
var endIdx = unityVer.IndexOf('.');
|
||||||
|
var verStr = unityVer.Substring(startIdx, endIdx - startIdx);
|
||||||
|
|
||||||
|
if(int.TryParse(verStr, out var version))
|
||||||
|
{
|
||||||
|
Version = version;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to parse Unity version: " + unityVer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse up to second '.' for major revision
|
||||||
|
startIdx = endIdx + 1;
|
||||||
|
endIdx = unityVer.IndexOf('.', startIdx);
|
||||||
|
var majStr = unityVer.Substring(startIdx, endIdx - startIdx);
|
||||||
|
|
||||||
|
if (int.TryParse(majStr, out var major))
|
||||||
|
{
|
||||||
|
Major = major;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break down final part of version string, minor revision, type & suffix ([Minor][Type][Revision][Suffix])
|
||||||
|
startIdx = endIdx + 1;
|
||||||
|
|
||||||
|
// Check for -dots suffix and discard.
|
||||||
|
var suffixIdx = unityVer.IndexOf('-', startIdx);
|
||||||
|
string minStr = (suffixIdx != -1) ? unityVer.Substring(startIdx, suffixIdx - startIdx) : unityVer.Substring(startIdx);
|
||||||
|
|
||||||
|
// Check for China suffix ('c') and discard.
|
||||||
|
suffixIdx = minStr.IndexOf('c');
|
||||||
|
if (suffixIdx != -1)
|
||||||
|
{
|
||||||
|
minStr = minStr.Substring(0, suffixIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
Minor = 0;
|
||||||
|
Revision = 0;
|
||||||
|
Type = EType.Unknown;
|
||||||
|
|
||||||
|
char[] versionTypes = { 'a', 'b', 'f', 'p', 'x' }; // Known version identifiers
|
||||||
|
var typeIdx = minStr.IndexOfAny(versionTypes);
|
||||||
|
|
||||||
|
if (typeIdx != -1)
|
||||||
|
{
|
||||||
|
var type = minStr[typeIdx];
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 'a': Type = EType.Alpha; break;
|
||||||
|
case 'b': Type = EType.Beta; break;
|
||||||
|
case 'f': Type = EType.Final; break;
|
||||||
|
case 'p': Type = EType.Patch; break;
|
||||||
|
case 'x': Type = EType.Experimental; break;
|
||||||
|
default:
|
||||||
|
Debug.LogWarningFormat("Unrecognized type identifier ({0}) in Unity version string: {1}", type, unityVer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int.TryParse(minStr.Substring(0, typeIdx), out var minor))
|
||||||
|
{
|
||||||
|
Minor = minor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to parse minor version from Unity version string: " + unityVer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int.TryParse(minStr.Substring(typeIdx + 1), out var revision))
|
||||||
|
{
|
||||||
|
Revision = revision;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to parse revision from Unity version string: " + unityVer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Debug.LogFormat("Version: {0} Major: {1} Minor: {2} Type: {3} Revision: {4}\n", Version, Major, Minor, Type, Revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static UnityVersion s_UnityVersion;
|
||||||
|
|
||||||
|
// Attributes queries require a fix in the Switch player available in the following versions onwards
|
||||||
|
// (The attributes field is reusing part of the struct that was padding in older versions)
|
||||||
|
// 2021.2.0a10, 2021.1.1f1, 2020.3.4f1, 2019.4.24f1, Not supported in 2018 or older
|
||||||
|
public static bool NpadAttributesSupported()
|
||||||
|
{
|
||||||
|
if (s_UnityVersion.IsMainVersionOrLater(2022) // Will be supported in all versions of 2022 onward
|
||||||
|
|| s_UnityVersion.IsVersionOrHigher(2021, 2, 0, UnityVersion.EType.Alpha, 10)
|
||||||
|
|| s_UnityVersion.IsVersionOrHigher(2020, 3, 4, UnityVersion.EType.Final, 1)
|
||||||
|
|| s_UnityVersion.IsVersionOrHigher(2019, 4, 24, UnityVersion.EType.Final, 1))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fc10b23f19793734895f4ef18a67daf7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "Unity.InputSystem.Switch",
|
||||||
|
"references": [
|
||||||
|
"Unity.InputSystem"
|
||||||
|
],
|
||||||
|
"includePlatforms": [
|
||||||
|
"Editor",
|
||||||
|
"Switch"
|
||||||
|
],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": true,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": []
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6374799de9bd44442818ee6dd5dbbfc5
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
**Unity Companion Package License v1.0 ("_License_")**
|
||||||
|
|
||||||
|
Copyright © 2019 Unity Technologies ApS ("**_Unity_**")
|
||||||
|
|
||||||
|
Unity hereby grants to you a worldwide, non-exclusive, no-charge, and royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute the software that is made available with this License ("**_Software_**"), subject to the following terms and conditions:
|
||||||
|
|
||||||
|
1. *Unity Companion Use Only*. Exercise of the license granted herein is limited to exercise for the creation, use, and/or distribution of applications, software, or other content pursuant to a valid Unity development engine software license ("**_Engine License_**"). That means while use of the Software is not limited to use in the software licensed under the Engine License, the Software may not be used for any purpose other than the creation, use, and/or distribution of Engine License-dependent applications, software, or other content. No other exercise of the license granted herein is permitted.
|
||||||
|
|
||||||
|
1. *No Modification of Engine License*. Neither this License nor any exercise of the license granted herein modifies the Engine License in any way.
|
||||||
|
|
||||||
|
1. *Ownership & Grant Back to You*.
|
||||||
|
|
||||||
|
3.1. You own your content. In this License, "derivative works" means derivatives of the Software itself--works derived only from the Software by you under this License (for example, modifying the code of the Software itself to improve its efficacy); “derivative works” of the Software do not include, for example, games, apps, or content that you create using the Software. You keep all right, title, and interest to your own content.
|
||||||
|
|
||||||
|
3.2. Unity owns its content. While you keep all right, title, and interest to your own content per the above, as between Unity and you, Unity will own all right, title, and interest to all intellectual property rights (including patent, trademark, and copyright) in the Software and derivative works of the Software, and you hereby assign and agree to assign all such rights in those derivative works to Unity.
|
||||||
|
|
||||||
|
3.3. You have a license to those derivative works. Subject to this License, Unity grants to you the same worldwide, non-exclusive, no-charge, and royalty-free copyright license to derivative works of the Software you create as is granted to you for the Software under this License.
|
||||||
|
|
||||||
|
1. *Trademarks*. You are not granted any right or license under this License to use any trademarks, service marks, trade names, products names, or branding of Unity or its affiliates ("**_Trademarks_**"). Descriptive uses of Trademarks are permitted; see, for example, Unity’s Branding Usage Guidelines at [https://unity3d.com/public-relations/brand](https://unity3d.com/public-relations/brand).
|
||||||
|
|
||||||
|
1. *Notices & Third-Party Rights*. This License, including the copyright notice above, must be provided in all substantial portions of the Software and derivative works thereof (or, if that is impracticable, in any other location where such notices are customarily placed). Further, if the Software is accompanied by a Unity "third-party notices" or similar file, you acknowledge and agree that software identified in that file is governed by those separate license terms.
|
||||||
|
|
||||||
|
1. *DISCLAIMER, LIMITATION OF LIABILITY*. THE SOFTWARE AND ANY DERIVATIVE WORKS THEREOF IS PROVIDED ON AN "AS IS" BASIS, AND IS PROVIDED WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR NONINFRINGEMENT. IN NO EVENT SHALL ANY COPYRIGHT HOLDER OR AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES (WHETHER DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL, INCLUDING PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, AND BUSINESS INTERRUPTION), OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR OUT OF, OR IN CONNECTION WITH, THE SOFTWARE OR ANY DERIVATIVE WORKS THEREOF OR THE USE OF OR OTHER DEALINGS IN SAME, EVEN WHERE ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
1. *USE IS ACCEPTANCE and License Versions*. Your receipt and use of the Software constitutes your acceptance of this License and its terms and conditions. Software released by Unity under this License may be modified or updated and the License with it; upon any such modification or update, you will comply with the terms of the updated License for any use of any of the Software under the updated License.
|
||||||
|
|
||||||
|
1. *Use in Compliance with Law and Termination*. Your exercise of the license granted herein will at all times be in compliance with applicable law and will not infringe any proprietary rights (including intellectual property rights); this License will terminate immediately on any breach by you of this License.
|
||||||
|
|
||||||
|
1. *Severability*. If any provision of this License is held to be unenforceable or invalid, that provision will be enforced to the maximum extent possible and the other provisions will remain in full force and effect.
|
||||||
|
|
||||||
|
1. *Governing Law and Venue*. This License is governed by and construed in accordance with the laws of Denmark, except for its conflict of laws rules; the United Nations Convention on Contracts for the International Sale of Goods will not apply. If you reside (or your principal place of business is) within the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the state and federal courts located in San Francisco County, California concerning any dispute arising out of this License ("**_Dispute_**"). If you reside (or your principal place of business is) outside the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the courts located in Copenhagen, Denmark concerning any Dispute.
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0fc53242e6c9fbd4c88f90fb1e7eff9e
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1 @@
|
|||||||
|
Switch Devices and extension for new input system.
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d07bdabda6639b447b233e47dca4e09f
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"SuiteConfig":
|
||||||
|
{
|
||||||
|
"Targets":
|
||||||
|
[
|
||||||
|
"+Switch"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fe4afccdf24f4148b8719f9a4ba5872a
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "com.unity.inputsystem.switch",
|
||||||
|
"displayName": "Input System Switch",
|
||||||
|
"version": "0.1.6-pre",
|
||||||
|
"unity": "2019.4",
|
||||||
|
"description": "Switch Devices for new Input System",
|
||||||
|
"keywords": [
|
||||||
|
"input",
|
||||||
|
"keyboard",
|
||||||
|
"mouse",
|
||||||
|
"gamepad",
|
||||||
|
"touch"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"com.unity.inputsystem": "1.1.0-pre.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f5132f131fbc3d14da629fca5b83a5e7
|
||||||
|
PackageManifestImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
@ -0,0 +1,130 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 562e8ae4167d26b42b4dd08d3f809531
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -9,7 +9,8 @@
|
|||||||
"Essgee.Unity",
|
"Essgee.Unity",
|
||||||
"StoicGooseUnity",
|
"StoicGooseUnity",
|
||||||
"Unity.InputSystem",
|
"Unity.InputSystem",
|
||||||
"AxiNSApi"
|
"AxiNSApi",
|
||||||
|
"Unity.InputSystem.Switch"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
using AxibugEmuOnline.Client.ClientCore;
|
||||||
using AxibugEmuOnline.Client.Common;
|
|
||||||
using AxibugEmuOnline.Client.Event;
|
using AxibugEmuOnline.Client.Event;
|
||||||
using AxibugEmuOnline.Client.Settings;
|
using AxibugEmuOnline.Client.Settings;
|
||||||
using NUnit.Framework.Internal;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
|
||||||
using VirtualNes.Core;
|
using VirtualNes.Core;
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
namespace AxibugEmuOnline.Client
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
using Assets.Script.AppMain.Filter;
|
using Assets.Script.AppMain.Filter;
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using static Coffee.UIExtensions.UIEffect;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client.Filters
|
namespace AxibugEmuOnline.Client.Filters
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,36 @@
|
|||||||
|
using AxibugProtobuf;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace AxibugEmuOnline.Client.InputDevices
|
||||||
|
{
|
||||||
|
public class SwitchJoyCon_D : InputDevice_D
|
||||||
|
{
|
||||||
|
public Button_C LeftSL;
|
||||||
|
public Button_C LeftSR;
|
||||||
|
public Button_C RightSL;
|
||||||
|
public Button_C RightSR;
|
||||||
|
|
||||||
|
public Button_C B;
|
||||||
|
public Button_C A;
|
||||||
|
public Button_C Y;
|
||||||
|
public Button_C X;
|
||||||
|
|
||||||
|
public Button_C Up;
|
||||||
|
public Button_C Down;
|
||||||
|
public Button_C Left;
|
||||||
|
public Button_C Right;
|
||||||
|
|
||||||
|
public Button_C Minus;
|
||||||
|
public Button_C Plus;
|
||||||
|
|
||||||
|
public Stick_C LeftStick;
|
||||||
|
public Stick_C RightStick;
|
||||||
|
public Button_C LeftStickPress;
|
||||||
|
public Button_C RightStickPress;
|
||||||
|
|
||||||
|
public SwitchJoyCon_D(InputResolver resolver) : base(resolver) { }
|
||||||
|
|
||||||
|
public override GamePadType PadType => GamePadType.SwitchJoyCon;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28380f06191bd35458b20113fbd2960b
|
||||||
@ -1,9 +1,18 @@
|
|||||||
#if ENABLE_INPUT_SYSTEM
|
#if ENABLE_INPUT_SYSTEM
|
||||||
|
|
||||||
|
#if UNITY_EDITOR || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_WSA || PACKAGE_DOCS_GENERATION
|
||||||
|
#define DUALSHOCK_SUPPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNITY_EDITOR || UNITY_SWITCH || PACKAGE_DOCS_GENERATION
|
||||||
|
#define JOYCON_SUPPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.InputSystem;
|
using UnityEngine.InputSystem;
|
||||||
using UnityEngine.InputSystem.Android;
|
|
||||||
using UnityEngine.InputSystem.DualShock;
|
using UnityEngine.InputSystem.DualShock;
|
||||||
|
using UnityEngine.InputSystem.Switch;
|
||||||
using UnityEngine.InputSystem.XInput;
|
using UnityEngine.InputSystem.XInput;
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
||||||
@ -24,18 +33,26 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
{
|
{
|
||||||
InputDevice_D newDevice = null;
|
InputDevice_D newDevice = null;
|
||||||
if (ipdev is Keyboard) newDevice = new Keyboard_D(this);
|
if (ipdev is Keyboard) newDevice = new Keyboard_D(this);
|
||||||
|
|
||||||
|
#if DUALSHOCK_SUPPORT
|
||||||
else if (ipdev is DualShockGamepad)
|
else if (ipdev is DualShockGamepad)
|
||||||
{
|
{
|
||||||
if (ipdev is DualShock3GamepadHID) newDevice = new DualShockController_D(this, ps3: true);
|
if (ipdev is DualShock3GamepadHID) newDevice = new DualShockController_D(this, ps3: true);
|
||||||
else if (ipdev is DualShock4GamepadHID) newDevice = new DualShockController_D(this, ps4: true);
|
else if (ipdev is DualShock4GamepadHID) newDevice = new DualShockController_D(this, ps4: true);
|
||||||
else if (ipdev is DualSenseGamepadHID) newDevice = new DualShockController_D(this, ps5: true);
|
else if (ipdev is DualSenseGamepadHID) newDevice = new DualShockController_D(this, ps5: true);
|
||||||
else newDevice = new DualShockController_D(this);
|
else newDevice = new DualShockController_D(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (ipdev is XInputController)
|
else if (ipdev is XInputController)
|
||||||
{
|
{
|
||||||
newDevice = new XboxController_D(this);
|
newDevice = new XboxController_D(this);
|
||||||
}
|
}
|
||||||
|
#if JOYCON_SUPPORT
|
||||||
|
else if (ipdev is NPad)
|
||||||
|
{
|
||||||
|
newDevice = new SwitchJoyCon_D(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (ipdev is Gamepad) newDevice = new GamePad_D(this); //注意Gamepad的优先级,因为任何手柄,Inputsystem中的基类都是GamePad
|
else if (ipdev is Gamepad) newDevice = new GamePad_D(this); //注意Gamepad的优先级,因为任何手柄,Inputsystem中的基类都是GamePad
|
||||||
|
|
||||||
if (newDevice != null)
|
if (newDevice != null)
|
||||||
@ -98,13 +115,13 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
protected override Vector2 OnGetVector2<CONTROLLER>(CONTROLLER control)
|
protected override Vector2 OnGetVector2<CONTROLLER>(CONTROLLER control)
|
||||||
{
|
{
|
||||||
var ipControl = GetInputSystemControl(control);
|
var ipControl = GetInputSystemControl(control);
|
||||||
return (ipControl as InputControl<Vector2>).value;
|
return (ipControl as InputControl<Vector2>).ReadValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override float OnGetFloat<CONTROLLER>(CONTROLLER control)
|
protected override float OnGetFloat<CONTROLLER>(CONTROLLER control)
|
||||||
{
|
{
|
||||||
var ipControl = GetInputSystemControl(control);
|
var ipControl = GetInputSystemControl(control);
|
||||||
return (ipControl as InputControl<float>).value;
|
return (ipControl as InputControl<float>).ReadValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
InputControl GetInputSystemControl(InputControl_C key)
|
InputControl GetInputSystemControl(InputControl_C key)
|
||||||
@ -233,6 +250,7 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
mapper[keyboard_d.Semicolon] = ipKeyboard.semicolonKey;
|
mapper[keyboard_d.Semicolon] = ipKeyboard.semicolonKey;
|
||||||
mapper[keyboard_d.Quote] = ipKeyboard.quoteKey;
|
mapper[keyboard_d.Quote] = ipKeyboard.quoteKey;
|
||||||
}
|
}
|
||||||
|
#if DUALSHOCK_SUPPORT
|
||||||
else if (device_d is DualShockController_D ds_d)
|
else if (device_d is DualShockController_D ds_d)
|
||||||
{
|
{
|
||||||
var ipDsGamePad = ipdevice as DualShockGamepad;
|
var ipDsGamePad = ipdevice as DualShockGamepad;
|
||||||
@ -256,6 +274,7 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
mapper[ds_d.LeftStick] = ipDsGamePad.leftStick;
|
mapper[ds_d.LeftStick] = ipDsGamePad.leftStick;
|
||||||
mapper[ds_d.RightStick] = ipDsGamePad.rightStick;
|
mapper[ds_d.RightStick] = ipDsGamePad.rightStick;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (device_d is XboxController_D xbox_d)
|
else if (device_d is XboxController_D xbox_d)
|
||||||
{
|
{
|
||||||
var ipXInputGamePad = ipdevice as XInputController;
|
var ipXInputGamePad = ipdevice as XInputController;
|
||||||
@ -277,8 +296,31 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
mapper[xbox_d.RightStickPress] = ipXInputGamePad.rightStickButton;
|
mapper[xbox_d.RightStickPress] = ipXInputGamePad.rightStickButton;
|
||||||
mapper[xbox_d.LeftStick] = ipXInputGamePad.leftStick;
|
mapper[xbox_d.LeftStick] = ipXInputGamePad.leftStick;
|
||||||
mapper[xbox_d.RightStick] = ipXInputGamePad.rightStick;
|
mapper[xbox_d.RightStick] = ipXInputGamePad.rightStick;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#if JOYCON_SUPPORT
|
||||||
|
else if (device_d is SwitchJoyCon_D joycon_d)
|
||||||
|
{
|
||||||
|
var ipdevice_joycon = ipdevice as NPad;
|
||||||
|
mapper[joycon_d.LeftSL] = ipdevice_joycon.leftSL;
|
||||||
|
mapper[joycon_d.LeftSR] = ipdevice_joycon.leftSR;
|
||||||
|
mapper[joycon_d.RightSL] = ipdevice_joycon.rightSL;
|
||||||
|
mapper[joycon_d.RightSR] = ipdevice_joycon.rightSR;
|
||||||
|
mapper[joycon_d.B] = ipdevice_joycon.bButton;
|
||||||
|
mapper[joycon_d.A] = ipdevice_joycon.aButton;
|
||||||
|
mapper[joycon_d.Y] = ipdevice_joycon.yButton;
|
||||||
|
mapper[joycon_d.X] = ipdevice_joycon.xButton;
|
||||||
|
mapper[joycon_d.Up] = ipdevice_joycon.dpad.up;
|
||||||
|
mapper[joycon_d.Down] = ipdevice_joycon.dpad.down;
|
||||||
|
mapper[joycon_d.Left] = ipdevice_joycon.dpad.left;
|
||||||
|
mapper[joycon_d.Right] = ipdevice_joycon.dpad.right;
|
||||||
|
mapper[joycon_d.Minus] = ipdevice_joycon.selectButton;
|
||||||
|
mapper[joycon_d.Plus] = ipdevice_joycon.startButton;
|
||||||
|
mapper[joycon_d.LeftStick] = ipdevice_joycon.leftStick;
|
||||||
|
mapper[joycon_d.RightStick] = ipdevice_joycon.rightStick;
|
||||||
|
mapper[joycon_d.RightStickPress] = ipdevice_joycon.rightStickButton;
|
||||||
|
mapper[joycon_d.LeftStickPress] = ipdevice_joycon.leftStickButton;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (device_d is GamePad_D gamepad_d)
|
else if (device_d is GamePad_D gamepad_d)
|
||||||
{
|
{
|
||||||
var ipGamepad = ipdevice as Gamepad;
|
var ipGamepad = ipdevice as Gamepad;
|
||||||
@ -300,6 +342,7 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
mapper[gamepad_d.RightStickPress] = ipGamepad.rightStickButton;
|
mapper[gamepad_d.RightStickPress] = ipGamepad.rightStickButton;
|
||||||
mapper[gamepad_d.LeftStick] = ipGamepad.leftStick;
|
mapper[gamepad_d.LeftStick] = ipGamepad.leftStick;
|
||||||
mapper[gamepad_d.RightStick] = ipGamepad.rightStick;
|
mapper[gamepad_d.RightStick] = ipGamepad.rightStick;
|
||||||
|
|
||||||
}
|
}
|
||||||
else throw new System.NotImplementedException($"初始化设备失败,未实现的物理按键映射 for {device_d.GetType()}");
|
else throw new System.NotImplementedException($"初始化设备失败,未实现的物理按键映射 for {device_d.GetType()}");
|
||||||
}
|
}
|
||||||
@ -308,6 +351,6 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
|
|||||||
m_deviceMapper.Remove(keyboard_d);
|
m_deviceMapper.Remove(keyboard_d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -163,7 +163,7 @@ PlayerSettings:
|
|||||||
androidMaxAspectRatio: 2.1
|
androidMaxAspectRatio: 2.1
|
||||||
androidMinAspectRatio: 1
|
androidMinAspectRatio: 1
|
||||||
applicationIdentifier:
|
applicationIdentifier:
|
||||||
Android: com.DefaultCompany.AxibugEmuOnline.Client
|
Android: com.AlienTechnology.AxibugEmuOnline.Client
|
||||||
Standalone: com.AlienTechnology.AxibugEmuOnline.Client
|
Standalone: com.AlienTechnology.AxibugEmuOnline.Client
|
||||||
buildNumber:
|
buildNumber:
|
||||||
Standalone: 0
|
Standalone: 0
|
||||||
@ -404,11 +404,13 @@ PlayerSettings:
|
|||||||
iPhone: 1
|
iPhone: 1
|
||||||
tvOS: 1
|
tvOS: 1
|
||||||
m_BuildTargetGroupLightmapEncodingQuality: []
|
m_BuildTargetGroupLightmapEncodingQuality: []
|
||||||
m_BuildTargetGroupHDRCubemapEncodingQuality: []
|
|
||||||
m_BuildTargetGroupLightmapSettings: []
|
m_BuildTargetGroupLightmapSettings: []
|
||||||
m_BuildTargetGroupLoadStoreDebugModeSettings: []
|
m_BuildTargetGroupLoadStoreDebugModeSettings: []
|
||||||
m_BuildTargetNormalMapEncoding: []
|
m_BuildTargetNormalMapEncoding: []
|
||||||
m_BuildTargetDefaultTextureCompressionFormat: []
|
m_BuildTargetDefaultTextureCompressionFormat:
|
||||||
|
- serializedVersion: 3
|
||||||
|
m_BuildTarget: Android
|
||||||
|
m_Formats: 01000000
|
||||||
playModeTestRunnerEnabled: 0
|
playModeTestRunnerEnabled: 0
|
||||||
runPlayModeTestAsEditModeTest: 0
|
runPlayModeTestAsEditModeTest: 0
|
||||||
actionOnDotNetUnhandledException: 1
|
actionOnDotNetUnhandledException: 1
|
||||||
@ -668,12 +670,12 @@ PlayerSettings:
|
|||||||
webGLMemoryLinearGrowthStep: 16
|
webGLMemoryLinearGrowthStep: 16
|
||||||
webGLMemoryGeometricGrowthStep: 0.2
|
webGLMemoryGeometricGrowthStep: 0.2
|
||||||
webGLMemoryGeometricGrowthCap: 96
|
webGLMemoryGeometricGrowthCap: 96
|
||||||
|
webGLEnableWebGPU: 0
|
||||||
webGLPowerPreference: 2
|
webGLPowerPreference: 2
|
||||||
webGLWebAssemblyTable: 0
|
webGLWebAssemblyTable: 0
|
||||||
webGLWebAssemblyBigInt: 0
|
webGLWebAssemblyBigInt: 0
|
||||||
webGLCloseOnQuit: 0
|
webGLCloseOnQuit: 0
|
||||||
webWasm2023: 0
|
webWasm2023: 0
|
||||||
webEnableSubmoduleStrippingCompatibility: 0
|
|
||||||
scriptingDefineSymbols:
|
scriptingDefineSymbols:
|
||||||
Android: DOTWEEN;ODIN_INSPECTOR;ODIN_INSPECTOR_3;ODIN_INSPECTOR_3_1;ODIN_INSPECTOR_EDITOR_ONLY;UNITY_POST_PROCESSING_STACK_V2
|
Android: DOTWEEN;ODIN_INSPECTOR;ODIN_INSPECTOR_3;ODIN_INSPECTOR_3_1;ODIN_INSPECTOR_EDITOR_ONLY;UNITY_POST_PROCESSING_STACK_V2
|
||||||
EmbeddedLinux: UNITY_POST_PROCESSING_STACK_V2
|
EmbeddedLinux: UNITY_POST_PROCESSING_STACK_V2
|
||||||
@ -820,4 +822,3 @@ PlayerSettings:
|
|||||||
insecureHttpOption: 2
|
insecureHttpOption: 2
|
||||||
androidVulkanDenyFilterList: []
|
androidVulkanDenyFilterList: []
|
||||||
androidVulkanAllowFilterList: []
|
androidVulkanAllowFilterList: []
|
||||||
androidVulkanDeviceFilterListAsset: {fileID: 0}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user