mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-17 18:40:33 +00:00
fix: Updated PickupsDropsChilds example
- Renamed prefabs - adjusted offsets to object prefabs - fixed orientation of RightHand on Custom Robot Kyle - Added spawn points to scene - Improved and simplified code
This commit is contained in:
parent
cc9cc4280b
commit
13bc00cfde
@ -191,15 +191,16 @@ MonoBehaviour:
|
||||
offlineSceneLoadDelay: 0
|
||||
transport: {fileID: 94711025}
|
||||
networkAddress: localhost
|
||||
maxConnections: 100
|
||||
maxConnections: 2
|
||||
disconnectInactiveConnections: 0
|
||||
disconnectInactiveTimeout: 60
|
||||
authenticator: {fileID: 0}
|
||||
playerPrefab: {fileID: 7267698107325001584, guid: 0a718236edc07af46a9f3ebb74fd1e45,
|
||||
type: 3}
|
||||
autoCreatePlayer: 1
|
||||
playerSpawnMethod: 0
|
||||
spawnPrefabs: []
|
||||
playerSpawnMethod: 1
|
||||
spawnPrefabs:
|
||||
- {fileID: 8373046805013990044, guid: 41c6c51270a8bab40b39ca7962e9ac6c, type: 3}
|
||||
exceptionsDisconnect: 1
|
||||
snapshotSettings:
|
||||
bufferTimeMultiplier: 2
|
||||
@ -335,6 +336,49 @@ Transform:
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1 &992559145
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 992559146}
|
||||
- component: {fileID: 992559147}
|
||||
m_Layer: 0
|
||||
m_Name: SpawnPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &992559146
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 992559145}
|
||||
m_LocalRotation: {x: 0, y: -0.8191521, z: 0, w: 0.57357645}
|
||||
m_LocalPosition: {x: 1.2, y: 0, z: 1.8}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1087861736}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: -110, z: 0}
|
||||
--- !u!114 &992559147
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 992559145}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 41f84591ce72545258ea98cb7518d8b9, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1054605962
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -485,6 +529,81 @@ Transform:
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1087861735
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1087861736}
|
||||
m_Layer: 0
|
||||
m_Name: Spawns
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1087861736
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1087861735}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1089501590}
|
||||
- {fileID: 992559146}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1089501589
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1089501590}
|
||||
- component: {fileID: 1089501591}
|
||||
m_Layer: 0
|
||||
m_Name: SpawnPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1089501590
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1089501589}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1087861736}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1089501591
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1089501589}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 41f84591ce72545258ea98cb7518d8b9, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1571122690
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -27,7 +27,7 @@ Transform:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8563961762736836479}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.04, z: 0}
|
||||
m_LocalPosition: {x: -0.05, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.1, y: 0.1, z: 0.1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
|
@ -26,13 +26,13 @@ Transform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6507540558446839548}
|
||||
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
|
||||
m_LocalPosition: {x: 0, y: 0.02, z: -0.1}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -0.025, y: 0.1, z: 0}
|
||||
m_LocalScale: {x: 0.05, y: 0.2, z: 0.05}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &3504059701668173685
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -27,7 +27,7 @@ Transform:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7003386763226572670}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.03, z: 0}
|
||||
m_LocalPosition: {x: -0.05, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.1, y: 0.1, z: 0.1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
|
@ -1724,10 +1724,10 @@ Transform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8617929508499776844}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalRotation: {x: 0.5, y: -0.5, z: 0.5, w: -0.5}
|
||||
m_LocalPosition: {x: 0.1, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1276535037084972472}
|
||||
m_RootOrder: 5
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_LocalEulerAnglesHint: {x: 180, y: -90, z: 90}
|
||||
|
@ -13,7 +13,7 @@ GameObject:
|
||||
- component: {fileID: 1580898288973620588}
|
||||
- component: {fileID: 68065165359339619}
|
||||
m_Layer: 0
|
||||
m_Name: PlayerPrefab
|
||||
m_Name: Player
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
@ -14,7 +14,7 @@ GameObject:
|
||||
- component: {fileID: 3436383402443096375}
|
||||
- component: {fileID: 6259401778744657634}
|
||||
m_Layer: 0
|
||||
m_Name: SceneObjectPrefab
|
||||
m_Name: SceneObject
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
@ -121,4 +121,6 @@ MonoBehaviour:
|
||||
type: 3}
|
||||
boxPrefab: {fileID: 7003386763226572670, guid: a4076fff9676bc243ae6d7d6c08341f3,
|
||||
type: 3}
|
||||
force: 1
|
||||
direction: {x: 0, y: 0, z: 0}
|
||||
equippedItem: 0
|
@ -13,46 +13,19 @@ public enum EquippedItem : byte
|
||||
|
||||
public class PickupsDropsChilds : NetworkBehaviour
|
||||
{
|
||||
public GameObject sceneObjectPrefab;
|
||||
|
||||
[Header("Player Components")]
|
||||
public GameObject rightHand;
|
||||
|
||||
[Header("Prefabs")]
|
||||
public GameObject ballPrefab;
|
||||
public GameObject batPrefab;
|
||||
public GameObject boxPrefab;
|
||||
public GameObject sceneObjectPrefab;
|
||||
|
||||
[SyncVar(hook = nameof(OnChangeEquipment))]
|
||||
[Header("Diagnostics")]
|
||||
[ReadOnly, SyncVar(hook = nameof(OnChangeEquipment))]
|
||||
public EquippedItem equippedItem;
|
||||
|
||||
void OnChangeEquipment(EquippedItem oldEquippedItem, EquippedItem newEquippedItem)
|
||||
{
|
||||
StartCoroutine(ChangeEquipment(newEquippedItem));
|
||||
}
|
||||
|
||||
// Since Destroy is delayed to the end of the current frame, we use a coroutine
|
||||
// to clear out any child objects before instantiating the new one
|
||||
IEnumerator ChangeEquipment(EquippedItem newEquippedItem)
|
||||
{
|
||||
while (rightHand.transform.childCount > 0)
|
||||
{
|
||||
Destroy(rightHand.transform.GetChild(0).gameObject);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
switch (newEquippedItem)
|
||||
{
|
||||
case EquippedItem.ball:
|
||||
Instantiate(ballPrefab, rightHand.transform);
|
||||
break;
|
||||
case EquippedItem.bat:
|
||||
Instantiate(batPrefab, rightHand.transform);
|
||||
break;
|
||||
case EquippedItem.box:
|
||||
Instantiate(boxPrefab, rightHand.transform);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
@ -70,23 +43,41 @@ void Update()
|
||||
CmdDropItem();
|
||||
}
|
||||
|
||||
void OnChangeEquipment(EquippedItem _, EquippedItem newEquippedItem)
|
||||
{
|
||||
StartCoroutine(ChangeEquipment());
|
||||
}
|
||||
|
||||
// Since Destroy is delayed to the end of the current frame, we use a coroutine
|
||||
// to clear out any child objects before instantiating the new one
|
||||
IEnumerator ChangeEquipment()
|
||||
{
|
||||
while (rightHand.transform.childCount > 0)
|
||||
{
|
||||
Destroy(rightHand.transform.GetChild(0).gameObject);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
switch (equippedItem)
|
||||
{
|
||||
case EquippedItem.ball:
|
||||
Instantiate(ballPrefab, rightHand.transform);
|
||||
break;
|
||||
case EquippedItem.bat:
|
||||
Instantiate(batPrefab, rightHand.transform);
|
||||
break;
|
||||
case EquippedItem.box:
|
||||
Instantiate(boxPrefab, rightHand.transform);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[Command]
|
||||
void CmdChangeEquippedItem(EquippedItem selectedItem)
|
||||
{
|
||||
equippedItem = selectedItem;
|
||||
}
|
||||
|
||||
// public because it's called from a script on the SceneObject
|
||||
[Command]
|
||||
public void CmdPickupItem(GameObject sceneObject)
|
||||
{
|
||||
// set the player's SyncVar so clients can show the equipped item
|
||||
equippedItem = sceneObject.GetComponent<SceneObject>().equippedItem;
|
||||
|
||||
// Destroy the scene object
|
||||
NetworkServer.Destroy(sceneObject);
|
||||
}
|
||||
|
||||
[Command]
|
||||
void CmdDropItem()
|
||||
{
|
||||
@ -100,17 +91,31 @@ void CmdDropItem()
|
||||
|
||||
SceneObject sceneObject = newSceneObject.GetComponent<SceneObject>();
|
||||
|
||||
// set the child object on the server
|
||||
sceneObject.SetEquippedItem(equippedItem);
|
||||
|
||||
// set the SyncVar on the scene object for clients
|
||||
// set the SyncVar on the scene object for clients to instantiate
|
||||
sceneObject.equippedItem = equippedItem;
|
||||
|
||||
// set the direction to launch the scene object
|
||||
sceneObject.direction = rightHand.transform.forward;
|
||||
|
||||
// set the player's SyncVar to nothing so clients will destroy the equipped child item
|
||||
equippedItem = EquippedItem.nothing;
|
||||
|
||||
// set the child object on the server
|
||||
sceneObject.SetEquippedItem();
|
||||
|
||||
// Spawn the scene object on the network for all to see
|
||||
NetworkServer.Spawn(newSceneObject);
|
||||
}
|
||||
|
||||
// public because it's called from a script on the SceneObject
|
||||
[Command]
|
||||
public void CmdPickupItem(GameObject sceneObject)
|
||||
{
|
||||
// set the player's SyncVar so clients can show the equipped item
|
||||
equippedItem = sceneObject.GetComponent<SceneObject>().equippedItem;
|
||||
|
||||
// Destroy the scene object
|
||||
NetworkServer.Destroy(sceneObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Examples.PickupsDropsChilds
|
||||
@ -6,50 +6,20 @@ namespace Mirror.Examples.PickupsDropsChilds
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class SceneObject : NetworkBehaviour
|
||||
{
|
||||
[Header("Prefabs")]
|
||||
public GameObject ballPrefab;
|
||||
public GameObject batPrefab;
|
||||
public GameObject boxPrefab;
|
||||
|
||||
[SyncVar(hook = nameof(OnChangeEquipment))]
|
||||
[Header("Settings")]
|
||||
[Range(0, 5)] public float force = 1;
|
||||
|
||||
[Header("Diagnostics")]
|
||||
[ReadOnly] public Vector3 direction;
|
||||
|
||||
[ReadOnly, SyncVar(hook = nameof(OnChangeEquipment))]
|
||||
public EquippedItem equippedItem;
|
||||
|
||||
void OnChangeEquipment(EquippedItem oldEquippedItem, EquippedItem newEquippedItem)
|
||||
{
|
||||
StartCoroutine(ChangeEquipment(newEquippedItem));
|
||||
}
|
||||
|
||||
// Since Destroy is delayed to the end of the current frame, we use a coroutine
|
||||
// to clear out any child objects before instantiating the new one
|
||||
IEnumerator ChangeEquipment(EquippedItem newEquippedItem)
|
||||
{
|
||||
while (transform.childCount > 0)
|
||||
{
|
||||
Destroy(transform.GetChild(0).gameObject);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Use the new value, not the SyncVar property value
|
||||
SetEquippedItem(newEquippedItem);
|
||||
}
|
||||
|
||||
// SetEquippedItem is called on the client from OnChangeEquipment (above),
|
||||
// and on the server from CmdDropItem in the PlayerEquip script.
|
||||
public void SetEquippedItem(EquippedItem newEquippedItem)
|
||||
{
|
||||
switch (newEquippedItem)
|
||||
{
|
||||
case EquippedItem.ball:
|
||||
Instantiate(ballPrefab, transform);
|
||||
break;
|
||||
case EquippedItem.bat:
|
||||
Instantiate(batPrefab, transform);
|
||||
break;
|
||||
case EquippedItem.box:
|
||||
Instantiate(boxPrefab, transform);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnValidate()
|
||||
{
|
||||
if (Application.isPlaying) return;
|
||||
@ -68,7 +38,7 @@ public override void OnStartServer()
|
||||
if (TryGetComponent(out Rigidbody rb))
|
||||
{
|
||||
rb.isKinematic = false;
|
||||
rb.AddForce(Vector3.forward, ForceMode.Impulse);
|
||||
rb.AddForce(direction * force, ForceMode.Impulse);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,5 +46,41 @@ void OnMouseDown()
|
||||
{
|
||||
NetworkClient.localPlayer.GetComponent<PickupsDropsChilds>().CmdPickupItem(gameObject);
|
||||
}
|
||||
|
||||
void OnChangeEquipment(EquippedItem _, EquippedItem newEquippedItem)
|
||||
{
|
||||
StartCoroutine(ChangeEquipment());
|
||||
}
|
||||
|
||||
// Since Destroy is delayed to the end of the current frame, we use a coroutine
|
||||
// to clear out any child objects before instantiating the new one
|
||||
IEnumerator ChangeEquipment()
|
||||
{
|
||||
while (transform.childCount > 0)
|
||||
{
|
||||
Destroy(transform.GetChild(0).gameObject);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
SetEquippedItem();
|
||||
}
|
||||
|
||||
// SetEquippedItem is called on the client from OnChangeEquipment (above),
|
||||
// and on the server from CmdDropItem in the PlayerEquip script.
|
||||
public void SetEquippedItem()
|
||||
{
|
||||
switch (equippedItem)
|
||||
{
|
||||
case EquippedItem.ball:
|
||||
Instantiate(ballPrefab, transform);
|
||||
break;
|
||||
case EquippedItem.bat:
|
||||
Instantiate(batPrefab, transform);
|
||||
break;
|
||||
case EquippedItem.box:
|
||||
Instantiate(boxPrefab, transform);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user