Magical Rigidbody/CharacterController free character...controller - Unity

edited in Questions and Answers
Hi

So it seems a lot of people have spoken against the evils of using a rigidbody in Unity so I have been using a CharacterController which is about 99% of what I need. This was fine until I was asked to look into that 1% and see if anyone wouldn't mind sharing how they handle character's and collisions.

The player character we're using is a squarish shape so using the CharacterController's Capsule collider is a bit of a nuisance. I did try use a Box Collider but that resulted in 3 problems:
1 - Using RayCast means I would need to emit a ray from each corner when moving he character which means at least 4 rays but at most 12 per frame. Even so if an object could still pass through the centre of the character undetected.
2 - The OnCollision events only get triggered if a rigid body is attached to the object (which kinda defeats the purpose of all this effort)
3 - Physics.CheckSphere is not Physics.CheckCube... and Physics.CheckCube doesn't exist (nor does Physics.CheckSphere return a list of the colliders within the sphere for additional checking with collider.bounds.Intersects).

If you can please let me know what you use for your player's collisions (or if you do just use character controller too just say so too).

P.S I have attached a drawing of our punk rock horse character code named bob in the collision cube I'd like to use. (It's actually meant to be a zebra but now you see why the powers that be have me doing the programming)
Untitled-1.png
250 x 226 - 24K

