Hello I am having a problem and I dont know how to solve it.
I want to create a 3d puzzle where the player needs to move multiple 3D objects to put them together. I already know how to implemet the movement (LeanTouch) but I need a way to recognize when two objects touch each other in special places. Then I would use transform to combine them. Does anyone have an Idea how to solve this?
One way to solve this is to create child objects with the colliders in the specific places you want to detect collision at. Then in OnCollisionEnter() you can practically combine them by creating a new parent of the two objects. Here's an example of an approach I took:
I set up my colliders like this:
Then on the individual colliders I added this code. Front is just the tag attached to the collider shown in the hierarchy.
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Front"))
{
var newParent = new GameObject();
newParent.transform.SetParent(collision.transform.parent.parent); // Get the parent of the current gameobject the collider is attached to
collision.transform.parent.SetParent(newParent.transform); // Doing .parent because this is the child collider
transform.parent.SetParent(newParent.transform);
}
}
It's not perfect, but the result is that the objects were combined under the same parent.
Alternatively, you could simply make one cube the child of the other by removing NewParent and replacing it with collision.transform.parent.
You should probably use colliders for that, and then use the collision event
Related
I am making a simple inventory/equipment system with a basic square character. One of the items you can use is a potion that will increase the pickup item area. I have a way to do this already, but I am wondering if there is a better way to do this?
WHAT I CURRENTLY HAVE
I have a collider on my character object, which deals with collisions with the walls and general world (all this handled in the Player script).
I then have an empty gameObject child of this object, which has a collider component the same size as the other collider (at start).
The child gameObject has a script (PickupAreaModifier script) with a OnTriggerEnter2D function that calls a method in the main character script to add the item.
If the item is the potion, then the Player script calls a method in the PickupAreaModifier script to change the size of that collider.
WHAT I WANT
This current logic works, but I would like to know if there is a more efficient way to handle this, especially considering the OnTriggerEnter2D function needing to be called on the child gameObject script. Is there any way I can handle this in only the Player script?
Thank you in advance, I hope that makes sense!
I have 2 simple capsules. 1 is stationary and the other is moving to the same tile on the tilemap using transform.position.
Both capsules have capsule colliders and rigid bodies. I've attempted to remove the rigid body but from what I can tell, the OnCollisionEnter function requires a rigid body to work.
My script, attached to both of these, is a simple:
private void OnCollisionEnter(Collision other)
{
print("Collision Detected! " + other.gameObject.name);
}
I've used combinations of 'isKinematic', 'isTrigger', placing one component before the other then reversing, ensuring I have the script attached to both objects, making sure my capsule collider is sized to the object, and looked at other people's issues to try their steps to fix my issue.
Nothing seems to trigger the collision between the 2 capsules. It's got to be something small I'm missing.
I have a tag on both objects and have tried things like if(other.gameObject.tag == "myTag") {...} but that's not working for me, either.
Can anyone spot my mistake? Let me know if you need to see anything else - happy to provide images or whatever will help. Thanks in advance!
Above is the basic identical hierarchy of both capsules with components attached to the capsule mesh. Both have the parent empty objects they're stationed under. (Which themselves, contain scripts but no collider or rigid body)
Here is an infographic to show when a collision message will be detected by OnCollisionEnter between two objects. Both objects will need some sort of collider, and will most likely need a Rigidbody.
You will not want to set isTrigger as that will not make it physically react to a collision, but will just detect when a collision occurs. It will also not call OnCollisionEnter but will call OnTriggerEnter. Setting both not as triggers, adding a collider, and giving them Rigidbodies should allow the collision to be detected. You will also need to attach this script to one of the objects that have the collider. Are there other components on the objects you are using?
Make sure you are not looking for
void OnTriggerEnter(Collision collision){}
I have 2 gameobjects within my character say right_obj and left_obj, I want them to ignore parent rotation, like if player change its direction (left, right), these 2 gameobjects stay on their position and rotation, so far I use 2 approaches but fail. here is my code, I use this script on my two gameobjects, but they ignour this lines
// first one approch
Quaternion rotation;
void Awake()
{
rotation = transform.rotation;
}
void LateUpdate ()
{
transform.rotation = rotation;
}
// 2nd approch
void LateUpdate ()
{
transform.rotation = Quaternion.identity;;
}
Do you really need this type of relationship?
If you don't really need the father/child relationship you can spawn an empty GameObject at 0,0,0 and spawn the actual parent and child as childs of the GameObject in the middle of the scene, this way they would still be grouped in some sort of relationship but instead of a father/child you'd get a brother/brother relationship, making the first independent from the second.
If you need to make two objects dependent from each other but not in every single way as it's supposed to be in father/child try using Parent Constraints
This way you'll obtain this type of hierarchy:
- Father GO (at 0,0,0)
-- Child1 (your actual father)
-- Child2 (your actual child)
Child1 and Child2 are syncing position by their ParentConstraint but not their rotation.
Else there is no other way than applying the opposite rotation to the child.
If you really don't want destory parent-child hierarchy, you could rotate child every frame to counteract parent rotation.
Let's say we have the follow scene,
Add the follow RestoreOriginRotation.cs to child object, we can get a stable child rotation.
What we can get.
****If you don't concern the underlying math, you chould stop here. ***
LeviathanCode's "Parent Constraints" solution only works with Unity 2018.1+ because it's a new addition.
My suggestion isn't a "pretty" solution but it'll also work with older versions if you want to prevent imitating rotations while still copying movement:
Get rid of the parent/child relationship, add a new parent GameObject (as LeviathanCode suggested) and a script to it that simply copies the player's movement each frame:
public GameObject player; //Drag the "player" GO here in the Inspector
public void LateUpdate() {
transform.position = player.transform.position;
}
This way your "right_obj" and "left_obj" won't rotate like the player but still move "with" it.
You could also use a Rotation Constraint component. This is similar to the Parent Constraint mentioned above, but it's simpler to understand in my opinion - it just uses the Rotation and only the rotation of whichever GameObjects you slot in.
You just have to make an empty game object and set the rotation to 0,0,0 , then set this empty game object as the source of the rotation constraint. I have this exact setup in my game, and it overrides the rotation of the actual parent, which is what I want.
Perhaps not the absolute cleanest solution, but it's something to consider.
Here is the docs link - https://docs.unity3d.com/Manual/class-RotationConstraint.html
As #aaronrums stated, a Rotation Constraint is an easy way to achieve this.
Here, I have 3 game objects. The main parent object container ("Player Seat") which holds all the children will always be set to a rotation of 0 on the Z axis. The GO I'm trying to keep positioned vertically (so the text and avatar doesn't rotate) is "DrewPlayer." I have it offset on the X-axis by 100 in its parent "Player Position." I added a rotation constraint on the item I didn't want to rotate. (a.k.a "DrewPlayer") Once the constraint was on it, I dragged over the "Player Seat" to the source list and when I rotated "Player Seat," I was able to achieve the desired effect in the gif below.
Thanks #aaronrums! Saved me some effort here. :)
context to the problem: I've got multiple sorts of cubes set up, placed in an array. I've made it so every different cube has his own parent, so all the cubes are grouped together with the other cubes of the same type.
I'm trying to move all the cubes of the same type up in the air away from the others so it becomes more visible how many cubes of the same type there are. my thought was that when any of the child objects get clicked, all of the objects under that parent move; but so far no succes.
Anyone got any tips as to how this might be able to work?
Note that I don't intend to use raycast as it seems overly compicated for this purpose.
If your cubes have colliders you can use OnMouseDown, in a script attached to each cube:
void OnMouseDown()
{
transform.parent.transform.Translate(Vector3.up * WhateverDistance);
}
If your cubes dont have colliders you'll have to use raycast to detect which cube has been clicked
If I instantiate a prefab like so:
GameObject asteroid = GameObject.Instantiate(thing2spawn);
//then set the location and some other stuff
The prefabbed asteroid's collisions do not register at all, but If I simply drag the asteroid into the scene, the collisions work exactly as expected.
Figured it out.
My asteroid object has two child objects which contain colliders that do different things. Hitting a certain part of the asteroid heals you, while hitting the other part damages you. These two children had rigid body components so when I set the speed of the asteroid (the parent object) in code, the two children wouldn't move with it. So it seemed like the colliders weren't working when really they were just left behind in some other place. Removing the rigid bodies from the children fixed the problem.
Weird.