The Photon Forum
is Closed Permanently.

After many dedicated years of service, we have made the decision to retire our Forum and switch to read-only: we´ve saved the best to last! Your search result can be found below. Plus, we offer support via these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

How to despawn if Object is manually instantiated?

vinibeg
2021-12-02 16:03:11

Hello,

I am following the Manual Instantiation from the doc here:

** Instantiation | Photon Engine **
Photon Unity Networking framework for realtime multiplayer games and applications with no punchthrough issues. Export to all Unity supported platforms, no matter what Unity license you have!

And it works. Now, how do I destroy the gameobject? Do i need to call Photon.Destroy? Or manual destroy, i.e remove PhotonView component, then call Unity Destroy function?

Comments

vinibeg
2021-12-02 16:07:49

More information:

I use the manual instantiation because I use PoolManager game assets:

PoolManager | Utilities Tools | Unity Asset Store
Use the PoolManager from Path-o-logical Games on your next project. Find this utility tool & more on the Unity Asset Store.

So for example, I want to spawn a vfx:

var obj = PoolManager.Pools[pool].Spawn("VFX", pos, rot);

So, when I want to despawn, by right using the PoolManager would be:

PoolManager.Pools[pool].Despawn(gameObject);

However, the gameobject still have photonView component attached to it. How should I do?

Pardon my english, as its not my first language.

JohnTube
2021-12-03 08:55:09

Hi @vinibeg,

Thank you for choosing Photon!

You need a manual destruction event like manual instantiation:

  • call raise event with custom event code for manual network destruction, payload should be network object's ViewId.

  • remove manual network instantiation event from cache.

  • on receiving clients find network object using ViewId and Unity destroy it locally.

As a side note, did you consider implementing support for PoolManager as custom prefab pool? Read more here.

vinibeg
2021-12-07 11:36:35

Hello JohnTube,

Thanks for your answer. Following your steps:

call raise event with custom event code for manual network destruction, payload should be network object's ViewId. [ done ]

remove manual network instantiation event from cache.

[How do I manually remove the instantiation event from cache? Do i need to remove the photonView component?]

on receiving clients find network object using ViewId and Unity destroy it locally.

[ sure, i will use my current PoolManager to despawn it]

Regarding the PrefabPool, do you mean, I should extend my current PoolManager to implement "IPunPrefabPool"?

Because my project has 2 modes, single player and multiplayer mode. Do you think i should:

  • Add photonView component to all single player prefabs?

  • Add and remove photonView component on spawn and despawn method?

vinibeg
2021-12-07 11:44:23

Sorry, how do i manual remove instantiate from cache?

RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache };

PhotonNetwork.RaiseEventInternal(MPEvent.Remove, photonView.id, options, SendOptions.SendReliable);

Then on the clients side, i do:

GameObject g = PhotonView.Find(photonViewID).gameObject;

Destroy(g)?

JohnTube
2021-12-08 05:58:54

Hi @vinibeg,

The network destroy is three steps, I think you already got two working.

Remove the cached manual instantiation event from the events cache of the room, so no new actor or rejoining actor will receive it, caching option is correct yes (EventCaching.RemoveFromRoomCache) (event code == same manual instantiation event code, payload or data should be a filter for event cache removal if what you sent initially is a Hashtable or same structure which hopefully the server accepts as filter so you will remove only the exact event occurrence related to a specific ViewId and not all instantiations of ALL ViewIDs, raiseEventOptions.TargetActors should be set to the actor number of the instantiator). Read more here about Cached Events here

  • . If you're stuck, share code snippet for both manual instantiation and destruction you used/tried/tested.

  • Send manual network destroy event (custom event code + ViewId as payload).

  • When receiving manual network destroy event, destroy or despawn object locally.

About IPunPrefabPool, it was just a suggestion and a totally alternative way of using manual network instantiation and destruction which allows you to keep using default built-in methods PhotonNetwork.Instantiate & PhotonNetwork.Destroy BUT use your own custom object pooling.

vinibeg
2021-12-09 04:49:13

Hello @JohnTube ,

Thanks for your reply. Here is my codes.

In my NetworkSpawner.cs, send manual Instantiate / Remove instantiate event codes:

Then in my EventManager.cs that handles the event:

In my Ball.cs script, where I want to destroy the ball:

Are above codes correct?

When I try to spawn the ball for second time, I got this:

AllocateViewID() can't be used for PhotonViews that already have a viewID. This view is: View 1001 on MP_Ball(Clone)001 Spawned By Ball Controller

JohnTube
2021-12-10 22:46:57

Hi @vinibeg,

Code looks fine but it's missing DespawnBaseObject method and OnEvent handling.

This part is a bit suspicious from a Unity point of view unless I'm missing something.

"remove", "reattach"?

I would suggest minor optimizations or changes (NOT DIRECTLY RELATED TO THE ISSUE IN QUESTION AND ARE OPTIONAL):

  • I understand why you're doing this from the comment, you're spawning locally and sending event to Others to spawn. In this case you won't get the live event but you may get this event if you leave the room and rejoin it (PlayerTTL ! = 0 & RejoinRoom) or join it again (AutoCleanUp / CleanUpCacheOnLeave == false).

    if (senderId == PhotonNetwork.LocalPlayer.ActorNumber) break;

  • No need for "action" key/value as you should not receive RemoveFromRoomCache events, those are only meant for the server.

  • No need for "ownerID" if by that you mean ActorNumber (or UserID). ActorNumber can be guessed from ViewID, UserId is exchanged if PublishUserId is enabled.

Back to top