Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
1
Question by Liam3997 · Sep 06, 2018 at 11:52 AM · rotationrigidbody2dcollider2djointrelative

Adding rotate-to-mouse code causes issues with Relative Joint

Background

I'm trying to create a 2D character out of a few sprites. Each sprite has a Rigidbody2D and a PolygonCollider2D. The head and hands are tied to the body with RelativeJoint2Ds. What I want to create is a character that moves left and right, while the head rotates so that it's always looking at the mouse.

The problem I'm having is that when I add the code to make the head rotate to look at the mouse, it seems to break the Relative Joint's behaviour, and as the character moves back and forth, the head slowly slides downwards until it collides with the ground.


Visuals

You can see what movement should look like in this GIF: https://imgur.com/a/tnPUGnq. This is what the movement looks like before I add the code that rotates the head to look at the mouse (The last 5 lines of the Head's code below). Ideally, movement should continue to look like this, except that the head should constantly rotate to look at the mouse.

You can see the bug occurring in this GIF: https://imgur.com/a/8Tq13ro. This is after adding the head rotation code. You'll notice that the code seems to work and that the rest of the character moves regularly, but the head now moves downwards slowly as the character moves left and right.


What I've Tried

  • Changing the rotation code to affect the head's RigidBody2D instead of the head's transform. This instead just made the head rotate around the body as the mouse moved.

  • Moving the rotation code between Update() and ForcedUpdate(). No change.

  • Moving the AddForce code that moves the character from the head to the body. No change.

  • Trying different 2D Joints. None of them seemed to produce the effect I wanted.

  • Trying different colliders on the body and head. As long as the body is able to rotate even a bit, the bug seems to occur.

  • Messing around with the Relative Joint's properties to see if Force, Torque, or Correction might fix the problem. They didn't.

  • Freezing the body's Z rotation in its RigidBody settings. This made the body stand perfectly upright at all times which did solve the problem, since the head remained stationary above the body. However, I don't want the body to be perfectly upright at all times, I want it to be able to rotate, and any time it's able to rotate, the bug occurs.


My hunch is that the problem is tied to the rotation code, the head's Relative Joint, and/or the way the body rotates when it moves. Maybe the clamping of the body's rotation isn't translating properly to the head? Or maybe the rotation code can't keep up with the head's changing position?

Any suggestions of how to fix this? I also welcome suggestions for different ways to tie the sprites together that would avoid this problem all together.


Additional Code and Images

The head's Components: The head's Components


The body's Components: The body's Components


The head's Code:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerHeadMovementController : MonoBehaviour
 {
     private float moveForce = 100;
     private float maxSpeed = 5;
 
     private Rigidbody2D rb2d;
 
     // Use this for initialization
     void Start()
     {
         //Get and store a reference to the Rigidbody2D component so that we can access it.
         rb2d = GetComponent<Rigidbody2D>();
     }
     
     //FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
     void FixedUpdate()
     {
         //Store the current horizontal input in the float moveHorizontal.
         float moveHorizontal = Input.GetAxis("Horizontal");
 
         // Add force if current movement is less than maxSpeed
         if (moveHorizontal * rb2d.velocity.x < maxSpeed)
         {
             rb2d.AddForce(Vector2.right * moveHorizontal * moveForce);
         }
 
         // Cap force if current movement is greater than maxSpeed
         if (Mathf.Abs(rb2d.velocity.x) > maxSpeed)
         {
             rb2d.velocity = new Vector2(Mathf.Sign(rb2d.velocity.x) * maxSpeed, rb2d.velocity.y);
         }
 
         // Make the head track the mouse position
         // THE PROBLEM CODE, adding this causes the bug
         Vector3 mouse = Input.mousePosition;
         Vector3 screenPoint = Camera.main.WorldToScreenPoint(transform.localPosition);
         Vector2 offset = new Vector2(mouse.x - screenPoint.x, mouse.y - screenPoint.y);
         float angle = Mathf.Atan2(offset.y, offset.x) * Mathf.Rad2Deg;
         transform.rotation = Quaternion.Euler(0, 0, angle);
     }
 }


