Search Unity

Need help very badly, how to save changes/overrides in prefab for instantiate in next scene

Discussion in 'Scripting' started by SamiRehman1997, May 20, 2020.

  1. SamiRehman1997

    SamiRehman1997

    Joined:
    Aug 13, 2018
    Posts:
    74
    hello guys, i am working on endless runner game, i have made a character select and also character customize. Basically in customize i change the material of selected character with a script when button is pressed (keycode.c) . but when i instantiate that prefab in game scene it instantiates with the default material, since changes are not saving in prefab, i am instantiating prefab from Resources folder. is there is way way for saving those changes in prefab automatically before instantiating it?



    here the video link for system i made.

    script files

    this is for material change.


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace RunnerGame
    4. {
    5.     public class MaterialChanger : MonoBehaviour
    6.     {
    7.         [Header("Components")]
    8.         public SkinnedMeshRenderer skinnedMesh;
    9.         public CharacterSelect selectedCharacter;
    10.         public CharacterControl control;
    11.  
    12.         [Header("Variables")]
    13.         public Material[] materials;
    14.         int arraycount = 0;
    15.  
    16.         private void Awake()
    17.         {
    18.             skinnedMesh = GetComponentInChildren<SkinnedMeshRenderer>();
    19.             control = GetComponent<CharacterControl>();
    20.         }
    21.         private void Update()
    22.         {
    23.             if (Input.GetKeyDown(KeyCode.C))
    24.             {
    25.                 if (selectedCharacter.SelectedCharacter == control.Type)
    26.                 {
    27.                     arraycount++;
    28.  
    29.                     if (arraycount >= materials.Length)
    30.                     {
    31.                         arraycount = 0;
    32.                     }
    33.                     skinnedMesh.material = materials[arraycount];
    34.                 }
    35.             }
    36.         }
    37.     }
    38. }
    39.  
    40.  
    for spawning player in game scene

    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. namespace RunnerGame
    5. {
    6.     public class CharacterSpawn : MonoBehaviour
    7.     {
    8.         public CharacterSelect characterSelect;
    9.         [SerializeField] private CharacterControl character;
    10.         private string ObjName;
    11.         private GameObject CamFollow;
    12.         private void Awake()
    13.         {
    14.             switch (characterSelect.SelectedCharacter)
    15.             {
    16.                 case PlayableCharacterTypes.Mike:
    17.                     {
    18.                         ObjName = "Mike";
    19.                     }
    20.                     break;
    21.                 case PlayableCharacterTypes.James:
    22.                     {
    23.                         ObjName = "James";
    24.                     }
    25.                     break;
    26.                 case PlayableCharacterTypes.Liam:
    27.                     {
    28.                         ObjName = "Liam";
    29.                     }
    30.                     break;
    31.                 case PlayableCharacterTypes.Noah:
    32.                     {
    33.                         ObjName = "Noah";
    34.                     }
    35.                     break;
    36.                 case PlayableCharacterTypes.Charlotte:
    37.                     {
    38.                         ObjName = "Charlotte";
    39.                     }
    40.                     break;
    41.  
    42.                 case PlayableCharacterTypes.Emma:
    43.                     {
    44.                         ObjName = "Emma";
    45.                     }
    46.                     break;
    47.                 case PlayableCharacterTypes.Jane:
    48.                     {
    49.                         ObjName = "Jane";
    50.                     }
    51.                     break;
    52.                 case PlayableCharacterTypes.Jessica:
    53.                     {
    54.                         ObjName = "Jessica";
    55.                     }
    56.                     break;
    57.                 case PlayableCharacterTypes.William:
    58.                     {
    59.                         ObjName = "William";
    60.                     }
    61.                     break;
    62.             }
    63.  
    64.             GameObject obj = Instantiate(Resources.Load(ObjName,
    65.                 typeof(GameObject))) as GameObject;
    66.  
    67.             obj.transform.position = this.transform.position;
    68.  
    69.             character = FindObjectOfType<CharacterControl>();
    70.  
    71.             if (characterSelect.SelectedCharacter != PlayableCharacterTypes.NONE)
    72.             {
    73.                 character.isStarted = true;
    74.                 character.anim.runtimeAnimatorController =
    75.                     Resources.Load<RuntimeAnimatorController>("PlayerAnimator");
    76.             }
    77.  
    78.             CinemachineVirtualCamera[] arr;
    79.  
    80.             arr = FindObjectsOfType<CinemachineVirtualCamera>();
    81.  
    82.             if (CamFollow == null)
    83.             {
    84.                 CamFollow = GameObject.FindGameObjectWithTag("CamFollow"); ;
    85.             }
    86.  
    87.             foreach (CinemachineVirtualCamera virtualCameras in arr)
    88.             {
    89.                 virtualCameras.LookAt = CamFollow.transform;
    90.                 virtualCameras.Follow = CamFollow.transform;
    91.             }
    92.         }
    93.     }
    94. }
    95.  
    96.  
    as you can see in video i selected with green material but in game scene it still instantiate with red.

    Game Scene Character.
     

    Attached Files:

    Last edited: May 20, 2020
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I don't think you can (or should) allow your game to permanently change a prefab at runtime.

    Instead, I suggest you either:

    a) Once you have customized one instance of the prefab, set it to DontDestroyOnLoad and continue to use the same instance in all future scenes

    b) Store a list of all the changes you made in some sort of custom data structure somewhere, and then whenever you create a new instance of the prefab, immediately apply all of those same changes again
     
    PraetorBlue and Joe-Censored like this.
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I'd suggest "b", as you may later want to include a save/load system and b's solution here will be immediately useful for such a system in addition to resolving the current issue.
     
  4. SamiRehman1997

    SamiRehman1997

    Joined:
    Aug 13, 2018
    Posts:
    74
    I don't know how to do the 'b' any tutorial or blog for that would be good or rough idea with script. Problem with a option 'A' is that character in game view starts with wrong position, since I've characters standing in line with offset of 2 from each other, what I'm doing is instantiate character on the position of empty game exist in game scene. Thanks for help in advance
     
  5. SamiRehman1997

    SamiRehman1997

    Joined:
    Aug 13, 2018
    Posts:
    74
    I'll be needing that too
     
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    The most straightforward way to preserve information when loading a new scene is to put it in some kind of singleton object. This could either be a MonoBehaviour that is attached to a DontDestroyOnLoad object, or it could be a plain C# object (non-MonoBehaviour) stored in a static variable.

    You can probably find lots of tutorials on making singletons pretty easily.
     
  7. SamiRehman1997

    SamiRehman1997

    Joined:
    Aug 13, 2018
    Posts:
    74
    I am using singleton alot in my game for mangers but, i think i know what you mean i did that had same position problem, I'll send you code later for confirming. It's 5 am here i probably should sleep now. But it would be great if you check later when i post, thanks for helping.