簡単なマルチプレイヤーの例を作成しようとしています。2Dで試しても3Dで試しても結果は同じです。私はそれを3Dで説明しますが、それは私が少なくとも試したものです. シーンとボールに 2 つの円柱を追加するだけです。各プレーヤーが自分のプレーヤーを制御できるように、プレーヤー コントローラー用のスクリプトをセットアップしました。Network トランスフォームを追加し、ネットワーク ID を Player プレハブのローカル playre 権限に設定し、いくつかのチュートリアルで説明したことをすべて実行しました。
思考は期待どおりに機能しています。ホスト上で、私はボールと他のプレーヤーと衝突することができます.バウンドするマテリアルを追加した後、ボールはプレーヤーから跳ね返り、他のプレーヤーも跳ね返ります。(発射ボタンにブーストを追加しました) 衝突はプログラムせず、物理エンジンに任せました。問題はクライアント側にあり、ボールはある種のスティッキーのように振る舞います。プレイヤーがバウンスせず、グリッチがあり、正しく動作しません。
私は衝突検出ディスクリート - 連続 - 補間あり、なし、または外挿の連続ダイナミクスとのすべての組み合わせを試しました。Player and Ball と Player/Player の組み合わせ。
ネットワーク設定で別の組み合わせも試しましたが、何も役に立ちません。
スクリーンショットをいくつか追加して、私がやろうとしていることと設定をよりよく理解できるようにします.
質問は: pyhics エンジンをネットワークと組み合わせて、私がやりたいことを実行できるか、またはより良い方法は: . キーボードからの入力をキャッチしてサーバーに送信し、そこで移動してグラフィックのみを同期することを考えています。(私の言いたいことが理解できるといいのですが)
プレーヤーの剛体
[編集] ボールとプレーヤーの間のすべての組み合わせで、5 ~ 100 のスナップしきい値を試しました。Rigidbody は、ボール上で同じように見えます (質量を除く)。ボールの質量は 0.5 です。Player はプレハブなので、すべての Player は同じ物理特性を持っています。また、ゲームの物理、特にバウンスのしきい値をいじってみましたが、役に立ちませんでした。
プレーヤー スクリプト:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class PlayerController : NetworkBehaviour
{
public float movmentForce = 75;
public float accelerationOnFire;
public GameObject ball;
public float fireRate = 0.5F;
private float nextFire = 0.0F;
private Rigidbody rbPlayer;
// Use this for initialization
void Start()
{
Vector3 pos;
Quaternion q;
pos.x = 0;
pos.y = 1;
pos.z = 10;
transform.position = pos;
rbPlayer = GetComponent<Rigidbody>();
ball = GameObject.FindGameObjectWithTag("Ball");
}
// Update is called once per frame
void Update()
{
if (!isLocalPlayer)
return;
float inputHorizontal = CrossPlatformInputManager.GetAxis("Horizontal");
float inputVertical = CrossPlatformInputManager.GetAxis("Vertical");
// float inputHorizontal = Input.GetAxis("Horizontal");
// float inputVertical = Input.GetAxis("Vertical");
if (inputHorizontal != 0)
{
rbPlayer.AddForce(Vector3.right * movmentForce * inputHorizontal, ForceMode.Force);
}
if (inputVertical != 0)
{
rbPlayer.AddForce(Vector3.forward * movmentForce * inputVertical, ForceMode.Force);
}
if (CrossPlatformInputManager.GetButton("Fire1") && Time.time > nextFire)
// if (Input.GetButton("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
rbPlayer.AddForce(transform.forward * -accelerationOnFire, ForceMode.Force);
}
Vector3 pos = transform.position;
pos.y += 10;
Camera.main.transform.position = pos;
}
void FixedUpdate()
{
if (!isLocalPlayer)
return;
if (ball)
{
Vector3 dir = ball.transform.position - rbPlayer.transform.position;
float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
rbPlayer.transform.rotation = Quaternion.AngleAxis(angle, Vector3.up);
rbPlayer.transform.Rotate(0, 180, 0);
}
else
{
ball = GameObject.FindGameObjectWithTag("Ball");
}
}
}
ボールスポナー
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class BallSpawn : NetworkBehaviour
{
public GameObject ballPrefab;
// Use this for initialization
public override void OnStartServer()
{
SpawnBall();
}
void SpawnBall()
{
GameObject myBall = Instantiate<GameObject>(ballPrefab);//, Vector2.zero, Quaternion.identity);
NetworkServer.Spawn(myBall);
myBall.tag = "Ball";
}
}
ゲーム物理学