The body's code

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerBodyMovementController : MonoBehaviour
 {
     private float minRot = -5;
     private float maxRot = 5;
 
     private Rigidbody2D rb2d;
 
     // Use this for initialization
     void Start()
     {
         //Get and store a reference to the Rigidbody2D component so that we can access it.
         rb2d = GetComponent<Rigidbody2D>();
     }
 
     //FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
     void FixedUpdate()
     {
         // Clamp rotation
         if (rb2d.rotation < minRot || rb2d.rotation > maxRot)
         {
             rb2d.rotation = Mathf.Clamp(rb2d.rotation, minRot, maxRot);
         }
 
         // If we're not trying to move, rotate back to upright
         if (Input.GetAxis("Horizontal") == 0f)
         {
             if (rb2d.rotation > 1)
             {
                 // Rotate upwards
                 rb2d.rotation = rb2d.rotation * 0.2f;
             }
             else
             {
                 // Set directly to 0 degrees to save needless arithmetic
                 rb2d.rotation = 0;
             }
         }
 
         // Kill any low velocity
         if (Mathf.Abs(rb2d.velocity.x) < 0.1) rb2d.velocity = new Vector2(0, rb2d.velocity.y);
     }
 }
 


Comment
Add comment · Show 1
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 JVene · Sep 07, 2018 at 12:05 AM 1
Share

I'm going to study this to help, just thought I'd give a heads up in case you otherwise get no response for a while. $$anonymous$$udos on providing a complete description, code and discussion of what brought you to this point. I may have some questions, but so far as I can see you've detailed all that is required. $$anonymous$$ore in a while....

1 Reply

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

Answer by JVene · Sep 07, 2018 at 01:17 AM

I have an experiment for you to try. My reasoning follows the description of the experiment.


Create a child gameobject of what is now the head. Move the artwork, and only the artwork for the head, to the child. Change your code to apply the rotation only to the child, not what is currently the head. See what the results are.


My reasoning:


Joints are somewhat dysfunctional. If you use them exactly the way example tutorials show, they work. Once they're used in situations for which one thinks they ought to work, joints can do strange things.


I have no experience with Relative Joint (I don't do much in 2D). I have found similar issues in all 3D joints, especially hinge (I don't find a Relative Joint in 3D, the spring is more like that). Hinge works for a door fairly well, but if you hit the door with moderate to heavy force, it can dislodge the artwork. It is as if the artwork is on a flange and is displace on the flange, even though the hinge otherwise continues working as it did before. I've used hinges for wheels (the motor makes this inviting), but if the vehicle is more than a few Kg, the result is as if the axle is bending and buckling under the load.


I think your observation is a version of this kind of issue, peculiar to relative joint. My thinking is that the transform.rotation changes you're applying here affect the joint in a way that just drives it nuts. Why, I can't say, but I believe if you apply that rotation to a child, which leaves the GameObject attached to the hinge 'un-rotated', the visible results should be similar (or identical), while the physics results should be the same as when your code is commented out. Let me know what you get.

Comment
Add comment · Show 2 · 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 Liam3997 · Sep 07, 2018 at 06:47 AM 1
Share

Genius! I created a child object of the Head, gave it the same Sprite as the Head, turned off the parent object's Sprite Renderer, and moved the rotation code into a new script used by the child object. It works perfectly now! If you want to turn it into an answer, I'll gladly accept it. Thanks as well for the extra information regarding how weird joints can be, I'll keep it in $$anonymous$$d for the future.

avatar image JVene Liam3997 · Sep 07, 2018 at 07:41 AM 0
Share

@Liam3997, delighted to hear that worked!

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

187 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 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 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 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 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 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 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 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 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 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 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

Relative Joint 2D weird reaction to full rotations 1 Answer

2d keep player upright 1 Answer

Record and replay movement 0 Answers

Making The Z rotation always on 0 plz help 1 Answer

Platform effector 2d doesn't work with rigidbody 0 Answers


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