Многопользовательский сценарий появления пули Unity

Я работаю над многопользовательским шутером, и до сих пор у меня работали сетевые системы перемещения и захвата оружия. Скрипт оружия работает в одиночной игре, и теперь я должен перенести его в многопользовательский режим. Вот весь код, связанный с проблемой:

PlayerController.cs:

using UnityEngine;
using System.Collections;
using System;

public class PlayerController : MonoBehaviour
{

    [SerializeField]
    private float Speed;
    public bool OnGamepad = false;
    private bool OnPrimary = true;

    private Vector3 MoveData = Vector3.zero;
    private Rigidbody PlayerRB;
    public Camera PlayerCam;
    public Transform gunOrigin;
    public CombatItem Primary;
    public CombatItem Secondary;

    void Start()
    {

        PlayerRB = GetComponent<Rigidbody>();
        PlayerCam = Instantiate(PlayerCam, transform.position, transform.rotation) as Camera;
        PlayerCam.GetComponent<CameraControl>().target = transform;
        PlayerCam.transform.parent = transform.parent;
    }

    void FixedUpdate ()
    {
        gameObject.SetActive(true);
        checkConrolMethod();
        Move();
        if (OnPrimary && Primary != null) Action1(Primary);
        else if(!OnPrimary && Secondary != null) Action1(Secondary);
        if (OnGamepad)
        {
            GamepadRotate(); 
        }
        else
        {
            Rotate();             
        }                                     
    }   

    void Move()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float z = Input.GetAxisRaw("Vertical");

        MoveData.Set(x, 0f, z);
        MoveData = MoveData.normalized * Speed;
        PlayerRB.MovePosition(PlayerRB.position + MoveData * Time.deltaTime);
    }

    void Rotate()
    {
        Ray camRay = PlayerCam.ScreenPointToRay(Input.mousePosition);
        Plane floor = new Plane(Vector3.up, Vector3.zero);
        float rayL;

        if (floor.Raycast(camRay, out rayL))
        {
            Vector3 lookPoint = camRay.GetPoint(rayL);
            transform.LookAt(new Vector3(lookPoint.x, transform.position.y, lookPoint.z));
        }
    }

    void GamepadRotate()
    {
        Vector3 direction = Vector3.right * Input.GetAxisRaw("GPLookHorizontal")
                          + Vector3.forward * -Input.GetAxisRaw("GPLookVertical");
        if(direction.sqrMagnitude > 0.0f)
        {
            transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
        }
    }

    void checkConrolMethod()
    {
        if (Input.GetJoystickNames().Length != 0)
            OnGamepad = true;
        if (Input.GetAxisRaw("Fire") != 0
            || Input.GetAxisRaw("Mouse X") != 0
            || Input.GetAxisRaw("Mouse X") != 0)
            OnGamepad = false;
    }

    void OnCollisionEnter(Collision c)
    {
        if(c.gameObject.tag == "Bullet")
        {
            transform.position = new Vector3(0, transform.position.y, 0);
        }
        else if(c.gameObject.tag == "CombatItem")
        {           
            PickUp(c.gameObject);
        }
    }

    void PickUp(GameObject g)
    {
        g.transform.parent = transform;
        g.transform.position = gunOrigin.transform.position;
        g.transform.rotation = gunOrigin.transform.rotation;
        CombatItem c = g.GetComponent<CombatItem>();
        c.equiped = true;
        if (OnPrimary) Primary = c;
        else Secondary = c;
    }

    void Action1(CombatItem c)
    {
        if (Input.GetAxisRaw("Fire") != 0 || Input.GetAxisRaw("GPFire") == -1) c.Action1(true);   
        else c.Action1(false);
    }                                                                     


    void OnDestroy()
    {
        PlayerCam.GetComponent<CameraControl>().enabled = false;
    }
}

CombatItem.cs:

using UnityEngine;
using System.Collections;

public class CombatItem : MonoBehaviour
{
    public bool equiped = false;

    public virtual void Action1(bool on){}
    public virtual void Action2(bool on){}
}
GunContoller.cs:

using UnityEngine;
using System.Collections;
using System;

public class GunController : CombatItem
{                                       
    [SerializeField]
    Transform Origin;
    [SerializeField]
    Bullet b;               

    float ROFCountDown;
    float TimeBetweenShots;
    public float RateOfFire;
    bool SingleShot;
    bool IsFiring;       

    void Start()
    {
        TimeBetweenShots = 60 / RateOfFire;
    }

    void Update()
    {
        Fire();                             
    }

    public void Fire()
    {
        ROFCountDown -= Time.deltaTime;
        if (IsFiring)
        {
            if (ROFCountDown <= 0)
            {
                ROFCountDown = TimeBetweenShots;
                Bullet newBullet = Instantiate(b, Origin.position, Origin.rotation) as Bullet;
            }
        }       
    }

    public override void Action1(bool on)
    {
        IsFiring = on;
    }

    public override void Action2(bool on)
    {

    }
}

и Bullet.cs:

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour
{

    public float Speed;
    public float Range;
    Vector3 initPosition;

    void Start()
    {
        initPosition = transform.position; 
    }

    void FixedUpdate()
    {
        transform.Translate(Vector3.forward * Speed * Time.deltaTime);
        if (Vector3.Distance(transform.position, initPosition) > Range)
        {
            Destroy(this.gameObject);
        }
    }
}

Итак, быстрое подведение итогов того, что происходит. CombatItem это класс, который предоставляет сценарию игрока возможность взаимодействовать с несколькими видами... хороших боевых предметов - оружия, гранат, оружия ближнего боя, флага CTF, если я доберусь до этого, и т. д. Оттуда каждый тип боевого предмета наследует этот класс и использует Action1() а также Action2() чтобы вызвать функциональность CombatItem, который реализован в каждом CombatItem учебный класс.

Здесь проблема. Чтобы я мог вызвать пулю, мне нужно отправить функцию [Command], содержащую NetworkServer.Spawn(bulletGameObject) (например). Проблема в том, что я не могу сделать это в GunController или PlayerController сценарии, так как они есть и должны быть MonoBehaviour (этот код должен использоваться и в одиночной игре). Мне нужен способ порождения пули "вне" этого кода. Надеюсь, я объяснил это достаточно правильно.......

Все префабы, связанные с этими сценариями, были правильно настроены с использованием сетевых идентификаторов и преобразований и были добавлены в список зарегистрированных префабов. Я понимаю, что для появления пули мне нужно NetworkServer.Spawn(), который требует gameObject с полномочиями клиента для правильного появления. Я просто не могу понять, как получить доступ к новому экземпляру маркера из вторичного скрипта (возможно, привязанного к префабу плеера).

РЕДАКТИРОВАТЬ: Это что-то близко к тому, что мне нужно, имейте в виду, что это в основном своего рода псевдокод

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class NetGun : NetworkBehaviour {

    [SerializeField]
    GunController GC;


    void Start ()
    {

    }

    void Update ()
    {
       if(GC.equiped)
        {
            this.GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
        }

        CmdSpawnBullet();
    }

    [Command]
    void CmdSpawnBullet()
    {
        if (GC.Fire() != null)
        {
            NetworkServer.Spawn(GC.Fire());
        }
    }
}

Как я уже сказал, этот код не функционален, он должен объяснить ситуацию немного лучше. Я хочу, чтобы пистолет мог порождать пулю в NetworkBehaviour сценарий отдельно от GunController, Я так хочу, потому что будут боевые предметы, которые не порождают снаряды...

0 ответов

Другие вопросы по тегам