feat: trigger fighter behavior from lobby action button
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using XWorld.Framework.ActorBehavior;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace XGame.ActorBehavior
|
||||
{
|
||||
public static class ActorBehaviorConfigLoader
|
||||
{
|
||||
public const string ConfigRoot = "Assets/Game/Config/ActorBehavior";
|
||||
|
||||
public static IEnumerator LoadCatalog(string type, Action<BehaviorConfigCatalog> onLoaded)
|
||||
{
|
||||
string skillJson = null;
|
||||
string flyObjectJson = null;
|
||||
string buffJson = null;
|
||||
|
||||
yield return LoadText(GetSkillPath(type), text => skillJson = text);
|
||||
yield return LoadText(GetFlyObjectPath(type), text => flyObjectJson = text);
|
||||
yield return LoadText(GetBuffPath(type), text => buffJson = text);
|
||||
|
||||
if (string.IsNullOrEmpty(skillJson) || string.IsNullOrEmpty(flyObjectJson) || string.IsNullOrEmpty(buffJson))
|
||||
{
|
||||
Debug.LogError("[ActorBehaviorConfigLoader] missing behavior config for type=" + type);
|
||||
onLoaded?.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
onLoaded?.Invoke(BehaviorConfigCatalog.LoadFromJson(type, skillJson, flyObjectJson, buffJson));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError("[ActorBehaviorConfigLoader] parse behavior config failed type=" + type + ", error=" + ex.Message);
|
||||
onLoaded?.Invoke(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetSkillPath(string type)
|
||||
{
|
||||
return ConfigRoot + "/" + type + "_skill.json";
|
||||
}
|
||||
|
||||
public static string GetFlyObjectPath(string type)
|
||||
{
|
||||
return ConfigRoot + "/" + type + "_flyobj.json";
|
||||
}
|
||||
|
||||
public static string GetBuffPath(string type)
|
||||
{
|
||||
return ConfigRoot + "/" + type + "_buff.json";
|
||||
}
|
||||
|
||||
private static IEnumerator LoadText(string assetPath, Action<string> onLoaded)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
TextAsset asset = AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath);
|
||||
if (asset != null)
|
||||
{
|
||||
onLoaded?.Invoke(asset.text);
|
||||
yield break;
|
||||
}
|
||||
#endif
|
||||
|
||||
string filePath = Path.Combine(Application.dataPath, assetPath.StartsWith("Assets/", StringComparison.Ordinal)
|
||||
? assetPath.Substring("Assets/".Length)
|
||||
: assetPath);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
onLoaded?.Invoke(File.ReadAllText(filePath, Encoding.UTF8));
|
||||
yield break;
|
||||
}
|
||||
|
||||
byte[] bytes = null;
|
||||
string runtimePath = assetPath.StartsWith("Assets/", StringComparison.Ordinal)
|
||||
? assetPath.Substring("Assets/".Length)
|
||||
: assetPath;
|
||||
yield return XResLoader.coLoadFile(runtimePath, data => bytes = data);
|
||||
onLoaded?.Invoke(bytes != null ? Encoding.UTF8.GetString(bytes) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 749877ee582c42058dfc794500488f28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,114 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using XGame.VirtualInput;
|
||||
using XWorld.Framework.ActorBehavior;
|
||||
|
||||
namespace XGame.ActorBehavior
|
||||
{
|
||||
public sealed class LobbyActorBehaviorRuntime
|
||||
{
|
||||
public const string DefaultCatalogType = "fighter";
|
||||
public const string SecondaryABehaviorId = "quantao01";
|
||||
public const ActionButtonId SecondaryAButtonId = ActionButtonId.Skill1;
|
||||
|
||||
private readonly BehaviorWorld world = new BehaviorWorld(new BehaviorWorldOptions
|
||||
{
|
||||
Mode = BehaviorRunMode.ClientPresentation
|
||||
});
|
||||
|
||||
public void RegisterCatalog(BehaviorConfigCatalog catalog)
|
||||
{
|
||||
world.RegisterCatalog(catalog);
|
||||
}
|
||||
|
||||
public bool SwitchActorCatalog(int actorId, string catalogType)
|
||||
{
|
||||
return world.SwitchActorCatalog(actorId, catalogType);
|
||||
}
|
||||
|
||||
public bool RemoveActor(int actorId)
|
||||
{
|
||||
return world.RemoveActor(actorId);
|
||||
}
|
||||
|
||||
public void RegisterOrUpdateActor(int actorId, Vector3 position, Vector3 forward)
|
||||
{
|
||||
world.AddActor(new BehaviorActorState
|
||||
{
|
||||
ActorId = actorId,
|
||||
CatalogType = DefaultCatalogType,
|
||||
TeamId = actorId,
|
||||
Position = ToBehavior(position),
|
||||
Forward = ToBehaviorForward(forward),
|
||||
Radius = 0.5f,
|
||||
Alive = true
|
||||
});
|
||||
}
|
||||
|
||||
public BehaviorStartResult HandleActionButton(ActionButtonEvent evt, int actorId, Vector3 fallbackForward)
|
||||
{
|
||||
if (!IsSecondaryATrigger(evt))
|
||||
{
|
||||
return BehaviorStartResult.Fail("button ignored");
|
||||
}
|
||||
|
||||
BehaviorInput input = CreateDirectionInput(evt, fallbackForward);
|
||||
return world.TryStartBehavior(actorId, SecondaryABehaviorId, input);
|
||||
}
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
{
|
||||
world.Tick(deltaTime);
|
||||
}
|
||||
|
||||
public IReadOnlyList<BehaviorEvent> DrainEvents()
|
||||
{
|
||||
return world.DrainEvents();
|
||||
}
|
||||
|
||||
public bool HasActiveBehavior(int actorId)
|
||||
{
|
||||
return world.HasActiveBehavior(actorId);
|
||||
}
|
||||
|
||||
public static bool IsSecondaryATrigger(ActionButtonEvent evt)
|
||||
{
|
||||
return evt.ButtonId == SecondaryAButtonId
|
||||
&& !evt.IsCanceled
|
||||
&& evt.Phase == ActionButtonPhase.Tap;
|
||||
}
|
||||
|
||||
private static BehaviorInput CreateDirectionInput(ActionButtonEvent evt, Vector3 fallbackForward)
|
||||
{
|
||||
Vector2 direction = evt.Direction;
|
||||
if (direction.sqrMagnitude > 0.0001f)
|
||||
{
|
||||
return BehaviorInput.FromDirection(direction.x, direction.y);
|
||||
}
|
||||
|
||||
fallbackForward.y = 0f;
|
||||
if (fallbackForward.sqrMagnitude <= 0.0001f)
|
||||
{
|
||||
fallbackForward = Vector3.forward;
|
||||
}
|
||||
fallbackForward.Normalize();
|
||||
return BehaviorInput.FromDirection(fallbackForward.x, fallbackForward.z);
|
||||
}
|
||||
|
||||
private static BehaviorVector3 ToBehavior(Vector3 value)
|
||||
{
|
||||
return new BehaviorVector3(value.x, value.y, value.z);
|
||||
}
|
||||
|
||||
private static BehaviorVector3 ToBehaviorForward(Vector3 value)
|
||||
{
|
||||
value.y = 0f;
|
||||
if (value.sqrMagnitude <= 0.0001f)
|
||||
{
|
||||
value = Vector3.forward;
|
||||
}
|
||||
value.Normalize();
|
||||
return new BehaviorVector3(value.x, 0f, value.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f25b35931c34b66982c41c5fd329fe2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user