fix: bind fighter animator controller in lobby
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using NUnit.Framework;
|
||||
using XGame.ActorBehavior;
|
||||
|
||||
public sealed class ActorBehaviorAnimatorControllerPathTests
|
||||
{
|
||||
[Test]
|
||||
public void GetControllerPath_Fighter_ReturnsGeneratedFighterController()
|
||||
{
|
||||
Assert.That(
|
||||
ActorBehaviorAnimatorControllerPaths.GetControllerPath("fighter"),
|
||||
Is.EqualTo("Assets/Game/Art/Actor/Controller/fighter.controller"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetControllerPath_UnknownType_ReturnsNull()
|
||||
{
|
||||
Assert.That(ActorBehaviorAnimatorControllerPaths.GetControllerPath("unknown"), Is.Null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b0d0c33caa94dbc94a83cf2c7e1cba0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UObject = UnityEngine.Object;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace XGame.ActorBehavior
|
||||
{
|
||||
public static class ActorBehaviorAnimatorControllerPaths
|
||||
{
|
||||
public static string GetControllerPath(string catalogType)
|
||||
{
|
||||
return string.Equals(catalogType, LobbyActorBehaviorRuntime.DefaultCatalogType, StringComparison.OrdinalIgnoreCase)
|
||||
? "Assets/Game/Art/Actor/Controller/fighter.controller"
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ActorBehaviorAnimatorControllerLoader
|
||||
{
|
||||
public static IEnumerator ApplyController(string catalogType, Animator animator, Action<bool> onApplied = null)
|
||||
{
|
||||
if (animator == null)
|
||||
{
|
||||
onApplied?.Invoke(false);
|
||||
yield break;
|
||||
}
|
||||
|
||||
string controllerPath = ActorBehaviorAnimatorControllerPaths.GetControllerPath(catalogType);
|
||||
if (string.IsNullOrEmpty(controllerPath))
|
||||
{
|
||||
onApplied?.Invoke(false);
|
||||
yield break;
|
||||
}
|
||||
|
||||
RuntimeAnimatorController controller = LoadControllerInEditor(controllerPath);
|
||||
if (controller == null)
|
||||
{
|
||||
UObject loaded = null;
|
||||
yield return XGame.XResLoader.coLoadRes(controllerPath, typeof(RuntimeAnimatorController), obj => loaded = obj);
|
||||
controller = loaded as RuntimeAnimatorController;
|
||||
}
|
||||
|
||||
if (controller == null)
|
||||
{
|
||||
Debug.LogWarning("[ActorBehaviorAnimatorControllerLoader] controller load failed: " + controllerPath);
|
||||
onApplied?.Invoke(false);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (animator.runtimeAnimatorController != controller)
|
||||
{
|
||||
animator.runtimeAnimatorController = controller;
|
||||
animator.Rebind();
|
||||
animator.Update(0f);
|
||||
}
|
||||
onApplied?.Invoke(true);
|
||||
}
|
||||
|
||||
private static RuntimeAnimatorController LoadControllerInEditor(string controllerPath)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(controllerPath);
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a9d2d021b3b4de0a1e9437e62a08f6a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -56,6 +56,10 @@ namespace XGame
|
||||
private const float CameraMouseZoomSensitivity = 1.4f;
|
||||
private const float CameraPinchZoomSensitivity = 0.015f;
|
||||
private const float CameraFollowSharpness = 12f;
|
||||
private const string FighterStandState = "140_stand01_qt";
|
||||
private const string FighterWalkState = "140_walk01_qt";
|
||||
private const string LegacyStandState = "Stand";
|
||||
private const string LegacyWalkState = "Walk";
|
||||
|
||||
private readonly Dictionary<int, Avatar> avatars = new Dictionary<int, Avatar>();
|
||||
private readonly Dictionary<int, GameObject> prefabCache = new Dictionary<int, GameObject>();
|
||||
@@ -805,7 +809,11 @@ namespace XGame
|
||||
{
|
||||
return;
|
||||
}
|
||||
string state = moving ? "Walk" : "Stand";
|
||||
string state = ResolveMoveState(avatar.Animator, moving);
|
||||
if (string.IsNullOrEmpty(state))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (avatar.AnimState == state)
|
||||
{
|
||||
return;
|
||||
@@ -814,6 +822,25 @@ namespace XGame
|
||||
avatar.Animator.CrossFade(state, 0.1f);
|
||||
}
|
||||
|
||||
private static string ResolveMoveState(Animator animator, bool moving)
|
||||
{
|
||||
string fighterState = moving ? FighterWalkState : FighterStandState;
|
||||
if (HasAnimatorState(animator, fighterState))
|
||||
{
|
||||
return fighterState;
|
||||
}
|
||||
|
||||
string legacyState = moving ? LegacyWalkState : LegacyStandState;
|
||||
return HasAnimatorState(animator, legacyState) ? legacyState : null;
|
||||
}
|
||||
|
||||
private static bool HasAnimatorState(Animator animator, string state)
|
||||
{
|
||||
return animator != null
|
||||
&& animator.runtimeAnimatorController != null
|
||||
&& animator.HasState(0, Animator.StringToHash(state));
|
||||
}
|
||||
|
||||
private void UpdateJoystick()
|
||||
{
|
||||
joystick = Vector2.zero;
|
||||
@@ -994,6 +1021,43 @@ namespace XGame
|
||||
actorBehaviorRuntime.RegisterOrUpdateActor(avatar.PlayerId, avatar.Obj.transform.position, avatar.Obj.transform.forward);
|
||||
actorBehaviorRuntime.SwitchActorCatalog(avatar.PlayerId, LobbyActorBehaviorRuntime.DefaultCatalogType);
|
||||
actorBehaviorPresentation.RegisterActor(avatar.PlayerId, avatar.Animator, avatar.Obj.transform, avatar.Obj.transform);
|
||||
ApplyActorBehaviorAnimatorController(avatar);
|
||||
}
|
||||
|
||||
private void ApplyActorBehaviorAnimatorController(Avatar avatar)
|
||||
{
|
||||
if (avatar == null || avatar.Obj == null || avatar.Animator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartCoroutine(ApplyActorBehaviorAnimatorControllerAsync(
|
||||
avatar.PlayerId,
|
||||
avatar.Obj,
|
||||
avatar.Animator,
|
||||
LobbyActorBehaviorRuntime.DefaultCatalogType));
|
||||
}
|
||||
|
||||
private IEnumerator ApplyActorBehaviorAnimatorControllerAsync(
|
||||
int playerId,
|
||||
GameObject actorObject,
|
||||
Animator animator,
|
||||
string catalogType)
|
||||
{
|
||||
bool applied = false;
|
||||
yield return ActorBehaviorAnimatorControllerLoader.ApplyController(catalogType, animator, value => applied = value);
|
||||
if (!applied || actorObject == null || animator == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!avatars.TryGetValue(playerId, out Avatar avatar) || avatar.Obj != actorObject || avatar.Animator != animator)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
avatar.AnimState = null;
|
||||
SetMoveState(avatar, avatar.Moving);
|
||||
}
|
||||
|
||||
private void UpdateActorBehaviorActor(Avatar avatar)
|
||||
|
||||
Reference in New Issue
Block a user