Fix annimation not loop

This commit is contained in:
Tran Hai Nam
2026-05-11 11:00:04 +07:00
parent 6cebb9079d
commit dda7b1c0db
3 changed files with 82 additions and 50 deletions
@@ -127,6 +127,8 @@ namespace ModelViewer.Common
public int m_nMinLoops;
public int m_nMaxLoops;
public bool IsInfinite() { return m_nMinLoops == -1 || m_nMaxLoops == -1; }
public int CalcLoopNum() { return IsInfinite() ? -1 : Random.Range(m_nMinLoops, m_nMaxLoops); }
public bool Load(FileStream fileStream, StreamReader file, uint dwVersion)
{
bool isBinary = fileStream != null;
@@ -174,6 +176,21 @@ namespace ModelViewer.Common
}
}
public class ACTIONDYN_DATA
{
private int m_nLoopNum;
ACTION_INFO m_pInfo;
public ACTIONDYN_DATA(int nLoopNum = 0, ACTION_INFO pInfo = null)
{
m_nLoopNum = nLoopNum;
m_pInfo = pInfo;
}
public int GetLoopNum() { return m_nLoopNum; }
public ACTION_INFO GetActInfo() { return m_pInfo; }
public int GetTimeSpan() { return 1/*m_pInfo.GetTimeSpan()*/; }
public int GetTotalTime() { return GetLoopNum() * GetTimeSpan(); }
}
[System.Serializable]
public class EVENT_INFO
{
@@ -487,7 +504,7 @@ namespace ModelViewer.Common
public string m_strName;
public int m_nLoops;
public bool IsLooping()
{
if (m_ActLst.Count == 0)
+35 -20
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
@@ -138,18 +139,11 @@ public class A3DCombActDynData
m_bSetSpeedWhenActStart = false;
m_fModelScale = 1.0f;
var actInfoList = pAct.m_ActLst;
// {
// ActInfoList& actInfoList = pAct->m_ActLst;
// ALISTPOSITION pos = actInfoList.GetHeadPosition();
// while (pos)
// {
// PACTION_INFO pAct = actInfoList.GetNext(pos);
// int nDynLoopNum = pAct->CalcLoopNum();
// m_arrActLoopNum.Add(ACTIONDYN_DATA(nDynLoopNum, pAct));
// if (!m_bIsInfiniteComAct && nDynLoopNum < 0) m_bIsInfiniteComAct = true;
// }
// CalcDynComActSpan();
// }
foreach(var actInfo in actInfoList)
{
int nDynLoopNum = actInfo.CalcLoopNum();
if (!m_bIsInfiniteComAct && nDynLoopNum < 0) m_bIsInfiniteComAct = true;
}
}
/// <param name="triggerVisualAndFx">
@@ -197,12 +191,13 @@ public class A3DCombActDynData
ChannelAct channelAct = m_pECModel.GetChannelAct(m_nChannel);
if (channelAct != null)
{
bool isLoop = m_pAct.m_nLoops == 1;
bool isLoop = m_bIsInfiniteComAct;
int ownerId = m_pECModel.GetId();
EventBus.PublishChannel(ownerId, new PlayActionEvent(ref channelAct, actionInfos[0].m_strName, m_nTransTime, bForceStopPrevious, ActiveAttackEvent, isLoop, channelRank));
m_ActionNames.Add(actionInfos[0].m_strName);
for(int i = 1; i < actionInfos.Count; i++)
{
isLoop = m_bIsInfiniteComAct;
EventBus.PublishChannelClass(ownerId, new QueueActionEvent(ref channelAct, actionInfos[i].m_strName, null, false, null, m_nTransTime, false, isLoop, channelRank));
m_ActionNames.Add(actionInfos[i].m_strName);
}
@@ -228,21 +223,41 @@ public class A3DCombActDynData
{
if (sfx.m_strFilePaths != null && sfx.m_strFilePaths.Count > 0)
{
string soundpath = AFile.NormalizePath(sfx.m_strFilePaths[0], true);
if (soundpath.Contains("gfx"))
continue;
soundpath = soundpath.ToLower();
m_SFXNames.Add(soundpath);
string path = AFile.NormalizePath(sfx.m_strFilePaths[0], true);
if (path.Contains("gfx"))
goto GFX;
path = path.ToLower();
m_SFXNames.Add(path);
try
{
SFXManager.Instance
.PlaySkillSfxAtPointAsync(soundpath, Vector3.zero).Forget();
.PlaySkillSfxAtPointAsync(path, Vector3.zero).Forget();
}
finally
{
// remove AFTER sound finished
m_SFXNames.Remove(soundpath);
m_SFXNames.Remove(path);
}
goto END;
GFX:
{
var gfxLogPath = Path.Combine(Application.dataPath, "PerfectWorld", "Scripts", "NPC", "GFXLOG.txt");
var lines = new List<string>();
if (File.Exists(gfxLogPath))
{
foreach (var line in File.ReadAllLines(gfxLogPath))
{
if (string.Equals(line.Trim(), path, StringComparison.OrdinalIgnoreCase))
continue;
lines.Add(line);
}
}
lines.Add(path);
File.WriteAllLines(gfxLogPath, lines);
}
END:
continue;
}
}
}
+29 -29
View File
@@ -46,20 +46,27 @@ namespace BrewMonster
}
if (_animationQueue.Count > 0)
{
_animationQueue.Enqueue(new AnimationQueue
if(@event.IsForceStopPrevious)
{
AnimationName = @event.AnimationName,
IsForceStopPrevious = @event.IsForceStopPrevious,
AttackEvent = @event.AttackEvent,
ChannelAct = @event.ChannelAct,
Rank = @event.Rank
});
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
return;
_animationQueue.Clear();
}
else
{
_animationQueue.Enqueue(new AnimationQueue
{
AnimationName = @event.AnimationName,
IsForceStopPrevious = @event.IsForceStopPrevious,
AttackEvent = @event.AttackEvent,
ChannelAct = @event.ChannelAct,
Rank = @event.Rank
});
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
return;
}
}
previousAnimationName = @event.AnimationName;
InternalPlayAnimation(@event.AnimationName, @event.ITransTime, FadeMode, @event.IsLoop);
ApplyAnimationEndCallbacks(@event.AttackEvent, @event.ChannelAct, @event.Rank, @event.AnimationName);
InternalPlayAnimation(@event.AnimationName, @event.ITransTime, FadeMode);
ApplyAnimationEndCallbacks(@event.AttackEvent, @event.ChannelAct, @event.Rank, @event.AnimationName, @event.IsLoop);
}
public void InitPlayerEventDoneHandler()
{
@@ -195,6 +202,7 @@ namespace BrewMonster
AttackEvent = null,
IsLoop = true
});
Debug.Log($"EnqueueAnimationForLooping: {animationName}, _animationQueue: {string.Join(", ", _animationList)}");
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
return true;
}
@@ -205,14 +213,6 @@ namespace BrewMonster
{
return;
}
else
{
string animationQueueString = "";
foreach(var animation in _animationQueue)
{
animationQueueString += animation.AnimationName + ", ";
}
}
if (_animationQueue.Peek().IsForceStopPrevious)
{
@@ -227,21 +227,26 @@ namespace BrewMonster
var animationQueue = _animationQueue.Dequeue();
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
previousAnimationName = animationQueue.AnimationName;
InternalPlayAnimation(animationQueue.AnimationName, animationQueue.ITransTime, FadeMode, animationQueue.IsLoop);
ApplyAnimationEndCallbacks(animationQueue.AttackEvent, animationQueue.ChannelAct, animationQueue.Rank, animationQueue.AnimationName);
InternalPlayAnimation(animationQueue.AnimationName, animationQueue.ITransTime, FadeMode);
ApplyAnimationEndCallbacks(animationQueue.AttackEvent, animationQueue.ChannelAct, animationQueue.Rank, animationQueue.AnimationName,animationQueue.IsLoop);
}
private void ApplyAnimationEndCallbacks(CECAttackEvent attackEvent, ChannelAct channelAct, int rank, string animationName)
private void ApplyAnimationEndCallbacks(CECAttackEvent attackEvent, ChannelAct channelAct, int rank, string animationName, bool isLoop)
{
if (_currentState == null) return;
_currentState.Events.OnEnd = () =>
{
if (attackEvent != null)
attackEvent.m_bSignaled = true;
if(isLoop)
{
EnqueueAnimationForLooping(animationName);
}
if (channelAct == null || string.IsNullOrEmpty(animationName))
return;
var node = channelAct.GetNodeByRank((byte)rank);
node?.m_pActive?.m_ActionNames?.Remove(animationName);
};
}
void ApplyDamage()
@@ -271,7 +276,7 @@ namespace BrewMonster
/// <param name="animationName"></param>
/// <param name="duration"></param>
/// <param name="fadeMode"></param>
private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode, bool isLoop = false)
private void InternalPlayAnimation(string animationName, float duration = FadeTime, FadeMode fadeMode = FadeMode)
{
if (namedAnimancer == null)
{
@@ -281,13 +286,8 @@ namespace BrewMonster
if (isState)
{
_currentState = namedAnimancer.TryPlay(animationName, duration / 1000, fadeMode);
_currentState.Time = 0;
_currentAnimationName = animationName;
//if the animation is looping and the current state is not looping, play the animation again
if(isLoop == true && _currentState.IsLooping == false)
{
_currentState.Time = 0;
_currentState.Events.OnEnd = () => EnqueueAnimationForLooping(animationName);
}
return;
}
//BMLogger.LogError($"Null name animation: {animationName}");