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 /
avatar image
0
Question by PingInfo · Jul 22, 2014 at 11:06 AM · animationcollisionrigidbodytriggercharactercontroller

How to have other (any) Objects smoothly push a Character Controller?

Making a character controller apply forces to a rigidbody via OnCollisionEnter or OnTriggerEnter is not very difficult. There's even a script for it in the docs and I've made my own.

However, how do I smoothly "push" a character controller with other objects, such as a static collider, or kinematic rigidbodies, or even non-kinematic rigidbodies (I'm trying not to use these but it doesn't make a difference at this point. Ideally I am going to be using lots of kinematic rigidbodies)?

When I mean smoothly push, I mean not as in apply "a fake force" a character controller upon entering Collision or Trigger (in case of kinematic rigidbodies or static colliders), but sort of "carrying" the character controller along the perimeters of the other object? That is, gently nudging the character controller with it no matter the speeds of the other object.

The way I tried, using OnTriggerStay produces jerky results, most likely because OnTriggerStay occurs every FixedUpdate(). Although in my script I did use Update() to simulate a constant push, I also used FixedUpdate(). I've included my scripts below in full. CharacterMovement goes on the character (as well as a trigger). MovingPlatform goes on a simple cube or platform (this also needs a trigger).

I tried using Animated Physics on something more complex than a platform and it produced close results to what I wanted, with a non-kinematic rigidbody on the character, but I could sadly not control the amount of force animated physics has on the character. It throws the character too hard, when animations are fast, no matter what the settings are instead of sort of carrying it alongside it like when animations are slow .

 public class CharacterMovement : MonoBehaviour
 {
     public float speed = 10f;
     public CharacterController controller;
     public bool useController = false;
 
     public void Start()
     {
         if (controller == null) controller = GetComponent<CharacterController>();
     }
 
     public Vector3 pushVector;
     //public float pushSpeed;
 
     void OnTriggerStay(Collider collider) 
     {
         Debug.Log("Collided with " + collider.name);
         //For easy testing purposes
         if (collider.name != "MovingPlatform") return;

         //Already tried using using this in both Update() and FixedUpdate() as well as a calculated velocity from fixed update instead of update in the platform, as well as inputting different values for velocity instead of calculated ones and speeds, and turning off and on fake friction before adding the this fake force to the character controller
         pushVector = collider.GetComponent<MovingPlatform2>().transformVelocity * collider.GetComponent<MovingPlatform2>().oldDelta * collider.GetComponent<MovingPlatform2>().speed; //pushSpeed;
 
         //pushVector += collider.GetComponent<MovingPlatform2>().transformVelocity * 0.1f;
         //pushVector += collider.rigidbody.velocity;
 
     }
 
     public void OnCollisionEnter(Collision collision)
     {
         Debug.Log(" I have collided with " + collision.gameObject.name);
     }
 
     public void OnControllerColliderHit(ControllerColliderHit hit)
     {
         if (hit.gameObject.name == "Floor") return;
         Debug.Log("OnHit: "+ hit.gameObject.name);
     }
 
     // Update is called once per frame
     void Update()
     {
 
         float h = Input.GetAxis("Horizontal");
         float v = Input.GetAxis("Vertical");
 
         // Add to Update or FixedUpdate, just before using moveDirection: //Note: doesn't work well in either
         Vector3 moveDirection = Vector3.zero;
         moveDirection = pushVector; //infinite momentum, just for testing
         //moveDirection += pushVector; //Use with friction
         //pushVector *= 0.8f; //Friction
 
         
         
         //Doesn't matter just for testing
         //Move via transform
         if (controller == null || !useController)
         {
             moveDirection.x += h;
             moveDirection.z += v;
 
             transform.Translate(moveDirection * speed * Time.deltaTime);
         }
         //Move via Controller //Note: if not moving collisions and triggers not detected (only below because of the fake gravity), 
         else 
         {
             moveDirection.x += h;
             moveDirection.z += v;
             moveDirection.y += Physics.gravity.y;
             controller.Move(moveDirection * speed * Time.deltaTime);
         }
 
     }
 }
 
 
 
 
 public class MovingPlatform : MonoBehaviour
 {
     public float speed = 12f;
     public float timeToTravel = 1f;
     public float delayTime = 0.7f;
     
     private Vector3 oldPosition;
     private Vector3 newPosition;
     public Vector3 transformVelocity = Vector3.zero;
     public float oldDelta;
     
     // Use this for initialization
     IEnumerator Start()
     {
         oldPosition = transform.position;
         fixedOldPosition = transform.position;
 
         while (true)
         {
             yield return new WaitForSeconds(delayTime);
             float t = 0f;
 
             while (t < timeToTravel)
             {
                 transform.position += new Vector3(0f, 0f, speed * Time.deltaTime);
                 t += Time.deltaTime;
                 yield return null;
             }
 
             yield return new WaitForSeconds(delayTime);
 
             while (t > 0f)
             {
                 transform.position -= new Vector3(0f, 0f, speed * Time.deltaTime);
                 t -= Time.deltaTime;
                 yield return null;
             }
         }
     }
     
     // Update is called once per frame
     void Update()
     {
         newPosition = transform.position;
         Vector3 media = (newPosition - oldPosition);
 
         transformVelocity = media / Time.deltaTime;
         oldDelta = Time.deltaTime;
         oldPosition = newPosition;
         newPosition = transform.position;
     }
 
     private Vector3 fixedOldPosition;
     private Vector3 fixedNewPosition;
     public Vector3 fixedTransformVelocity = Vector3.zero;
     public float fixedOldDelta;
 
     void FixedUpdate()
     {
         fixedNewPosition = transform.position;
         Vector3 media = (fixedNewPosition - fixedOldPosition);
 
         fixedTransformVelocity = media / Time.deltaTime;
         fixedOldDelta = Time.deltaTime;
         fixedOldPosition = fixedNewPosition;
         fixedNewPosition = transform.position;
     }
 }
 
Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by CriticalAngleStudios · May 02, 2019 at 03:07 AM

I found the solution! When you collide with the object that wants to push your controller, make the the player a child of that object

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Collisions with an animated character 1 Answer

Possible to stop collider from "popping" through plane when re-centering? 2 Answers

How to Play an animation state on an animator controller on collision? 1 Answer

CharacterController gets pushed by RigidBodies 1 Answer

CharacterControllers don't register collisions with each other? 2 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