我正在使用多人射击游戏,到目前为止,我的网络机芯和武器拾音系统都在工作。武器脚本适用于单人游戏,现在我必须将其移植到多人游戏中。这是所有与问题相关的代码:
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]函数(例如)。问题是我无法在PlayerController
或MonoBehaviour
脚本中执行此操作,因为它们必须是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
。我想这样,因为会有战斗物品不会产生弹丸......