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:
MrGadget 2024-10-11 06:59:13 -04:00
parent cc9cc4280b
commit 13bc00cfde
11 changed files with 231 additions and 99 deletions

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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}

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}
}