浏览代码

first pass at action system work

/main
David Woodruff 4 年前
当前提交
a81b6769
共有 18 个文件被更改,包括 349 次插入2 次删除
  1. 2
      Assets/BossRoom/Scripts/Shared/Net/GameNetHub.cs
  2. 89
      Assets/BossRoom/Scripts/Shared/NetworkCharacterState.cs
  3. 8
      Assets/BossRoom/Scripts/Client/Game/Character.meta
  4. 8
      Assets/BossRoom/Scripts/Server/Game/Action.meta
  5. 8
      Assets/BossRoom/Scripts/Server/Game/Character.meta
  6. 8
      Assets/BossRoom/Scripts/Shared/Game/Action.meta
  7. 25
      Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacter.cs
  8. 11
      Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacter.cs.meta
  9. 21
      Assets/BossRoom/Scripts/Server/Game/Action/Action.cs
  10. 11
      Assets/BossRoom/Scripts/Server/Game/Action/Action.cs.meta
  11. 25
      Assets/BossRoom/Scripts/Server/Game/Character/ServerCharacter.cs
  12. 11
      Assets/BossRoom/Scripts/Server/Game/Character/ServerCharacter.cs.meta
  13. 113
      Assets/BossRoom/Scripts/Shared/Game/Action/ActionRequestData.cs
  14. 11
      Assets/BossRoom/Scripts/Shared/Game/Action/ActionRequestData.cs.meta

2
Assets/BossRoom/Scripts/Shared/Net/GameNetHub.cs


/// This synthesizes a general NetworkStart event out of other events provided by MLAPI. This can be removed
/// when the NetworkingManager starts publishing this event directly.
/// </summary>
public event Action NetworkStartEvent;
public event System.Action NetworkStartEvent;
/// <summary>
/// This event contains the game-level results of the ApprovalCheck carried out by the server, and is fired

89
Assets/BossRoom/Scripts/Shared/NetworkCharacterState.cs


using System;
using System.IO;
using MLAPI.Serialization.Pooled;
namespace BossRoom.Shared
namespace BossRoom
/// <summary>
/// Contains all NetworkedVars and RPCs of a character. This component is present on both client and server objects.
/// </summary>

public NetworkedVarFloat NetworkRotationY;
public NetworkedVarFloat NetworkMovementSpeed;
public NetworkedVarInt HitPoints;
public NetworkedVarInt Mana;
/// <summary>
/// Gets invoked when inputs are received from the client which own this networked character.

{
OnReceivedClientInput?.Invoke(movementTarget);
}
// ACTION SYSTEM
/// <summary>
/// This event is raised on the server when an action request arrives, and on the client after the server
/// has broadcast an action play.
/// </summary>
public event Action<BossRoom.ActionRequestData> DoActionEvent;
/// <summary>
/// Client->Server RPC that sends a request to play an action.
/// </summary>
/// <param name="data">Data about which action to play an dits associated details. </param>
public void C2S_DoAction(ref ActionRequestData data)
{
using (PooledBitStream stream = PooledBitStream.Get())
{
SerializeAction(ref data, stream);
InvokeServerRpcPerformance(RecvDoAction, stream);
}
}
/// <summary>
/// Server->Client RPC that broadcasts this action play to all clients.
/// </summary>
/// <param name="data">The data associated with this Action, including what action type it is.</param>
public void S2C_BroadcastAction(ref ActionRequestData data )
{
using (PooledBitStream stream = PooledBitStream.Get())
{
SerializeAction(ref data, stream);
InvokeClientRpcOnEveryonePerformance(RecvDoAction, stream);
}
}
private void SerializeAction( ref ActionRequestData data, PooledBitStream stream )
{
var Logic = ActionDescriptionList.LIST[data.ActionTypeEnum][0].Logic;
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
{
writer.WriteInt16((short)data.ActionTypeEnum);
if (Logic == ActionLogic.RANGED)
{
writer.WriteVector3(data.Direction);
}
if (Logic == ActionLogic.RANGEDTARGETED)
{
writer.WriteIntArray(data.TargetIds);
}
}
}
[ServerRPC, ClientRPC]
private void RecvDoAction(ulong clientId, Stream stream )
{
ActionRequestData data = new ActionRequestData();
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
data.ActionTypeEnum = (Action)reader.ReadInt16();
var Logic = ActionDescriptionList.LIST[data.ActionTypeEnum][0].Logic;
if( Logic == ActionLogic.RANGED )
{
data.Direction = reader.ReadVector3();
}
if( Logic == ActionLogic.RANGEDTARGETED )
{
data.TargetIds = reader.ReadIntArray(data.TargetIds);
}
}
DoActionEvent?.Invoke(data);
}
}
}

8
Assets/BossRoom/Scripts/Client/Game/Character.meta


fileFormatVersion: 2
guid: 70fb5c14d66a3014cae1f19fbca24fae
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/BossRoom/Scripts/Server/Game/Action.meta


fileFormatVersion: 2
guid: 5ec107f53c08ae849aed16f2ecd0b94f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/BossRoom/Scripts/Server/Game/Character.meta


fileFormatVersion: 2
guid: 5ccdcdfae8ab32b41a0f5a51b67c7146
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/BossRoom/Scripts/Shared/Game/Action.meta


fileFormatVersion: 2
guid: 958f00c29aa7c9e4bac124a84266df97
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

