Unity多人子弹产生脚本

时间:2017-01-04 00:28:39

标签: c# networking unity3d spawning

我正在使用多人射击游戏,到目前为止,我的网络机芯和武器拾音系统都在工作。武器脚本适用于单人游戏,现在我必须将其移植到多人游戏中。这是所有与问题相关的代码:

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在每个NetworkServer.Spawn(bulletGameObject)类中实现。

这就是问题所在。为了让我生成子弹,我需要发送一个包含GunController的[Command]函数(例如)。问题是我无法在PlayerControllerMonoBehaviour脚本中执行此操作,因为它们必须是NetworkServer.Spawn()(此代码将用于单个 - 球员也是)。我需要一种方法来产生子弹&#34;外面&#34;这段代码。我希望我能够恰当地解释这个.......

与这些脚本关联的所有预制件都已正确设置了网络标识和转换,并已添加到已注册的预制件列表中。我不认为为了产生子弹,我需要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()); } } } ,这需要具有客户端权限的gameObject才能正确生成它。我无法弄清楚如何从辅助脚本访问新的子弹实例(可能附加到播放器预制件)。

编辑:这是我需要的东西,请记住它主要是有点伪代码

NetworkBehaviour

就像我说的那样,这段代码不起作用,它可以更好地解释一下情况。我希望枪能够在GunController脚本中生成一个子弹而不是mkdir _build pushd _build cmake.exe .. cmake --build . popd 。我想这样,因为会有战斗物品不会产生弹丸......

0 个答案:

没有答案