存储功能供以后使用/委托具有未定义的属性

Store function for later use / delegate with undefined attributes

我正在 Unity 中进行网络项目。以下代码目前正在运行,但它不是最佳的,因为我将不得不一遍又一遍地编写非常相似的代码。我阅读了有关委托、lambdas and/or 命令模式的信息,但我不知道该怎么做。 我想存储一个函数,以便在将网络权限移交给客户端后立即调用它。

以下代码生成一个游戏对象“角”:

public void CornerSpawnRequest(Vector3 spawnPosition, GameObject joinToObject)
{
    NetworkIDRequest.instance.RequestAuthority(GetComponent<NetworkIdentity>());
    StartCoroutine(WaitForSeconds(spawnPosition, joinToObject));    
}

IEnumerator WaitForSeconds(Vector3 spawnPosition, GameObject joinToObject)
{
    yield return new WaitForSeconds(.1f);
    NetworkCornerSpawn(spawnPosition, joinToObject);
}

[Command]
private void NetworkCornerSpawn(Vector3 spawnPosition, GameObject joinToObject)
{
    CornerSpawnExecution(spawnPosition, joinToObject);
}

以下代码是播放器的一部分,方便交接权限。 委托部分目前没有做任何事情,只显示我尝试过的内容:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using System;

public class NetworkIDRequest : NetworkBehaviour
{
//Singleton pattern in void Start().
//I deleted it for Whosebug to optimize readeability

    private void Update()
    {
        //RunWithAuthority();
    }

    public delegate void taskDelegate();

    private taskDelegate clickOnGameObjectDelegate = delegate { };
    public taskDelegate command
    {
        get => clickOnGameObjectDelegate;
        set => clickOnGameObjectDelegate = value;
    }

    public void RequestAuthority(NetworkIdentity identity)
    {
        CmdRequestNetworkAuthority(identity);
    }

    [Command]
    private void CmdRequestNetworkAuthority(NetworkIdentity identity)
    {
        identity.AssignClientAuthority(base.connectionToClient);
    }
}

我想用 class NetworkIDRequest 中的某种委托替换“CornerSpawnRequest()”中的两行,以始终交出我想要请求权限的网络 ID 和一个函数我一有权力就被召唤。该函数应具有未定义数量的属性。这就是为什么我无法找到解决方案的原因。我只知道如何创建具有定义属性的委托。

我希望有人能告诉我如何以可靠且不那么笨拙的方式解决这个问题。 谢谢大家

最佳 比约恩

每当您需要签名未知的委托时,只需将其包装在 Action 中(基本上是一个无参数的 void 委托)

你可能会做类似的事情

// For storing the callback
private Action _whenHaveAuthority;
// For storing the NetworkIdentity that requested authority
// In order to check back later if the event is for us
private NetworkIdentity _identity;

public void RequestAuthority(NetworkIdentity identity, Action whenHaveAuthority)
{
    // Store identity and callback
    _whenHaveAuthority = whenHaveAuthority;
    _identity = identity;
    CmdRequestNetworkAuthority(identity);
}

[Command]
private void CmdRequestNetworkAuthority(NetworkIdentity identity)
{
    identity.AssignClientAuthority(base.connectionToClient);

    Rpc_InformClientHasAuthority(identity);
}

// Server informs all clients 
[ClientRpc]
private void Rpc_InformClientHasAuthority(NetworkIdentity identity)
{
    // Check if we are the one that sent the request
    if(_identity && _identity == identity)
    {
        // Execute the stored callback
        _whenHaveAuthority?.Invoke();

        // and reset
        _identity = null;
        _whenHaveAuthority = null;
    }
}

然后你会传入回调,例如

public void CornerSpawnRequest(Vector3 spawnPosition, GameObject joinToObject)
{
    NetworkIDRequest.instance.RequestAuthority(GetComponent<NetworkIdentity>(), () =>
    {
        NetworkCornerSpawn(spawnPosition, joinToObject);
    });
}

[Command]
private void NetworkCornerSpawn(Vector3 spawnPosition, GameObject joinToObject)
{
    CornerSpawnExecution(spawnPosition, joinToObject);
}

注意:在智能手机上打字,但我希望思路清晰