I have a script on an empty game object that shakes the screen (I followed a Brakeys tutorial for this) - it has a function inside the script.
I wished to attach it to a prefab in the Inspector so I can call the shake function, however as I’ve now started to realise, this isn’t always possible. When I have the prefab open in the editor to edit, even though the reference slot is available, I can’t access the the scene game object to drag it in. I’m assuming Unity doesn’t want me to anyway
As far as I think know, I may have to get the reference of the game object in my prefabs script for the empty game object with it’s script attached, but I’m not sure if this what I should do. Am I on the right track here?
Could someone kindly explain what I should do and what’s going on? and perhaps show me some some sample code if scripting this is the method to use to - I’m confused!
Pretty sure you won’t be able to do that. GameObjects only exist with the scene, Prefabs exist ‘outside’ of it. So I expect they block you giving a reference to a GameObject to a Prefab, because if the correct scene isn’t loaded, it doens’t make sense for the prefab to be referencing said object. (That’s my understanding of it anyway!)
You can however make your other object a prefab as well. Prefabs can reference other prefabs at design time.
Alternatively, as you you correctly said here:
^ exactly, you can do this at runtime by getting a reference to the other object in code and setting the reference in the prefab instance in the scene.
I understand I’m not able to do it in the Inspector, I get that. But I was hoping for some help doing the coding for the reference.
There is a script on the Main Camera called “CameraShake”.
Inside that script is Coroutine function to do the shake.
In my prefab to get the refernce game object and to start the coroutine, I would normaly do this:
//Reference
public CameraShake cameraShake;
// Start coroutine function
StartCoroutine(cameraShake.Shake(.15f, .4f));
Then drag over the Main Camera into the prefabs reference.
But as I have to do this in code, can someone help me how to grab from the reference to the MainCamera with it’s CameraShake script, then how do I use it please?
It sounds like you neither want nor need a prefab here. There is nothing you’re describing that would use a prefab, and a prefab is causing you a string of problems.
If you need it to be a prefab (for some other reason), then simply update whatever code is instantiating the prefab and have it set the Camera reference after it instantiates a new object. This is the normal way to do things.
I have a Prefab Asteroid which is instantiated as a Prefab. This Asteroid Prefab has a script for collision, particle explosion, Lives etc.
The Main Camera has the Shake Script attached.
I require reference to the Shake Scripts Coroutine function in the Asteroid Script so that when the player is hit by the asteroid I can call the coroutine function.
I know I can’t drag over the Main Camera to the Prefab. So I have to use a scripted refernce instead. but as I’m still quite new to Unity Scripting, I’m not sure what to write.
I also know there several ways, such as searching for the script name or the Game Objects tag. It’s just putting it all together so I can use the reference
You always have a player in-scene, and won’t be using a prefab for it … so: when there’s a collision, have the Player script trigger the camera shake (this is also better for clean code: asteroids have nothing to do with cameras. You could run a sim without a cam. But players do! Players need cameras!)
Use a singleton in the scene for ‘global game effects’ that has a reference to the scene-camera. When something wants to shake the screen, call: “Singleton.instance.ShakeScreen()” or similar.
(note: singletons are bad, nearly always the wrong solution to every problem – BUT: Unity has a lot of quirks, and some missing features, so that Singletons are often necessary, and it’s common to use them in Unity projects)
Thanks for the respone. Yeah I can see where you’re going with best-practices idea. I’ll try have a change around and see if that helps. I oringally thought most things should be prefabbed, but of course, it’s not necassary.
I have not read up on Singleton’s yet, so i’ll see how I get on with this first.
I know I’m late but:
If you’re dead set on having the asteroid cause the camera shake, then what you can do is have a public variable called cameraShaker in the asteroid script. Then whenever you create an asteroid (from an object specified for the task or any solution you come up with) you just set that variable to the camera shake object in the scene.
//Asteroid script
public class AsteroidScript : MonoBehavior
{
public CameraShake cameraShaker;
//Whenever you want to shake the camera call
StartCoroutine(cameraShaker.Shake(.15f,.4f);
}
//Asteroid spawner
public class AsteroidSpawner : MonoBehavior
{
public CameraShake cameraShake; //Set this in the inspector
public GameObject asteroid; //Set this in the inspector
//Whenever you want to spawn a asteroid do
GameObject newAsteroid = asteroid.Instantiate();
newAsteroid.GetComponent<AsteroidScript>().cameraShaker = cameraShake;
}