Skip to content

Commit

Permalink
DynamicBoneの制限確認に、VRChat SDKのAvatarPerformance.csを修正し、同クラスを利用するようにした
Browse files Browse the repository at this point in the history
  • Loading branch information
esperecyan committed Apr 13, 2019
1 parent 4a1498f commit ef8bac7
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 39 deletions.
34 changes: 34 additions & 0 deletions Editor/ComponentsReplacer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEditor;
using VRM;
using UniGLTF;
using VRCSDK2;

namespace Esperecyan.Unity.VRMConverterForVRChat
Expand Down Expand Up @@ -36,6 +38,7 @@ public enum SwayingObjectsConverterSetting
static ComponentsReplacer()
{
EnableClassDependentDependingOptionalAsset();
FixFindDynamicBoneTypesMethodOnAvatarPerformanceClass();
}

/// <summary>
Expand Down Expand Up @@ -100,6 +103,37 @@ private static void EnableClassDependentDependingOptionalAsset()
}
}

/// <summary>
/// <see cref="AvatarPerformance"/>クラスを書き替えて、DynamicBoneに関するパフォーマンスが表示されないVRChat SDKのバグを修正します。
/// </summary>
/// <seealso cref="SwayingObjectsConverter.GetMessagesAboutDynamicBoneLimits"/>
/// <remarks>
/// 参照:
/// SDK avatar performance reports always report dynamic bone counts as 0 | Bug Reports | VRChat
/// <https://vrchat.canny.io/bug-reports/p/sdk-avatar-performance-reports-always-report-dynamic-bone-counts-as-0>
/// </remarks>
private static void FixFindDynamicBoneTypesMethodOnAvatarPerformanceClass()
{
string fullPath = UnityPath.FromUnityPath(VRChatUtility.AvatarPerformanceClassPath).FullPath;

string content = File.ReadAllText(path: fullPath, encoding: Encoding.UTF8);
if (content.Contains("DynamicBoneColliderBase"))
{
return;
}

string fixedContent = content.Replace(
oldValue: "System.Type dyBoneColliderType = Validation.GetTypeFromName(\"DynamicBoneCollider\");",
newValue: "System.Type dyBoneColliderType = Validation.GetTypeFromName(\"DynamicBoneColliderBase\");"
);
if (fixedContent == content)
{
return;
}

File.WriteAllText(path: fullPath, contents: fixedContent, encoding: Encoding.UTF8);
}

/// <summary>
/// キャラクターに関する情報を設定します。
/// </summary>
Expand Down
63 changes: 24 additions & 39 deletions Editor/SwayingObjectsConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ ComponentsReplacer.SwayingParametersConverter swayingParametersConverter
{
var dynamicBone = springBone.gameObject.AddComponent<DynamicBone>();
dynamicBone.m_Root = transform;
dynamicBone.m_Exclusions = new List<Transform>();

DynamicBoneParameters dynamicBoneParameters = null;
if (swayingParametersConverter != null)
Expand Down Expand Up @@ -168,55 +169,39 @@ ComponentsReplacer.SwayingParametersConverter swayingParametersConverter
private static IEnumerable<Converter.Message> GetMessagesAboutDynamicBoneLimits(GameObject avatar)
{
var messages = new List<Converter.Message>();
AvatarPerformanceStats statistics = AvatarPerformance.CalculatePerformanceStats(
avatarName: avatar.GetComponent<VRMMeta>().Meta.Title,
avatarObject: avatar
);Debug.Log(statistics.DynamicBoneAffectedTransformCount);

var dynamicBonesAndAffectedTransformCounts = avatar.GetComponentsInChildren<DynamicBone>().ToDictionary(
keySelector: dynamicBone => dynamicBone,
elementSelector: dynamicBone => {
Transform rootTransform = dynamicBone.m_Root;
if (!rootTransform.IsChildOf(avatar.transform))
{
return 0;
}

return dynamicBone.m_Root.GetComponentsInChildren<Transform>().Length
//- 1 // Collision checks counted incorrectly | Bug Reports | VRChat <https://vrchat.canny.io/bug-reports/p/collision-checks-counted-incorrectly>
- (dynamicBone.m_Exclusions != null ? dynamicBone.m_Exclusions.Sum(exclusion => exclusion.GetComponentsInChildren<Transform>().Length) : 0);
}
);

int affectedTransformCount = dynamicBonesAndAffectedTransformCounts.Values.Sum();
if (affectedTransformCount > AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneAffectedTransformCount)
if (statistics.DynamicBoneAffectedTransformCount
> AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneAffectedTransformCount)
{
messages.Add(new Converter.Message
{
message = string.Format(Gettext._("The “Dynamic Bone Affected Transform Count” is {0}."), affectedTransformCount)
+ string.Format(
Gettext._("If this value exceeds {0}, the default user setting disable all Dynamic Bones."),
AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneAffectedTransformCount
),
message = string.Format(
Gettext._("The “Dynamic Bone Affected Transform Count” is {0}."),
statistics.DynamicBoneAffectedTransformCount
) + string.Format(
Gettext._("If this value exceeds {0}, the default user setting disable all Dynamic Bones."),
AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneAffectedTransformCount
),
type = MessageType.Warning,
});
}

int collisionCheckCount = dynamicBonesAndAffectedTransformCounts.Sum(selector: dynamicBoneAndAffectedTransformCount => {
IEnumerable<DynamicBoneColliderBase> colliders = dynamicBoneAndAffectedTransformCount.Key.m_Colliders;
if (colliders == null)
{
return 0;
}

return (dynamicBoneAndAffectedTransformCount.Value)
* colliders.Where(collider => collider.transform.IsChildOf(avatar.transform)).Count();
});
if (collisionCheckCount > AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneCollisionCheckCount)

if (statistics.DynamicBoneCollisionCheckCount
> AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneCollisionCheckCount)
{
messages.Add(new Converter.Message
{
message = string.Format(Gettext._("The “Dynamic Bone Collision Check Count” is {0}."), collisionCheckCount)
+ string.Format(
Gettext._("If this value exceeds {0}, the default user setting disable all Dynamic Bones."),
AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneCollisionCheckCount
),
message = string.Format(
Gettext._("The “Dynamic Bone Collision Check Count” is {0}."),
statistics.DynamicBoneCollisionCheckCount
) + string.Format(
Gettext._("If this value exceeds {0}, the default user setting disable all Dynamic Bones."),
AvatarPerformanceStats.MediumPeformanceStatLimits.DynamicBoneCollisionCheckCount
),
type = MessageType.Warning,
});
}
Expand Down
5 changes: 5 additions & 0 deletions Editor/VRChatUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public enum Anim
/// </summary>
internal static readonly string CustomStandingAnimsPath = "Assets/VRCSDK/Examples/Sample Assets/Animation/CustomOverrideEmpty.overrideController";

/// <summary>
/// <see cref="AvatarPerformance"/>クラスが記述されているファイルのパス。
/// </summary>
internal static readonly string AvatarPerformanceClassPath = "Assets/VRCSDK/Dependencies/VRChat/Scripts/AvatarPerformance.cs";

/// <summary>
/// <see cref="VRC_SdkControlPanel.AnalyzeGeometry"/>を実行します。
/// </summary>
Expand Down

0 comments on commit ef8bac7

Please sign in to comment.