I created several objects in a blender: man, horse, dog, and others. I can animate them separately, like walking or running but I can not understand how to make the interaction animation between them in Unity, like riding a horse or pet a dog. To which object to apply this animation? Can you please describe or provide some tutorials for me?
I don't need already done solution, I want to realize how to make this on my own.
There are several ways to do that.
The easier way to do that is to include a script with public GameObject (consumers) variables in a GameObject (producer). With that reference, you can interact with other GameObjects.
You can drop the reference of the GamObject(consumers) on these public variables. These consumers will react to an action of the producer GameObject script.
Example public GameObject
However, I would really recommend you to use Events, it is a more elegant way to do the interaction between objects.
Basically, one of the objects triggers an Event and the subscribers (other objects) will react in consequence to this event.
Related
Whenever I need to instantiate prefabs, I always use the following technique
Add a GameObject/MonoBehaviour field to the MonoBehaviour which would instantiate the prefab.
Use this field to instantiate the prefab
E.g.:
public class ExmapleController : Monobehaviour
{
[Serializefield]
GameObject _examplePrefab;
GameObject _exampleObject;
public void SpawnExample()
{
_exampleObject = Instantiate(_examplePrefab);
}
}
Now my problem with this is that first of all I need two references. One for the prefab and one for the instantiated object. Secondly, whenever I need additional prefabs I have to create new and new references inside my script. This sometimes clutters my Scripts and I always wonder that is this memory efficient? What does Unity do behind the scenes? It just only stores a GUID reference for my prefab than somehow loads this prefab based on this reference? Or when I make a prefab reference the whole object tree is pulled into memory and I should rather use Asset bundles or another Unity technique?
Basically that's fine. But if you want to improve your workflow you can try creating ScriptableObjects to store the prefab references and then have only 1 reference to your scriptable object inside the mono behaviour. It will help you keep your mono behaviour classes clear. For more advanced approach you can check Dependency Injection frameworks for Unity. The most common one is Zenject. It helps you in managing dependencies in your classes (prefabs in your case are dependencies of Monobehaviour class).
When you create a reference to a Prefab Unity only store the GUID of the prefab you referenced. It is how resource system in Unity works. But if your prefab is required on the current scene then it will be fully loaded with all inner dependencies. If loading takes much time than it is the reason to think about using Addressables (AssetBundles). Unity doesnt have any other technique to avoid loading the full object tree in memory. But addressables let you control when to load the specific prefab from asset bundles to memory.
Yes this perfectly fine and how it's done. A reference is just that: a reference. The only time a copy of the object is made is when you call Instantiate.
If you have multiple prefabs that are just variations of one you should use ScriptableObject instead and have just 1 prefab that can take any variation form. You would still intantiate them the same way.
Basically that's fine. But if you want to create a huge numbe of objects or delete them you could also have a look at Object Pooling. More infos can be found under the link from the tutorial at Unity:
https://learn.unity.com/tutorial/introduction-to-object-pooling#
"Object Pooling is a great way to optimize your projects and lower the
burden that is placed on the CPU when having to rapidly create and
destroy GameObjects. It is a good practice and design pattern to keep
in mind to help relieve the processing power of the CPU to handle more
important tasks and not become inundated by repetitive create and
destroy calls. (Unity)"
Me and my friend are building a simple idle game as our first project in unity.
We got to the point at which we build a script that handles all calculations, and communicates with each GameObject the player sees.
Now, to what should we attach this script?
We would rather not use a GameObject because:
1) The GameObject would be an overkill
2) The GameObject lies in the space where all of my "physical" objects exist (That would be useless since the script does not have to "exist somewhere")
First time posting in stackoverflow, if I made any mistake please tell me ^^
Convention says to put it on the main camera or an empty GameObject.
If you really don't want to do either of those, you could make your class static.
If your class inherits from MonoBehaviour you have to attach it to a GameObject. If you want to attach it to a GameObject it has to inherit from MonoBehaviour.
If you want to better understand the Unity way, I advise you to read up on Entity-Component Systems:
GameObject are Entities
MonoBehaviour are Components
Services and managers generally get implemented as Components in Unity which then get attach to the main camera or to empty GameObjects named after them.
You can create a usual singleton class, and "Game Initializer" monobehaviour, that will initialize all your singletone managers, fabrics, etc...
Just add this monobehaviour to every scene in empty gameobject with a code like that:
if(GameManager.instance == null)
new GameManager();
Or in case of scriptableObjects,
if(GameManager.instance == null)
gameManager.init()
Also, a good desicion is to use Entity System pattern, here is frameworks for unity (Unity-Ash, Entitas, etc)
I have a gameobject with two sphere colliders attached. One has IsTrigger checked and the other not.
I want to execute different set of statements when collision occurs with different colliders. For example I want to play different sound for both different collisions. Is there any way to achieve it?
I tried OnTriggerEnter() but unfortunately it is called for both type of collisions since other colliding objects have triggered colliders. I just thought if we could somehow find out on which collider of the gameobject the collision has taken place we will be able to achieve it.
So is there any way to get through with this?
I have been using Unity for years and faced tons of problems like this, related to bad software design. I hope Unity guys will handle physics more carefully in future releases.
In the mean time, you can use Physics.OverlapSphere and Physics.CheckSphere to manually check if there is something that collides with your object. Remove the collider that you are using as a trigger and use these methods instead of OnTriggerEnter. This is a bit hacky, but this will do the job I think.
Make your colliders visible in the inspector (make them public or add [SerializeField] before it) and then tie in the colliders to the code that way.
Then, in your collisions, compare the colliding objects against your variables that are holding the colliders for you to keep them separate.
To detect for source trigger in OnTriggerEnter, you must use workaround with multiple gameobject hosting trigger and satellite scripts.
Allow me to link to my answer on gamedev SO:
https://gamedev.stackexchange.com/a/185095/54452
Say you want to let your users create a 2D airship (side view) made up of components. One component could be a floating balloon, another could be a storage room, etc.
And say you want this airship to have physics applied to it as a whole, with each component playing a part in this. For example, balloons would take away from its down force and other compartments would apply down force to it.
At the same time, the whole airship works as a whole (or at least the only physical separation would be between floater components and the others, which apply weight), so physics are applied to it as if it was one body.
Now, how can this be managed? How can I customize a game object via a script, giving it different components with different weights, and have it behave like it was a single premade object?
I'm sorry if the question is simple, but I'm only getting started with unity. Thank you very much!
TL;DR: Customizable airship gameobject with different components that have different weights. How to make it behave as a single physics entity and manage its different components?
I'm not sure that I completely understood the question :D
You mean having a game object, that has some child game objects, each with individual Collider and Rigidbody, and the Rigidbody physics applied to the parent game object? You can use joint colliders for this purpose such as HingeJoint2D, and set the parent's Rigidbody as ConnectedRigidBody.
(And instead of the word "component", use child or part or sth else to prevent ambiguity. 'Cuz the components in Unity3D are stuff like scripts, rigidbody, collider, etc. which are attached to game objects.)
Ok, I have this main class called Enemy, and inside it I have subclasses of different enemies (ie ZombieEnemy). I need a way to target all sprites/subclasses of Enemy. Ie, for collision detection, I need a way to see if ALL Enemy's are 'dead' to end the Level.
Thanks
There are plenty of ways to do this. One is to add a method to your Enemy class like -(BOOL)isEnemy that simply returns YES. (That'd actually be more useful if Enemy has a superclass that you can customize, like GameObject. Implement -isEnemy in that class to return NO. Otherwise, you won't know if you can call -isEnemy on a given object.) Subclasses will automatically inherit this method. Alternately, you could test the class of each object using -isKindOfClass:. Or, since you're the one creating enemies, you could certainly keep a list of all active enemies. This is probably the best plan if you have lots of objects on the screen, only some of which are Enemy objects.
Deciding when all enemies are dead is something you probably want to do very often. It might make sense to keep a list of live enemies. When an enemy dies, remove it from the list. You can quickly test whether the player has successfully cleared the level by checking the length of the live enemies list. If it's greater than 0, there's more work to do.