Unity Mirror Multiplayer RTS,客户端忽略 hasAuthority 检查

问题描述

我正在使用镜像开发 RTS 游戏,但遇到了问题。 我正在研究单位的自动攻击功能。 一切都适用于主机,但不适用于客户端。 任何帮助将不胜感激,我已经在这几天了.. 帮助! 或者至少在这里指出我正确的方向。 稍后我会更好地优化它,我只需要了解为什么它在客户端上不起作用。我还注意到客户端会将自己添加到敌人列表中,它似乎忽略了“hasAuthority”检查

写的有点多,所以我会尽量让它更容易理解。

Unit 被实例化,这是附加到它的脚本:

import 'firebase/analytics'

接下来是ArrayDetect函数 使用 Physics.OverlapSphere 检测单元,确保它具有权限并将其添加到敌人对撞机列表中,我还添加了 layerMask 以确保它仅检查单元。

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;

现在AttackUnit函数,它会考虑敌人的碰撞器列表并将它们设置为攻击目标

[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);
                }
            
        }
    }

这是 Targetable Script,它只是返回 aimAtPoint:

[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

    }    
}

这是 Targeter 脚本中的 CmdsetTarget 命令:

public class Targetable : NetworkBehavIoUr
{
    [Serializefield] private Transform aimAtPoint = null;

    public Transform GetaimAtPoint()
    {
        return aimAtPoint;
    }
}

这是我在控制台中得到的错误,但只有在客户端单元上,主机才能正常运行:

[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;
    }

感谢您花时间阅读本文

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...