存储功能供以后使用/委托具有未定义的属性
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);
}
注意:在智能手机上打字,但我希望思路清晰
我正在 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);
}
注意:在智能手机上打字,但我希望思路清晰