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 CameraMouseZoomSensitivity = 1.4f;
|
||||||
private const float CameraPinchZoomSensitivity = 0.015f;
|
private const float CameraPinchZoomSensitivity = 0.015f;
|
||||||
private const float CameraFollowSharpness = 12f;
|
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, Avatar> avatars = new Dictionary<int, Avatar>();
|
||||||
private readonly Dictionary<int, GameObject> prefabCache = new Dictionary<int, GameObject>();
|
private readonly Dictionary<int, GameObject> prefabCache = new Dictionary<int, GameObject>();
|
||||||
@@ -805,7 +809,11 @@ namespace XGame
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string state = moving ? "Walk" : "Stand";
|
string state = ResolveMoveState(avatar.Animator, moving);
|
||||||
|
if (string.IsNullOrEmpty(state))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (avatar.AnimState == state)
|
if (avatar.AnimState == state)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -814,6 +822,25 @@ namespace XGame
|
|||||||
avatar.Animator.CrossFade(state, 0.1f);
|
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()
|
private void UpdateJoystick()
|
||||||
{
|
{
|
||||||
joystick = Vector2.zero;
|
joystick = Vector2.zero;
|
||||||
@@ -994,6 +1021,43 @@ namespace XGame
|
|||||||
actorBehaviorRuntime.RegisterOrUpdateActor(avatar.PlayerId, avatar.Obj.transform.position, avatar.Obj.transform.forward);
|
actorBehaviorRuntime.RegisterOrUpdateActor(avatar.PlayerId, avatar.Obj.transform.position, avatar.Obj.transform.forward);
|
||||||
actorBehaviorRuntime.SwitchActorCatalog(avatar.PlayerId, LobbyActorBehaviorRuntime.DefaultCatalogType);
|
actorBehaviorRuntime.SwitchActorCatalog(avatar.PlayerId, LobbyActorBehaviorRuntime.DefaultCatalogType);
|
||||||
actorBehaviorPresentation.RegisterActor(avatar.PlayerId, avatar.Animator, avatar.Obj.transform, avatar.Obj.transform);
|
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)
|
private void UpdateActorBehaviorActor(Avatar avatar)
|
||||||
|
|||||||
Reference in New Issue
Block a user