• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by newbdragoon · Sep 12, 2020 at 10:56 PM · instantiateprefabseditorguimoving platformpathing

Instantiate an object in a prefab?

I have a setup with some nodes to form a path for a moving platform, each with a custom editor UI button to instantiate the currently selected node, and set the newly made node as the next node in the path. This works fine, except it breaks when I try to make a prefab of the setup so I can drag-and-drop in more moving platforms later.


When I make it a prefab, everything seems fine at first - I can make a new node, and it's set as the next one along the path. However, the editor doesn't mark the first node as having been modified from the prefab, so when I hit play it reverts to the prefab - and the connection to the new node breaks. If I drag and drop in the new node as reference it works fine, but I wanted to try and make the button do all the work so I wouldn't need to worry about having to drag and drop for every node.


Is there a way to force the prefab to recognize that there's been an update when pressing the button? I'm guessing it's just not recognizing it, since I'm using custom UI. Is there a more graceful way to fix this?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Capricornum · Sep 13, 2020 at 07:01 AM 1
Share

I have just been playing around with custom editors. Are you using SerializedProperty and SerializedObject? Those are recommended when working around with prefabs and prefab instances.

The other way, by using customClass = (customClass)target is apparently not that safe with prefabs. It requires you to use something like PrefabUtility.RecordPrefabInstanceProperty$$anonymous$$odifications. This is a link: Link

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by newbdragoon · Sep 13, 2020 at 07:47 PM

Thanks for the help! I managed to get it working with customClass = (customClass)target and PrefabUtility.RecordPrefabInstancePropertyModifications - however, I'm not using SerializedProperty and SerializedObject since I didn't really realize that they were better to use, and I don't have any experiecne using them. Since I'm not using them, though, I can't Undo the creation of the new pathing nodes. This isn't the worst thing in the universe, but it would be nice. I tried a few different things with SerializedObject and couldn't quite figure out how to get it working, can anyone shed some light on what I might be doing wrong? Here's the relevant code, without using SerializedObject since I'm not sure how to correctly implement it:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEditor;
 
 [CustomEditor(typeof(PlatformPathNode))]
 public class PlatformPathNodeUI : Editor
 {
     public override void OnInspectorGUI()
     {
         PlatformPathNode thisNode = (PlatformPathNode)target; //grabs the current object
 
         if (GUILayout.Button("Create New Node"))
         {
             int c = thisNode.transform.parent.childCount;
             Instantiate(thisNode.transform.GetComponent<PlatformPathNode>(), thisNode.transform.parent); //creates a clone of this node with the same parent
             PlatformPathNode newNode = thisNode.transform.parent.GetChild(c).GetComponent<PlatformPathNode>(); //grab the new node
             newNode.name = "Node " + (c - 1); //renames the new node to show its number in the child hierarchy
 
             thisNode.nextNode = newNode; //sets the newly made node as the next one in the path
 
             PrefabUtility.RecordPrefabInstancePropertyModifications(thisNode);
             Selection.activeObject = thisNode.nextNode; //set the new node as active
 
         }
     }
 }
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Capricornum · Sep 13, 2020 at 09:42 PM 0
Share

Too be honest I don't quite manage to follow along. Do you really need this connection via thisNode.nextNode? Everything is connected as next child within a transform anyhow isn't it? So you could just access it later by calling this from the Parent Transform:

 foreach (Transform child in transform)
 {
 PlatformPathNode node = child.GetComponent<PlatformPathNode>();
 node.DoSomeStuff();
 }

Then you don't need to make any references at all. You can happily create your nodes in the scene, no?

avatar image Capricornum · Sep 13, 2020 at 09:54 PM 1
Share

However there is an actual Undo class within Unity. You can find it HERE. So try writing Undo.RecordObject(thisNode, "Change on Node") as the first thing in your GUILayout.Button part. $$anonymous$$aybe that's all you need.

Also how about this:

 if (GUILayout.Button("Create New Node))
 {
 Undo.RecordObject(thisNode, "Change on Node");
 PlatformPathNode newNode = Instantiate(thisNode, thisNode.transform.parent);
 newNode.index = thisNode.index + 1;
 thisNode.nextNode = newNode;
 PrefabUtility.RecordPrefabInstanceblablalba;
 Selection.activeSelection = blablabla;
 }

avatar image Capricornum · Sep 13, 2020 at 09:56 PM 0
Share

I am not experienced enough with SerializedProperty and SerializedObject to help you with that.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

171 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Call a function in an instanciated prefab has no effect on the prefab 2 Answers

Help needed on getting distance value of chain of links after instantiation 0 Answers

Make a game object in a scene into a prefab with script 1 Answer

how to call the animation of prefab 0 Answers

Trouble with prefabs and activating each other's scripts 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges