c# - Unity Mirror Multiplayer RTS,客户端忽略 hasAuthority 检查
问题描述
我正在使用镜像开发 RTS 游戏并遇到问题。我正在研究单位的自动攻击功能。一切都适用于主机,但不适用于客户端。任何帮助将不胜感激,我已经在这几天了..帮助!或者至少在这里为我指明正确的方向。稍后我将对此进行更好的优化,我只需要了解为什么它在客户端上不起作用。我还注意到客户端会将自己添加到敌人列表中,它似乎忽略了“hasAuthority”检查
这有点写,所以我会尽量让它尽可能容易理解。
单元被实例化,这是附加到它的脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using System.Linq;
public class UnitFiring : NetworkBehaviour
{
[SerializeField] private Targeter targeter = null;
[SerializeField] private GameObject projectilePrefab = null;
[SerializeField] private Transform projectileSpawnPoint = null;
[SerializeField] private float fireRange = 10f;
[SerializeField] private float fireRate = 1f;
[SerializeField] private float rotationSpeed = 20f;
private float lastFireTime;
//auto attack
[SerializeField] private Transform ownAimAtPoint = null;
[SerializeField] private LayerMask layerMask;
[SerializeField] private int updateFunctionFrequency = 60; //in frames
[ServerCallback]
private void Update()
{
if (Time.frameCount % this.updateFunctionFrequency != 0) return;
//runs update every 60 frames
enemyColliders.RemoveAll(Collider => Collider == null);
//if enemyCollider List has GameObject that was destroyed or null, it removes it from the list.
Targetable target = targeter.GetTarget();
if(target == null)
{
ArrayDetect();
AttackUnit();
return;
}
if (!CanFireAtTarget()) { return; }
//look at target
Quaternion targetRotation =
Quaternion.LookRotation(target.transform.position - transform.position);
//Rotate
transform.rotation = Quaternion.RotateTowards
(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
if(Time.time > (1 / fireRate) +lastFireTime)
{
Quaternion projectileRotation = Quaternion.LookRotation(
target.GetAimAtPoint().position - projectileSpawnPoint.position);
GameObject projectileInstance = Instantiate(
projectilePrefab, projectileSpawnPoint.position, projectileRotation);
NetworkServer.Spawn(projectileInstance, connectionToClient);
lastFireTime = Time.time;
}
}
[Client]
private bool CanFireAtTarget()
{
return (targeter.GetTarget().transform.position - transform.position).sqrMagnitude
<= fireRange * fireRange;
}
[SerializeField] private Collider[] colliderArray;
[SerializeField] private List<GameObject> enemyColliders;
接下来是带有 Physics.OverlapSphere 的 ArrayDetect 功能检测单元,确保它具有权限并将其添加到enemyCollider 列表中,我还添加了 layerMask 以确保它只检查单元。
[Server]
private void ArrayDetect()
{
colliderArray = Physics.OverlapSphere(ownAimAtPoint.position, fireRange, layerMask);
foreach (Collider collider in colliderArray)
{
Debug.Log("we hit a", collider);
if (!collider.TryGetComponent<Targetable>(out Targetable potentialTarget))
{
return;
}
if (potentialTarget.hasAuthority)
{
return; //if the hit target is the players, do nothing
}
else
{
enemyColliders = enemyColliders.Distinct().ToList();
enemyColliders.Add(collider.gameObject);
Debug.Log("Found an enemy", potentialTarget);
}
}
}
现在 AttackUnit 函数,它会去考虑enemyColliders List 并将它们设置为攻击目标
[ServerCallback]
private void AttackUnit()
{
foreach (GameObject enemy in enemyColliders)
{
Debug.Log("We got confirmed enemy", enemy);
//GetComponent<Targeter>().CmdSetTarget(enemy);
targeter.CmdSetTarget(enemy);
//attack the enemy
}
}
这是 Targetable Script,它只返回 AimAtPoint:
public class Targetable : NetworkBehaviour
{
[SerializeField] private Transform aimAtPoint = null;
public Transform GetAimAtPoint()
{
return aimAtPoint;
}
}
这是 Targeter 脚本中的 CmdSetTarget 命令:
[Command]
public void CmdSetTarget(GameObject targetGameObject)
{
if(!targetGameObject.TryGetComponent<Targetable>(out Targetable newTarget)) { return; }
//if game object does not have a target, return
target = newTarget;
}
这是我在控制台中遇到的错误,但仅在客户端单元上,主机按应有的方式运行:
Trying to send command for object without authority. Targeter.CmdSetTarget
感谢您花时间阅读本文
解决方案
推荐阅读
- apache-spark - 如何使用 Spark 数据集和 UDF 分析类型不匹配错误
- c++ - C++ 字符串到 wstring 打印不正确,无法获取 unicode 路径
- vb6 - 在 vb6 中卸载动态创建的标签时出错
- mainframe - 在 IBM z 中是否有像 IBM i 中的显示文件 (dspf)?
- java - 我用Gradle插件编译Java代码的时候,本地JDK是1.8的,但是我想编译成1.7版本
- java - 请求在 chrome 中待处理
- javascript - Confluence “Hello World” 宏帮助 - NPM 安装/启动不工作
- r - 向量化嵌套 ifelse
- json - chatfuel Json api插件上的消息数组问题:仅发送文本对象但不发送模板
- java - 我的代码中没有生成 DaggerApplicationComponent?