• 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 /
avatar image
1
Question by KazYamof · May 17, 2019 at 01:30 PM · charactercontrollerparent

Character Controller doesn't move with a moving parent

Using Unity 2019.1 There's no rigidbody in none of the objects. Character moves with CharacterController.Move method.

MovingPlatform:

 Update() {  transform.Translate(transform.forward * speed * Time.deltaTime); }

CharacterController:

 private void OnControllerColliderHit(ControllerColliderHit hit)
 {
         if (charControl.isGrounded && hit.transform.tag == "Floor")
                 transform.SetParent(hit.transform);
 }

The character keeps sliding out the platform while standing fixed. Platform has the tag "Floor". The object is being setted as child while looking at hierarchy.

Any solutions?

Comment
Add comment · Show 2
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 CoryButler · May 17, 2019 at 03:25 PM 0
Share

Ins$$anonymous$$d of changing the hierarchy, could you and the platform's speed to the character's speed?

avatar image KazYamof CoryButler · May 17, 2019 at 03:28 PM 0
Share

This would break my logic... In previous versions of Unity, set parent was the way to achieve this. There was some change or is this a bug?

4 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by KazYamof · May 17, 2019 at 05:59 PM

Figured out that if I change the platform from Update to FixedUpdate, changing the parent of CharacterController will works, and it will be carried with the platform.

FixedUpdate

  FixedUpdate() {transform.Translate (transform.forward * speed * Time.deltaTime); }

But I can not say if it's a bug or a feature! So, it does not seem to be a 'answer', even if it works

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 Mufasa-Vibes · May 30, 2021 at 12:29 AM 0
Share

Did you ever figure out why this was the case?

avatar image deplorablemountaineer · Jan 18 at 09:00 PM 0
Share

Late Update (not intended to be a pun): it also seems to be sensitive to Script Execution Order between platform rider (that parents/unparents the platform), character movement (that calls char controller's Move), and platform mover (that moves the platform) components. That is exactly the order I put them in to make it work. The default order, whatever it was, failed.

avatar image
0

Answer by Kim-Nobre · May 17, 2019 at 04:03 PM

You need to add the platform movement in the CharacterController.Move.

 Vector3 externalMovement = externalMoveSpeed * Time.deltaTime;
 controller.Move(movement + externalMovement);

The "externalMoveSpeed" is a public Vector3. When the character collides with the platform, the platform should change that value. It would look something like this:

 using UnityEngine;
 
 public class Platform: MonoBehaviour
 {
     private CharacterMovement character;
 
     public Vector3 moveDirection;
 
     private void Update()
     {
         transform.Translate(moveDirection * Time.deltaTime);
     }
 
     private void OnCollisionEnter(Collision collision)
     {
         if (!character)
         {
             character = collision.gameObject.GetComponent<CharacterMovement>();
         }
 
         character.externalMoveSpeed = moveDirection;
     }
 
     private void OnCollisionExit(Collision collision)
     {
         character.externalMoveSpeed = Vector3.zero;
     }
 }

But I suggest you put a BoxCollider on top of the platform, check "IsTrigger" and use OnTriggerEnter/OnTriggerExit instead (with that same logic) because when the character moves, the OnCollisionExit method might get called and it won't work properly.

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 FedoraDaEsplorer · Feb 06, 2021 at 07:18 PM 0
Share

Just a note for future references because this is the first google result: this solution works well, but ONLY if the platforms aren't rotating. If the platforms are rotating you'll have to do some more complicated math or just use the other solution of actually switching the parents.

Another note is to make sure that you undo the parenting when the player jumps off of the platform or else you'll get some weirdness.

avatar image
0

Answer by TheHemohscinProject · Apr 22 at 05:03 PM

turns out there's a much easier way to do this, instead of changing the transform in script using an animator and under the update mode change it to "animate physics", setting the object's parent under the same script of moving the character controller in a oncontrollercolliderhit method

 void OnControllerColliderHit(ControllerColliderHit hit)
     {
         if (hit.collider.tag == "floor")
         {
              transform.parent = hit.transform;
         }
         else
         {
             transform.parent = null;
         }
     }
Comment
Add comment · 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
0

Answer by unity_l_ltyl3C41NYHQ · May 22 at 01:03 AM

I just got a very simple solution for this problem that might help someone coming to this post. It also solves the problem related to moving the player acordingly when the platform/spaceship rotates, without needing to have it parented!

  1. Instead of parenting the object with the character controller to the platform or whatever, create an empty object and parent it instead. I will call it ghost.

  2. On your custom player controller script, create a reference to the ghost and set its position the same as the player itself on Start():

      private void Start()
         {
             ghost.transform.position = transform.position;
         }
    
    
  3. Create a Vector3 representing the amount of movement your character should be doing to be synchronized with the platform (IMPORTANT: Make sure to use LateUpdate to create all of the player movement logic now on). Sum up with the movement logic on Move(), reset the ghost position to player position so it is always up to date on where the player is exactly and then get all the movement up to the next frame.

      private void LateUpdate()
         {
             Vector3 translation = ghost.transform.position - transform.position;
     
             controller.Move(translation + movement);
     
             ghost.transform.position = transform.position;
     
             transform.rotation = ghost.transform.rotation;
         }
    
    
  4. Now its up to you how to customize that. You can also use OnControllerColliderHit() to change which object should the player have its movement synchronized to, like this:

      void OnControllerColliderHit(ControllerColliderHit hit)
         {
             if (hit.collider.tag == "Ground")
             {
                 ghost.transform.parent = hit.transform;
                 ghost.transform.position = transform.position;
             }
         }
    

Also a tip: Some unwanted behaviour might happen because of how the Character Controllers collisions works, turning the controller.detectCollisions to false will fix a lot of these problems. However, in order to get it perfect, a workaround is to remove all of the colliders from the object containing the rigidbody, create another independent object with only the colliders and simply copying the transform to the object with the rigidbody, so it will always be at the same pos/rot/scale. That is the most solid I could get. No jittering, no object going through eachother, fluid movement, etc. Hope it helps!

Comment
Add comment · 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

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

127 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

Related Questions

Character controller moves slow when an object its parented 1 Answer

Character-controller offset during gameplay 0 Answers

Weapon passing through colliders (objects)? 0 Answers

Parenting the Character Controller to rigidbody: won't stick 1 Answer

Making the character controller a child of another 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