- Home /
Creating a Character Collider Script
Im new to Unity and fairly new to Javascript. I am creating a game that uses a movement and camera system similar to Xenogears, and I have the character movement script and the camera script working correctly. However, I have scripted the player character's movement to be effected by other objects in the scene. Im looking make it stand on the ground and not pass through walls and buildings.
I was wondering what the best way to go about this is. Im not sure how difficult writing a script from scratch would be. I see my options being to write a completely new script to handle it, to take pieces from the provided 3rd person character controller script and add them to my current script, or to go into the provided character controller script and edit its movement to operate like the script I've written.
The problem with all of these is that Im not experienced enough with javascript to be able to fully follow whats happening in the provided 3rd person character controller script. I have been learning the scripting needed as I go along form online tutorials and am having a hard time finding any that relate to the way the collider system in Unity works.
So far the script I have rotates the character in the direction of the arrow keys and then moves him forward. Up moves north (0 degrees), Up and left moves northwest (45 degrees) and so on.
Any help or advice would be appreciated. Thanks.
EDITED: So I checked out the character controller, and realized I can pass all of the movement scripting through it and get the same results as adding the scripting directly through the prefab, so I feel like this solves most of my issues. The only question I have left is how to make the character controller actually work? Like the scripts I use to make the character controller respond to other objects.
So you are creating a script from scratch and want to have collisions with walls, go's etc? If so..
The Collider Class in unity is the collision basic in this realm. If you have something that can be hit or bumped into, you better bet theres a collider involved.
Give me some specific info and youll be on you way with no hesitation.
Realistically...look at it like this
$$anonymous$$ovement (happens on) transform+rotation scripting
Collisions(happen on) collision scripting
Physics (happens on) physics scripting
Very broad layout, but a basic thought here...
Let Unity handle thing like collision by simply adding a collider to you player and go's (conditions apply when using $$anonymous$$esh vs normal collider). This allows for triggers as well which is a huge fundamental in games (event / action).
Answer by aldonaletto · Jul 09, 2012 at 04:32 PM
The CharacterController is usually the best solution for characters, unless you need them walking on the walls or upside down - the CharacterController is always upright.
You can rotate left/right your CharacterController with Transform methods like Rotate, but must always move it using SimpleMove or Move: SimpleMove takes a Vector3 indicating the velocity and automatically applies gravity, but can't jump or fly (the velocity.y component is ignored); Move takes a Vector3 indicating the displacement (equivalent to Transform.Translate), and everything is in your hands (gravity, jumping, flying etc.)
There are good example scripts in SimpleMove and Move - the first one rotates with AD and moves forth/back with WS, and the second moves left/right/forth/back with ADWS. Both are simple scripts, and can be modified to suit your needs.
So the original script is called if A or D or W or S in pressed down. Individual direction input rotates the object accordingly. The script to actually move the object looks like this:
transform.position += transform.forward moveSpeed Time.deltaTime;
so would I change it to
$$anonymous$$ove.forward moveSpeed Time.deltaTime;
or
$$anonymous$$ove.position += $$anonymous$$ove.forward moveSpeed deltaTime;
or do I need write my own $$anonymous$$ove script? The above two are assu$$anonymous$$g the $$anonymous$$ove scripts are build into Unityscript.
No, you should use this:
GetComponent(CharacterController).$$anonymous$$ove(transform.forward * moveSpeed * Time.deltaTime);
But this code doesn't apply gravity - you must calculate gravity yourself, if needed.
There's an alternative, Simple$$anonymous$$ove, that applies gravity automatically:
GetComponent(CharacterController).Simple$$anonymous$$ove(transform.forward * moveSpeed);
Notice that Simple$$anonymous$$ove takes a velocity as argument, thus we don't multiply it by Time.deltaTime.
So I've tried out both of those, and Im having a issue with gravity. Im not quite sure how to fix it or what I'm doing wrong.
WITH THE $$anonymous$$OVE FUNCTION:
In the $$anonymous$$ove function, I tried to just add a second $$anonymous$$ove function for gravity, but it made my normal movement and the falling act strangely, so I checked the documentation and it said to make only one call to $$anonymous$$ove per frame. I so I made an if statement that was if(grounded) move forward, if(!grounded) then move the controller down.
This worked out just fine until I added a fall animation, and I found that the controller was having a very difficult time deciding if it was grounded or not. Sometimes when walking or running (it occurred more with the running) on a flat surface it would move me up and unground me, and it happened more often when running against a wall, and it happened almost every time that I fell to the ground. I've been trying to figure out what the problem is, but am completely lost.
While I'm sure there is a workaround to make the fall animation work more smoothly, the controller's grounding seems very unstable and feel like it should be more stable.
WITH THE SI$$anonymous$$PLE $$anonymous$$OVE FUNCTION:
I changed my controller.$$anonymous$$ove(transform.forward etc.) to controller.Simple$$anonymous$$ove(transform.forward * moveSpeed) and the the controller does not register gravity. I kept the original if(grounded) setup for animations, but the controller always reads as ungrounded and floats in the air. Do I have to declare velocity to make it work?
Simple$$anonymous$$ove must be called every frame in order to apply gravity - if you call it only when grounded, the character will get stuck in the air.
About the animation: isGrounded gets false every time the character looses contact with the ground, thus using it may not be so reliable for a falling animation. A possible alternative is to trigger the falling animation when isGrounded is false for some $$anonymous$$imum interval:
var timeInAir: float = 0;
function Update(){ if (controller.isGrounded){ timeInAir = 0; // reset timer when grounded } else { // and count time while in the air timeInAir += Time.deltaTime; if (timeInAir > 0.3){ // if in the air for more than 0.3s... animation.CrossFade("Falling"); // play Falling animation } } ...