Comments

  • I'm afraid I can't help you with the technical gubbins, but just wanted to say that that's the most beautiful zebra I have ever seen. ;)
    Thanked by 2Manikin hanli
  • edited
    On the bandwagon of not-very-helpfulness, but I'd love to see said Zebra star in a game through your artistic prowess, and don't let no "artist" tell you otherwise ;)
  • Just a quick question: Why is the player object in control of when objects collide with it? It should always be the responsibility of the object doing the moving to check if it's going to collide with something - so that means that a smaller moving object shouldn't be able to pass through the center of your character if the character has a useful hitbox.

    Or is the problem that you don't have logic that can do stuff like test for specific collisions between objects?
  • Hi @mushu
    So it seems a lot of people have spoken against the evils of using a rigidbody in Unity)
    I have to confess I am not aware of the rigidbody evilness :) would like to read more on that and see what its about.

    I am using rigidbody a great deal in one of my current projects and have had good results with the character controllers previously *albeit not with such a cool geometric zebra as you have*. What problems are you referring to that you need to avoid. You might be skipping the very tool you need. Have you used a rigid body and found specific problems? If so perhaps we could tackle those instead.

    Alternatively so you need a cube or could me make your little guy a sphere or perhaps a capsule (2 capsules one aft and one fore if you use controller) again.
  • edited
    Haven't played with it much (current project is 2D), but from what I understand the standard approach is as follows :

    Attach a RigidBody to your object and set Is Kinematic to true on that RigidBody. With Is Kinematic set to true, the RigidBody won't invoke the cost of the physics, but it will cause Triggers to fire. Additionally, while the Kinematic object won't receive collisions, other Rigidbodies will receive collision events with it. So, a bullet or whatever will detect that it's collided with your player's kinematic Rigidbody. It will then send a message to your player saying "I hit you bro, for X damage."

    See here :

    http://docs.unity3d.com/Documentation/Components/class-Rigidbody.html

    Does that help, or have you already tried that?

    About your horse shape, can you tilt the capsule collider? May be a better fit?

    @tbulford : manually moving non-kinematic rigidbodies creates a significant hit in performance, as far as I know.
  • edited
    1 - Using RayCast means I would need to emit a ray from each corner when moving he character which means at least 4 rays but at most 12 per frame. Even so if an object could still pass through the centre of the character undetected.
    12 raycasts aren't very much at all. A hundred isn't very much, either.
    3 - Physics.CheckSphere is not Physics.CheckCube... and Physics.CheckCube doesn't exist (nor does Physics.CheckSphere return a list of the colliders within the sphere for additional checking with collider.bounds.Intersects).
    Have you tried Physics.OverlapSphere? As Danny said, you should be raycasting with the bullet so it would collide with your box perfectly.

    There is also Bounds.Intersect which you can look into for AABB checks, but I've never used it so I can't advise on its usefullness.
  • If I understand correctly, you're asking how your horse checks itself against other objects (like the ground) when it moves?

    (not asking about how to check other moving objects against it?, which is a simpler problem I think)

    I go with number 1. If your terrain is so irregular that raycasts might miss small objects, then I might try spherecasts.

    The last FPS I did seemed to work okay with raycasts, but we had quite low detail terrain. We're doing another FPS for the 7DFPS next week... so maybe I can help better then.

    Disclaimer: I'm not too sure that I can in good conscience recommend doing things the way I do... I've never worked with a punk-rock horse before, and my games are silly

    And I'm not actually too sure how the Unity character controller works...
  • @garethf ah OK. So a specific issue with them not a general one.
  • edited
    @tbulford I tend to talk out against rigidbodies in Unity as they constrain you to realistic style movement (if you aren't using them kinematically) and operate on the Fixedtime step (which isn't in sync with the render update, inevitably causing jitters in fast moving objects unless your fixedtime step is incredibly short).

    Rigidbodies I find to be a headache in anything that isn't cosmetic or only interactive in physics simulation related ways.

    But I don't know if those are the evils that @mushu is referring to.
  • I found this video when I was trying to figure out raycast stuff for sprites. I use the character controller just because it gets me somewhere really quick without having to do anything, but now that I want to have things walk through each other, it seems raycast is the only way!


    Disclaimer: I have no clue how that stuff works, it's pretty much some voodoo magic I believe, well the rays certainly look like pins
  • edited
    All the raycasts

    using UnityEngine;
    using System.Collections;
    
    public class PlayerMovement : MonoBehaviour {
    
    	public float MovementSpeed;
    	public float HorizontalRaycastLength = 2;
    	public float DepthRaycastLength = 2;
    	
    	void Start () {
                // Start stuffs
    	}
    	
    	void Update () {
                ProcessInput();
    	}
    	
    	void ProcessInput() {
    	    if (Input.GetButton("Up")) 
    	        if (!Physics.Raycast(this.transform.position, this.transform.forward, DepthRaycastLength))
    		    this.transform.position += MovementSpeed * this.transform.Forward * Time.deltaTime ;
    
    	    if (Input.GetButton("Down")) 
    		if (!Physics.Raycast(this.transform.position, -this.transform.forward, DepthRaycastLength))	
    		    this.transform.position += MovementSpeed * -this.transform.Forward * Time.deltaTime;
    		
    	    if (Input.GetButton("Left")) 
    		if (!Physics.Raycast(this.transform.position, -this.transform.right, HorizontalRaycastLength))
    			this.transform.position += MovementSpeed * -this.transform.Right * Time.deltaTime;
    
    	    if (Input.GetButton("Right")) {
    		if (!Physics.Raycast(this.transform.position, this.transform.right, HorizontalRaycastLength))
    			this.transform.position += MovementSpeed * this.transform.Right * Time.deltaTime;
    	}
    	
    	void OnDrawGizmos() {
    		Gizmos.color = Color.red;
    		// Draw horizontal rays
    		Gizmos.DrawLine(this.transform.position - (this.transform.right * HorizontalRaycastLength), this.transform.position + (this.transform.right * HorizontalRaycastLength));
    		// Draw depth rays
    		Gizmos.DrawLine(this.transform.position - (this.transform.forward * DepthRaycastLength), this.transform.position + (this.transform.forward * DepthRaycastLength));
    
    	}
    }
  • Wow. Thanks everyone for all the helpful feedback and compliments on my amazing zebra drawing.

    @dislekcia I'm still relatively new to game dev and having the actual moving objects detect collisions seemed like it would take more processing power since they only need to react with the character. But the approach you mentioned does make sense so I'll try that. Thanks.

    @tbulford The evils I talk about is more along the lines of advice that I got from some guys at the game dev meetups. They mentioned a few of the things that @BlackShipsFilltheSky covered.

    @raithza Being new to unity I didn't know that raycasts were inexpensive.
    I have read that using Spherecast's can be though.

    Sorry for replying so late. I've been locked out of the forums (the password reset didn't seem to wanna work)
Sign In or Register to comment.