25
Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacter.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom.Client
{
[RequireComponent(typeof(BossRoom.Shared.NetworkCharacterState))]
public class ClientCharacter : MLAPI.NetworkedBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
}

11
Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacter.cs.meta


fileFormatVersion: 2
guid: ae9a06a3585027044ababe9f9cb7b8e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

21
Assets/BossRoom/Scripts/Server/Game/Action/Action.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom.Server
{
/// <summary>
/// The abstract parent class that all Actions derive from.
/// </summary>
/// <remarks>
/// The Action System is a generalized mechanism for Characters to "do stuff" in a networked way. Actions
/// include everything from your basic character attack, to a fancy skill like the Archer's Volley Shot, but also
/// include more mundane things like pulling a lever.
/// </remarks>
public abstract class Action
{
}
}

11
Assets/BossRoom/Scripts/Server/Game/Action/Action.cs.meta


fileFormatVersion: 2
guid: f1a0b3549fd35644090b4eb4c57a8e0e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

25
Assets/BossRoom/Scripts/Server/Game/Character/ServerCharacter.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ServerCharacter : MLAPI.NetworkedBehaviour
{
// Start is called before the first frame update
void Start()
{
}
public override void NetworkStart()
{
if( !IsServer ) { this.enabled = false; }
}
// Update is called once per frame
void Update()
{
}
}

11
Assets/BossRoom/Scripts/Server/Game/Character/ServerCharacter.cs.meta


fileFormatVersion: 2
guid: 920a440eb254ba348915767fd046027a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

113
Assets/BossRoom/Scripts/Shared/Game/Action/ActionRequestData.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom
{
/// <summary>
/// List of all Actions supported in the game.
/// </summary>
public enum Action
{
TANK_BASEATTACK,
ARCHER_BASEATTACK,
}
/// <summary>
/// List of all Types of Actions. There is a many-to-one mapping of Actions to ActionLogics.
/// </summary>
public enum ActionLogic
{
MELEE,
RANGED,
RANGEDTARGETED,
}
/// <summary>
/// FIXME: ??? This will be turned into a ScriptableObject.
/// </summary>
public class ActionDescription
{
/// <summary>
/// ActionLogic that drives this Action. This corresponds to the actual block of code that executes it.
/// </summary>
public ActionLogic Logic;
/// <summary>
/// Could be damage, could be healing, or other things. This is a base, nominal value that will get modified
/// by game logic when the action takes effect.
/// </summary>
public int Amount;
/// <summary>
/// How much it consts in Mana to play this Action.
/// </summary>
public int ManaCost;
/// <summary>
/// How how the Action performer can be from the Target, or how far the action can go (for an untargeted action like a bowshot).
/// </summary>
public float Range;
/// <summary>
/// Duration in seconds that this Action takes to play.
/// </summary>
public float Duration_s;
/// <summary>
/// How long the effect this Action leaves behind will last, in seconds.
/// </summary>
public float EffectDuration_s;
/// <summary>
/// The primary Animation action that gets played when visualizing this Action.
/// </summary>
public string Anim;
}
/// <summary>
/// FIXME: this list will be turned into a collection of Scriptable Objects.
/// Question: Do we want to show how to do skill levels, as I am doing here?
/// </summary>
public class ActionDescriptionList
{
public static Dictionary<Action, List<ActionDescription>> LIST = new Dictionary<Action, List<ActionDescription>>
{
{ Action.TANK_BASEATTACK , new List<ActionDescription>
{
{new ActionDescription{Logic=ActionLogic.MELEE, Amount=10, ManaCost=2, Duration_s=0.5f, Anim="Todo" } }, //level 1
{new ActionDescription{Logic=ActionLogic.MELEE, Amount=15, ManaCost=2, Duration_s=0.5f, Anim="Todo" } }, //level 2
{new ActionDescription{Logic=ActionLogic.MELEE, Amount=20, ManaCost=2, Duration_s=0.5f, Anim="Todo" } }, //level 3
}
},
{ Action.ARCHER_BASEATTACK, new List<ActionDescription>
{
{new ActionDescription{Logic=ActionLogic.RANGED, Amount=7, ManaCost=2, Duration_s=0.5f, Range=12f, Anim="Todo" } }, //Level 1
{new ActionDescription{Logic=ActionLogic.RANGED, Amount=12, ManaCost=2, Duration_s=0.5f, Range=15f, Anim="Todo" } }, //Level 2
{new ActionDescription{Logic=ActionLogic.RANGED, Amount=15, ManaCost=2, Duration_s=0.5f, Range=18f, Anim="Todo" } }, //Level 3
}
}
};
}
/// <summary>
/// Comprehensive class that contains information needed to play back any action on the server. This is what gets sent client->server when
/// the Action gets played, and also what gets sent server->client to broadcast the action event. Note that the OUTCOMES of the action effect
/// don't ride along with this object when it is broadcast to clients; that information is sync'd separately, usually by NetworkedVars.
/// </summary>
public struct ActionRequestData
{
public Action ActionTypeEnum; //the action to play.
public Vector3 Position; //center position of skill, e.g. "ground zero" of a fireball skill.
public Vector3 Direction; //direction of skill, if not inferrable from the character's current facing.
public int[] TargetIds; //networkIds of targets, or null if untargeted.
int Level; //what level the Action plays at (server->client only).
}
}

11
Assets/BossRoom/Scripts/Shared/Game/Action/ActionRequestData.cs.meta


fileFormatVersion: 2
guid: fa0d0ef458748aa49a30b1900b4a995e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存