Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by vikhi · Jul 25, 2013 at 12:48 PM · collisiontransformparentparentingpuzzle

Child object getting transformed out side the scene on collision?

I have a requirement to do Jigsaw Puzzle.When I connect adjacent pieces ,the colliding piece should become child and it should transform along with its parent piece. I have written collision script for piece 1 and attached the script to it. When piece 2 collide with piece 1 , piece 2 getting transformed as child but goes out of the scene.

Reverse collision works fine.(When piece 1 collides with piece 2,piece 2 getting transformed as child and remains connected).

And I have also tried writing script for Piece 2, even then the same happens.

I have used four box colliders for four sides.

Have uploaded images too.

Here is the code:

 if(co.gameObject.collider.tag=="Piece2")
 {
     foreach (Transform child in transform) 
     {
         if(child.gameObject.collider.name=="Right")
         {
             foreach (Transform child1 in piece2.transform)
             {
             if(child1.gameObject.collider.name=="Left")
                 {
                 i1=2;
             if(i1==2)
             {
                 i1=3;
                         piece2.transform.parent = transform;
                 piece2.GetComponent<OTSprite>().draggable = false;
                 child1.GetComponent<BoxCollider>().isTrigger=false;
                 child.GetComponent<BoxCollider().isTrigger=false;
                 piece2.transform.position = new Vector3(piece1.transform.position.x+80.0f,
             piece1.transform.position.y, piece1.transform.position.z);                                       
                         }
                     }
                  }
                }
             }

Please suggest any ideas.Thanks.alt text

capture1.png (190.0 kB)
capture2.png (483.7 kB)
Comment
Add comment · Show 17
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 dorpeleg · Jul 25, 2013 at 01:43 PM 0
Share

After setting up the parent, you might want to move the piece with localposition and not position.

avatar image vikhi · Jul 26, 2013 at 05:31 AM 0
Share

@dorpeleg Have tried that too.Even though I got same result.

Here is the code:

piece2.transform.position = new Vector3(piece1.transform.position.x+80, piece1.transform.localPosition.y, piece1.transform.localPosition.z);

Thanks for your reply.

avatar image dorpeleg · Jul 26, 2013 at 09:31 PM 0
Share

Try:

 piece2.transform.localPosition = new Vector3(piece1.transform.localPosition.x+80, piece1.transform.localPosition.y, piece1.transform.localPosition.z);
avatar image vikhi · Jul 29, 2013 at 06:06 AM 0
Share

@dorpeleg Have tried that too. But got the same result.

Thanks for your reply.

avatar image rhys_vdw · Jul 29, 2013 at 09:05 AM 0
Share
 piece2.transform.localPosition = new Vector3(80, 0, 0);

If it's still not correct, then you need to change the value from 80 to something smaller.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by rhys_vdw · Jul 29, 2013 at 01:06 PM

Okay, so firstly I just want to explain what's actually happening in your script.

 void OnTriggerEnter(Collider co)
 {
     // Check if the collider that the piece is touching is tagged "Piece2".
     if(co.gameObject.collider.tag=="Piece2")
     {
         // Step through *all four* children of this object.
         foreach (Transform child in transform)
         {
             // Ignore all but the right collider. Note this does NOT check if
             // the right collider is touching the other piece!
             if(child.gameObject.collider.name=="Right")
             {
                 // Step through all the children of 'piece2'.
                 foreach (Transform child1 in piece2.transform)
                 {
                     // This code will ALWAYS find the left collider, it doesn't
                     // matter which is touching.
                     if(child1.gameObject.collider.name=="Left")
                     {
                         // So some pointless math.
                         i1=2;
                         if(i1==2)
                         {
                             i1=3;
 
                             // Child piece2 to this object, and set its
                             // localPosition to (80,0,0).
                             piece2.transform.parent = transform;
                             piece2.GetComponent<OTSprite>().draggable = false;
                             piece2.transform.localPosition = new Vector3(80.0f, 0, 0);
                         }
                     }
                 }
             }
         }
     }
 }

So basically your script just will attach this "piece2" thing to itself, no matter which side it hits. I think you're making the mistake of thinking that when you do this foreach through all the children, you will only see children that are touching the other collider. This is not the case. Each of these foreach statements will step through all the children.

I've taken out a lot of the redundant code in your script and this is what is left:

 void OnTriggerEnter( Collider collider )
 {
     if( collider.tag == "Piece2" )
     {
         // Get this pieces right child, and the other piece's left child.
         Transform thisRight = transform.Find( "Right" );
         Transform otherLeft = piece2.transform.Find( "Left" );
 
         // Assign this number.
         i1 = 3;
 
         // Child to this.
         piece2.transform.parent = transform;
         piece2.GetComponent<OTSprite>().draggable = false;
         piece2.transform.localPosition = new Vector3(80.0f, 0, 0);
     }
 }

Basically your script doesn't care about who is hitting it, or what is going on. I'm worried that you have a huge list of every single piece in this script.

I'm going to just write a script for you that will solve the problem correctly, because it seems like you're a bit lost. But I'll be happy to give you more feedback or explanation if you don't understand.

Attach this script to each of the four child objects:

 using UnityEngine;
 
 // This script should be attached to each of the four children of PuzzlePiece.
 public class PuzzlePieceCollider : MonoBehaviour
 {
     void OnTriggerEnter( Collider collider )
     {
         // Get the parent of the collider that we've hit.
         Transform otherPiece = collider.transform.parent;
 
         // If it should be attached, do so. Otherwise ignore.
         if( name == "Right" && collider.name == "Left" )
         {
             SendMessageUpwards( "AttachRight", collider.transform.parent );
         }
         else if( name == "Left" && collider.name == "Right" )
         {
             SendMessageUpwards( "AttachLeft", collider.transform.parent );
         }
         else if( name == "Top" && collider.name == "Bottom" )
         {
             SendMessageUpwards( "AttachTop", collider.transform.parent );
         }
         else if( name == "Bottom" && collider.name == "Top" )
         {
             SendMessageUpwards( "AttachBottom", collider.transform.parent );
         }
     }
 }

And this one to the actual piece:

 using UnityEngine;
 
 public class PuzzlePiece : MonoBehaviour
 {
     public float size = 80f;
 
     void AttachRight( Transform other )
     {
         Attach( other, Vector3.right * size );
     }
 
     void AttachLeft( Transform other )
     {
         Attach( other, Vector3.left * size );
     }
 
     void AttachTop( Transform other )
     {
         Attach( other, Vector3.up * size );
     }
 
     void AttachBottom( Transform other )
     {
         Attach( other, Vector3.down * size );
     }
 
     void Attach( Transform other, Vector3 offset )
     {
         // Check that the other piece is not already the parent of this piece!
         // This will be called on both pieces so we only need to parent one of them.
         if( transform.parent == other ) return;
 
         // Parent the piece.
         other.parent = transform;
         other.localPosition = offset;
 
         // Do this thing.
         other.GetComponent<OTSprite>().draggable = false;
     }
 }

You should set "size" on the pieces to the width/height of the pieces.

Each of the four colliders should be set to trigger, and the puzzle piece will require a kinematic rigibody.

Tell me how you go.

Comment
Add comment · Show 1 · 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 rhys_vdw · Jul 30, 2013 at 10:07 AM 0
Share

I'm glad to hear that.

If you want to add checks in to see if the pieces are in the right place, I suggest adding public xPosition and yPosition integers to the PuzzlePiece script.

Then before you call "Attach" you will have to check something like this...

 void AttachRight {
     int otherX = other.GetComponent<PuzzlePiece>().XPosition;
     if( otherX == XPosition + 1 ) {
         Attach( other, Vector3.right * size );
     }
 }

Good luck!

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.

Follow this Question

Answers Answers and Comments

17 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

Related Questions

How to instantiate a GameObject in a scene and keep world transform? 3 Answers

Parenting Transforms, Must (still) Set Parent at 0,0,0 ? 1 Answer

Parenting from code doesn't really change the hierarchy 1 Answer

Parent mesh problem 0 Answers

Parent colliding bullet to the object 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges