Closed jacobjgrant closed 1 month ago
Thank you, for bug reporting, try make changes to EquipmentModelBonesSetupByHumanBodyBonesUpdater.cs
I've forget to dispose
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Jobs;
namespace MultiplayerARPG
{
[DefaultExecutionOrder(int.MaxValue - 1)]
public class EquipmentModelBonesSetupByHumanBodyBonesUpdater : MonoBehaviour
{
[System.Serializable]
public struct PredefinedBone
{
public HumanBodyBones boneType;
public Transform boneTransform;
}
public PredefinedBone[] predefinedBones = new PredefinedBone[0];
private readonly List<Transform> _srcTransforms = new List<Transform>();
private TransformAccessArray _dstTransforms = new TransformAccessArray();
private Dictionary<HumanBodyBones, Transform> _predefinedBonesDict;
public Dictionary<HumanBodyBones, Transform> PredefinedBonesDict
{
get
{
if (_predefinedBonesDict == null)
{
_predefinedBonesDict = new Dictionary<HumanBodyBones, Transform>();
for (int i = 0; i < predefinedBones.Length; ++i)
{
_predefinedBonesDict.Add(predefinedBones[i].boneType, predefinedBones[i].boneTransform);
}
}
return _predefinedBonesDict;
}
}
public void PrepareTransforms(Animator src, Animator dst)
{
#if !UNITY_SERVER
if (src == null || dst == null)
return;
if (_dstTransforms.isCreated)
_dstTransforms.Dispose();
List<Transform> tempDstTransforms = new List<Transform>();
for (int i = 0; i < (int)HumanBodyBones.LastBone; ++i)
{
Transform srcTransform = src.GetBoneTransform((HumanBodyBones)i);
if (srcTransform == null)
continue;
Transform dstTransform = null;
try
{
dstTransform = dst.GetBoneTransform((HumanBodyBones)i);
}
catch (System.Exception)
{
// Some error occuring, skip it.
}
if (dstTransform != null)
{
_srcTransforms.Add(srcTransform);
tempDstTransforms.Add(dstTransform);
}
else if (PredefinedBonesDict.TryGetValue((HumanBodyBones)i, out dstTransform))
{
_srcTransforms.Add(srcTransform);
tempDstTransforms.Add(dstTransform);
}
}
_dstTransforms = new TransformAccessArray(tempDstTransforms.ToArray());
#endif
}
private void OnDestroy()
{
#if !UNITY_SERVER
if (_dstTransforms.isCreated)
_dstTransforms.Dispose();
#endif
}
#if !UNITY_SERVER
private void LateUpdate()
{
if (_srcTransforms.Count <= 0 || !_dstTransforms.isCreated)
return;
int transformsCount = _srcTransforms.Count;
// Prepare source data
NativeArray<Vector3> sourcePositions = new NativeArray<Vector3>(transformsCount, Allocator.TempJob);
NativeArray<Quaternion> sourceRotations = new NativeArray<Quaternion>(transformsCount, Allocator.TempJob);
NativeArray<Vector3> sourceLocalScales = new NativeArray<Vector3>(transformsCount, Allocator.TempJob);
for (int i = 0; i < _srcTransforms.Count; ++i)
{
_srcTransforms[i].GetPositionAndRotation(out Vector3 position, out Quaternion rotation);
sourcePositions[i] = position;
sourceRotations[i] = rotation;
sourceLocalScales[i] = _srcTransforms[i].localScale;
}
// Prepare jobs
CopyTransformsJob job = new CopyTransformsJob
{
sourcePositions = sourcePositions,
sourceRotations = sourceRotations,
sourceLocalScales = sourceLocalScales,
};
JobHandle jobHandle = job.Schedule(_dstTransforms);
jobHandle.Complete();
sourcePositions.Dispose();
sourceRotations.Dispose();
sourceLocalScales.Dispose();
}
#endif
[BurstCompile]
private struct CopyTransformsJob : IJobParallelForTransform
{
[ReadOnly]
public NativeArray<Vector3> sourcePositions;
[ReadOnly]
public NativeArray<Quaternion> sourceRotations;
[ReadOnly]
public NativeArray<Vector3> sourceLocalScales;
public void Execute(int index, TransformAccess transform)
{
if (!transform.isValid)
return;
transform.SetPositionAndRotation(sourcePositions[index], sourceRotations[index]);
transform.localScale = sourceLocalScales[index];
}
}
}
}
That stopeed the leak ty
Dam. I spoke too soon. Yes the memory leaks have gone, but Its not adding my skinned mesh anymore either. Its just sitting on the ground. Is there any other ideas mate?
is the problem the update? Cause I need it to add the mesh.
I did this and memory leaks have gone...
using System.Collections.Generic; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; using UnityEngine.Jobs;
namespace MultiplayerARPG { [DefaultExecutionOrder(int.MaxValue - 1)] public class EquipmentModelBonesSetupByHumanBodyBonesUpdater : MonoBehaviour { [System.Serializable] public struct PredefinedBone { public HumanBodyBones boneType; public Transform boneTransform; }
public PredefinedBone[] predefinedBones = new PredefinedBone[0];
private readonly List<Transform> _srcTransforms = new List<Transform>();
private TransformAccessArray _dstTransforms = new TransformAccessArray();
private Dictionary<HumanBodyBones, Transform> _predefinedBonesDict;
public Dictionary<HumanBodyBones, Transform> PredefinedBonesDict
{
get
{
if (_predefinedBonesDict == null)
{
_predefinedBonesDict = new Dictionary<HumanBodyBones, Transform>();
for (int i = 0; i < predefinedBones.Length; ++i)
{
_predefinedBonesDict.Add(predefinedBones[i].boneType, predefinedBones[i].boneTransform);
}
}
return _predefinedBonesDict;
}
}
public void PrepareTransforms(Animator src, Animator dst)
{
if (src == null || dst == null)
return;
if (_dstTransforms.isCreated)
_dstTransforms.Dispose();
List<Transform> tempDstTransforms = new List<Transform>();
for (int i = 0; i < (int)HumanBodyBones.LastBone; ++i)
{
Transform srcTransform = src.GetBoneTransform((HumanBodyBones)i);
if (srcTransform == null)
continue;
Transform dstTransform = null;
try
{
dstTransform = dst.GetBoneTransform((HumanBodyBones)i);
}
catch (System.Exception)
{
// Some error occuring, skip it.
}
if (dstTransform != null)
{
_srcTransforms.Add(srcTransform);
tempDstTransforms.Add(dstTransform);
}
else if (PredefinedBonesDict.TryGetValue((HumanBodyBones)i, out dstTransform))
{
_srcTransforms.Add(srcTransform);
tempDstTransforms.Add(dstTransform);
}
}
_dstTransforms = new TransformAccessArray(tempDstTransforms.ToArray());
}
private void OnDestroy()
{
if (_dstTransforms.isCreated)
_dstTransforms.Dispose();
}
private void LateUpdate()
{
if (_srcTransforms.Count <= 0 || !_dstTransforms.isCreated)
return;
int transformsCount = _srcTransforms.Count;
// Prepare source data
NativeArray<Vector3> sourcePositions = new NativeArray<Vector3>(transformsCount, Allocator.TempJob);
NativeArray<Quaternion> sourceRotations = new NativeArray<Quaternion>(transformsCount, Allocator.TempJob);
NativeArray<Vector3> sourceLocalScales = new NativeArray<Vector3>(transformsCount, Allocator.TempJob);
for (int i = 0; i < _srcTransforms.Count; ++i)
{
_srcTransforms[i].GetPositionAndRotation(out Vector3 position, out Quaternion rotation);
sourcePositions[i] = position;
sourceRotations[i] = rotation;
sourceLocalScales[i] = _srcTransforms[i].localScale;
}
// Prepare jobs
CopyTransformsJob job = new CopyTransformsJob
{
sourcePositions = sourcePositions,
sourceRotations = sourceRotations,
sourceLocalScales = sourceLocalScales,
};
JobHandle jobHandle = job.Schedule(_dstTransforms);
jobHandle.Complete();
sourcePositions.Dispose();
sourceRotations.Dispose();
sourceLocalScales.Dispose();
}
[BurstCompile]
private struct CopyTransformsJob : IJobParallelForTransform
{
[ReadOnly]
public NativeArray<Vector3> sourcePositions;
[ReadOnly]
public NativeArray<Quaternion> sourceRotations;
[ReadOnly]
public NativeArray<Vector3> sourceLocalScales;
public void Execute(int index, TransformAccess transform)
{
if (!transform.isValid)
return;
transform.SetPositionAndRotation(sourcePositions[index], sourceRotations[index]);
transform.localScale = sourceLocalScales[index];
}
}
}
}
And it adds armour with no leaks...
You've just delete #if !UNITY_SERVER
conditions, I intend to optimize it by not update on server.
I will be better change conditions like this #if !UNITY_SERVER || UNITY_EDITOR
Ok mate, can you post the updated script once you have optimised it?
I've told you what it should be, it is very easy to make changes by yourself, so I won't post it again.
I am experienceing Memory leaks when I use the skinned mesh renderer. When I use the Equipment Model Bones Setup By Human Body Bones Manager. I have also tried the List Replacing Manager and the Bone Names Manager. Which canot find the bone names.
My armour has the correct Armature atached to it and its identical the character rig names, yet it cant find the bones.
The renderer works when I use the Equipment Model Bones Setup By Human Body Bones Manager except for the memory leak issue. Is there a way to stop this from happening? Im unsing unity 2022.3.16f1 and the latest version of the kit.