@CodeSmile
I removed many assets from the environment but it is not helping much. Also added the LODs to many assets.
So I profiled the IOS build. I getting the spikes at a certain duration. Mainly for three different systems one after another.
- From Physics.System.BuildPhysicsWorld (I am not sure why I am getting a spike from this)
- WeaponFiringMechnisum (Used ISystem with BurstCompile but still getting spike)
- ThirdPersonPlayerAnimationSystem (Used ISystem with BurstCompile but still getting spike)
using Rukhanka;
using System.Runtime.CompilerServices;
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using Unity.NetCode;
public struct InputStateData
{
public float Speed;
public bool Jump;
public bool Grounded;
public bool Crouch;
public float InputX;
public float InputY;
public bool IsIdle;
public bool FreeFall;
public float MotionSpeed;
public bool IsShooting;
public bool Sprint;
public bool IsDancing;
public float DanceIndex;
public bool IsAttecking;
public bool IsVictim;
public float FinisherIndex;
public bool IsDead;
public int CombinedStates;
}
#if RUKHANKA_WITH_NETCODE
[UpdateInGroup(typeof(RukhankaPredictedAnimationSystemGroup))]
#endif
[UpdateBefore(typeof(RukhankaAnimationSystemGroup))]
[RequireMatchingQueriesForUpdate]
[BurstCompile]
public partial struct ThirdPersonPlayerAnimationSystem : ISystem
{
private FastAnimatorParameter Speed;
private FastAnimatorParameter Jump;
private FastAnimatorParameter Grounded;
private FastAnimatorParameter Crouch;
private FastAnimatorParameter InputX;
private FastAnimatorParameter InputY;
private FastAnimatorParameter IsIdle;
private FastAnimatorParameter IsAiming;
private FastAnimatorParameter MotionSpeed;
private FastAnimatorParameter IsShooting;
private FastAnimatorParameter Sprint;
private FastAnimatorParameter IsDancing;
private FastAnimatorParameter DanceIndex;
private FastAnimatorParameter IsAttecking;
private FastAnimatorParameter IsVictim;
private FastAnimatorParameter FinisherIndex;
private FastAnimatorParameter IsDead;
private FastAnimatorParameter CombinedStates;
private float m_SprintSpeedMultiplier;
private float m_SmoothTime;
[BurstCompile]
public void OnCreate(ref SystemState state)
{
Speed = new FastAnimatorParameter("Speed");
Jump = new FastAnimatorParameter("Jump");
Grounded = new FastAnimatorParameter("Grounded");
Crouch = new FastAnimatorParameter("Crouch");
InputX = new FastAnimatorParameter("InputX");
InputY = new FastAnimatorParameter("InputY");
IsIdle = new FastAnimatorParameter("IsIdle");
IsAiming = new FastAnimatorParameter("IsAiming");
MotionSpeed = new FastAnimatorParameter("MotionSpeed");
IsShooting = new FastAnimatorParameter("IsShooting");
Sprint = new FastAnimatorParameter("Sprint");
IsDancing = new FastAnimatorParameter("IsDancing");
DanceIndex = new FastAnimatorParameter("DanceIndex");
IsAttecking = new FastAnimatorParameter("IsAttecking");
IsVictim = new FastAnimatorParameter("IsVictim");
FinisherIndex = new FastAnimatorParameter("FinisherIndex");
IsDead = new FastAnimatorParameter("IsDead");
CombinedStates = new FastAnimatorParameter("CombinedStates");
m_SprintSpeedMultiplier = 2f;
m_SmoothTime = 0.2f;
state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll<ThirdPersonCharacterComponent, GhostOwnerIsLocal>().Build());
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var deltaTime = SystemAPI.Time.DeltaTime;
foreach (var (animatorParameterComponent, characterAspect, characterComponent, playerFinisherState, health, entity) in
SystemAPI.Query<DynamicBuffer<AnimatorControllerParameterComponent>, ThirdPersonCharacterAspect, ThirdPersonCharacterComponent, RefRW<PlayerFinisherState>, Health>()
.WithAll<ThirdPersonCharacterComponent, GhostOwnerIsLocal>()
.WithEntityAccess())
{
/*if (playerFinisherState.ValueRO.IsPlayerVictim)
PlayerInputHandler.Instance.crouch = false;*/
if (characterAspect.CharacterControl.ValueRO.Sprint)
m_SprintSpeedMultiplier = characterComponent.SprintSpeedMultiplier;
else if (characterAspect.CharacterControl.ValueRO.Crouch)
m_SprintSpeedMultiplier = characterComponent.CrouchSpeedMultiplier;
else
m_SprintSpeedMultiplier = characterComponent.SprintSpeedMultiplier;
float speedValue;
bool isIdle = characterAspect.CharacterControl.ValueRO.MoveVector.x == 0 && characterAspect.CharacterControl.ValueRO.MoveVector.y == 0;
if (!characterAspect.CharacterControl.ValueRO.Sprint && !isIdle)
{
float rawSpeed = math.length(characterAspect.CharacterControl.ValueRO.MoveVector * m_SprintSpeedMultiplier);
float maxSpeed = m_SprintSpeedMultiplier;
speedValue = math.remap(0f, maxSpeed, 1.7f, 1f, rawSpeed);
}
else
{
speedValue = math.length(characterAspect.CharacterControl.ValueRO.MoveVector * m_SprintSpeedMultiplier);
}
UpdateAnimatorParameter(animatorParameterComponent, 0, speedValue);
UpdateAnimatorParameter(animatorParameterComponent, 1, characterAspect.CharacterControl.ValueRO.Jump);
UpdateAnimatorParameter(animatorParameterComponent, 2, characterAspect.CharacterControl.ValueRO.IsGrounded);
UpdateAnimatorParameter(animatorParameterComponent, 3, characterAspect.CharacterControl.ValueRO.Crouch);
UpdateAnimatorParameter(animatorParameterComponent, 4, math.lerp(characterAspect.CharacterControl.ValueRO.MoveAxisValue.x, characterAspect.CharacterControl.ValueRO.MoveAxisValue.x, m_SmoothTime));
UpdateAnimatorParameter(animatorParameterComponent, 5, math.lerp(characterAspect.CharacterControl.ValueRO.MoveAxisValue.y, characterAspect.CharacterControl.ValueRO.MoveAxisValue.y, m_SmoothTime));
UpdateAnimatorParameter(animatorParameterComponent, 6, speedValue == 0);
UpdateAnimatorParameter(animatorParameterComponent, 7, characterAspect.CharacterControl.ValueRO.IsAiming);
UpdateAnimatorParameter(animatorParameterComponent, 8, 1f);
UpdateAnimatorParameter(animatorParameterComponent, 9, characterAspect.CharacterControl.ValueRO.IsShooting);
UpdateAnimatorParameter(animatorParameterComponent, 10, characterAspect.CharacterControl.ValueRO.Sprint);
UpdateAnimatorParameter(animatorParameterComponent, 11, characterAspect.CharacterControl.ValueRO.IsDancing);
UpdateAnimatorParameter(animatorParameterComponent, 12, characterAspect.CharacterControl.ValueRO.DanceIndex);
UpdateAnimatorParameter(animatorParameterComponent, 13, playerFinisherState.ValueRW.IsPlayerAttecker);
UpdateAnimatorParameter(animatorParameterComponent, 14, playerFinisherState.ValueRW.IsPlayerVictim);
UpdateAnimatorParameter(animatorParameterComponent, 15, playerFinisherState.ValueRW.AnimationIndex);
if (!playerFinisherState.ValueRW.IsPlayerVictim)
{
UpdateAnimatorParameter(animatorParameterComponent, 16, health.IsDead());
}
UpdateAnimatorParameter(animatorParameterComponent, 17, characterAspect.CharacterControl.ValueRO.IsReloading ? 5 : 0);
}
}
private void UpdateAnimatorParameter(DynamicBuffer<AnimatorControllerParameterComponent> buffer, int index, float value)
{
var param = buffer[index];
param.FloatValue = value;
buffer[index] = param;
}
private void UpdateAnimatorParameter(DynamicBuffer<AnimatorControllerParameterComponent> buffer, int index, bool value)
{
var param = buffer[index];
param.BoolValue = value;
buffer[index] = param;
}
private void UpdateAnimatorParameter(DynamicBuffer<AnimatorControllerParameterComponent> buffer, int index, int value)
{
var param = buffer[index];
param.IntValue = value;
buffer[index] = param;
}
}
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation | WorldSystemFilterFlags.ServerSimulation)]
[UpdateInGroup(typeof(WeaponPredictionUpdateGroup), OrderFirst = true)]
[BurstCompile]
public partial struct WeaponFiringMecanismSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll<StandardWeaponFiringMecanism, WeaponControl>().Build());
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
StandardWeaponFiringMecanismJob standardMecanismJob = new StandardWeaponFiringMecanismJob
{
DeltaTime = SystemAPI.Time.DeltaTime,
};
state.Dependency = standardMecanismJob.Schedule(state.Dependency);
}
[BurstCompile]
[WithAll(typeof(Simulate))]
public partial struct StandardWeaponFiringMecanismJob : IJobEntity
{
public float DeltaTime;
void Execute(Entity entity, ref StandardWeaponFiringMecanism mecanism, ref WeaponControl weaponControl, ref WeaponShotVisuals weaponShotVisuals, in GhostOwner ghostOwner)
{
mecanism.ShotsToFire = 0;
mecanism.ShotTimer += DeltaTime;
// Detect starting to fire
if (weaponControl.ShootPressed)
{
mecanism.IsFiring = true;
}
// Handle firing
if (mecanism.FiringRate > 0f)
{
float delayBetweenShots = 1f / mecanism.FiringRate;
// Clamp shot timer in order to shoot at most the maximum amount of shots that can be shot in one frame based on the firing rate.
// This also prevents needlessly dirtying the timer ghostfield (saves bandwidth).
mecanism.ShotTimer = math.clamp(mecanism.ShotTimer, 0f, math.max(delayBetweenShots + 0.01f ,DeltaTime));
// This loop is done to allow firing rates that would trigger more than one shot per tick
while (mecanism.IsFiring && mecanism.ShotTimer > delayBetweenShots)
{
mecanism.ShotsToFire++;
// Consume shoot time
mecanism.ShotTimer -= delayBetweenShots;
// Stop firing after initial shot for non-auto fire
if (!mecanism.Automatic)
{
mecanism.IsFiring = false;
}
}
}
// Detect stopping fire
if (!mecanism.Automatic || weaponControl.ShootReleased)
{
mecanism.IsFiring = false;
}
weaponShotVisuals.TotalShotsCount += mecanism.ShotsToFire;
}
}
}
here are some images related to the profiling