2016-06-27 3 views
1

私のゲームのクライアントがアイテムを購入し、それらのアイテムをネットワークから作り出すことを許可しようとしています。これを行うために、私は2つのスクリプト、プレーヤー上のスクリプトとアイテム購入ボタン上のスクリプトを使用しています。 NetworkServer.Spawn()はサーバー上でしか呼び出せないことを知っていますので、アイテムスクリプトを購入する代わりにアイテムを生成するためにプレーヤースクリプトにコマンド関数を作成しました。しかし、この回避策を使用すると、NullReferenceExceptionエラーが渡された引数がnullであると表示されます。なぜ引数がnullですか?クライアントからサーバーに送信されたときに引数がnullになりました

購入アイテムのスクリプトコード:

void BuyItemAndSubtractGold(){ 
    GameObject item = SearchForItem(); 
    int cost = item.GetComponent<ItemManager_ItemStats>().item.buyValue; 
    if (item.GetComponent<ItemManager_ItemStats>() != null && storeMaster.gold >= cost) { 
     GameObject newItem = (GameObject)Instantiate (item); 
     playerMaster.CmdSpawnOnServer (newItem); 
     newItem.transform.parent = playerInventory.transform; 
     newItem.SetActive (false); 
     Vector3 gunPosition = newItem.GetComponent<ItemManager_ItemPickup>().gunPositions [0]; 
     newItem.transform.localPosition = gunPosition; 
     newItem.transform.rotation = Quaternion.Euler(itemThrow.originalRotation); 
     storeMaster.gold -= cost; 
     audioSource.clip = boughtItem; 
     audioSource.Play(); 
     storeMaster.CallEventUpdateUI(); 
     sellInventory.LoadInventory(); 
     playerMaster.CmdCallEventInventoryChanged(); 
    } else { 
     noGold.SetActive (true); 
     StartCoroutine (wait5sec()); 
    } 
} 

Playerのスクリプトコード:エラー enter image description here

+1

あなたは、システムが 'NetworkIdentity'コンポーネントを探して行くとき' NullReferenceException'が発生気づくことがあります。あなたがクライアント/サーバーアーキテクチャを回避しようとしているように私には見えますが、それは良いアプローチではないかもしれません。チュートリアルをチェックすることをお勧めします。 – rutter

+0

@rutter良いチュートリアルをお勧めしますか? –

答えて

1

[Command] 
public void CmdSpawnOnServer(GameObject item){ 
    print (item != null); 
    NetworkServer.Spawn (item); 
} 

ピクチャーあなたはコマンドでゲームオブジェクトを送信しようとしているように思えます。 command、clientrpc、およびsyncvarを介して送信できる引数は、特定の型に限定されており、gameobjectはそのようなものではないようです。これを行う代わりに、サポートされている型(intなど)を使用して項目IDを指定するか、ユーザー定義の値型(struct)を作成することができます。渡されたときに引数がnullになるのは、コマンドがゲームオブジェクトを引数としてサポートしていないためです。したがって、エラーを解決するには、サポートされている型を介して値を送信する必要があります。たとえば、アイテムgameObjectの配列を含むクラスを作成し、目的のゲームオブジェクトのインデックスを指定する整数を使用してコマンドを送信することができます。送信された整数値を使用して、目的のアイテムgameObjectを取得します。有効なタイプの

詳しい情報はこちら: http://answers.unity3d.com/questions/1001474/unet-parameter-restrictions-for-command-and-client.html

+0

検索する整数を使用するgameobjectsがクライアントとサーバーの両方に存在することを確認するのに、syncvarsを使用する必要はありませんか? –

+0

私が提供したリンクのメソッドを使用すると、networkIDは正常に送信されましたが、ClientScene.FindLocalObject(itemID)またはNetworkServer.FindLocalObject(itemID)でgameobjectにアクセスしようとするたびにnull参照例外が発生します。 –

+0

あなたの最初のコメントに答えて - いいえ、あなたはしません。 gameオブジェクトの項目を含む配列を持つスクリプトを(クライアントとサーバーの両方のビルドで)保持することができます。これはサーバービルドとクライアントビルドの両方で行われるため(リストスクリプトが添付された空のgameobjectである可能性があります)、アイテムがクライアントとサーバーに存在するかどうかを確認する必要はありません。武器がゲームプレイを通じて動的に作成された場合(これはそうではない可能性があります - この場合は、より多くのデータを送信したり、ユーザー定義の構造体を使用することができます)。 – user3210251

関連する問題