using UnityEngine;
using System.Collections;
public class ShipController : MonoBehaviour {
public float speed = 8.0f;
private Vector3 velocity;
private Vector3 newPos;
private Vector3 oldPos;
void Start() {
newPos = transform.position;
oldPos = newPos;
}
// Update is called once per frame
void Update () {
// Get the input vector from kayboard or analog stick
var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
if (directionVector != Vector3.zero) {
// Get the length of the directon vector and then normalize it
// Dividing by the length is cheaper than normalizing when we already have the length anyway
var directionLength = directionVector.magnitude;
directionVector = directionVector / directionLength;
// Make sure the length is no bigger than 1
directionLength = Mathf.Min(1, directionLength);
// Make the input vector more sensitive towards the extremes and less sensitive in the middle
// This makes it easier to control slow speeds when using analog sticks
directionLength = directionLength * directionLength;
// Multiply the normalized direction vector by the modified length
directionVector = directionVector * directionLength;
transform.forward = directionVector;
}
oldPos = transform.position;
transform.position = newPos;
velocity = directionVector * speed;
newPos += velocity * Time.deltaTime;
}
}
The above code allows me to fly straight through static primitive colliders as if they weren’t even there. I’ve tried with and without adding a rigidbody to my ship and the result is the same.
The code is a mishmash of things so there’s a very high possibility it’s flawed, but I just thought it looked so much cleaner than the dreaded character controller with it’s skin and slope settings which I have no need for.
And I like to understand why something fails before I scrap it.
Perhaps because you’re setting absolute positions?
Also, there’s very specific collision matrix that specifies what objects register legal collisions with each other. For example, a static colidder is anything without a rigidbody (even if you move it, it’s still considered static, and very expensive on physics system to move statics) and static’s won’t collide with each other. Not all combinations work and using isKinematic can also alter the way collisions work. Look in the manual for any collider component, it’ll show the collision matrix down the bottom.
Also try using ridigbody and applying forces rather than directly adjusting the position, this will also give you much more physically accurate collision responses. Collision also happens on a frame-by-frame basis, if you move too fast you can be one side of a wall in one frame and the other side of a wall in the next frame and it will never detect the collision. In these cases you need to either use continuous collision, sweep tests or raycast ahead of the player.
That may be true, but I was just so sure I had done something like this with success before.
Maybe I don’t have to start a new thread for this, but what is a cheap way of continuously moving an object and having it register collisions? My game is a top down shooter and I currently only need my ship to not exit the playing field, enemies to bounce around the playing field and not overlap eachother.
I like to think I don’t need all the physics rigidbody stuff, but just the collisions.
Have you tried CharacterController? Its like a rigidbody but made for manual setting of position for unrealistic physics. You should give that a shot and then just replace this line:
BDev, on my player ship I can utilize it, but from earlier experiments it seems to be uber slow so if I’m going to have hundreds of enemies on screen I need something different.
Edit: Of course that was with Unity 2, perhaps it’s much faster now. I’ll check it out.
Yea, that sounds like a challenge, hundreds of enemies i mean. If there all moving that could be tough to accomplish, just make sure that if you don’t use a CharacterController you at least have a kinematic rigid body so that the colliders don’t retrigger world physics calculations.
It works great. I can easily have 100-200 enemies on screen without it slowing down too much. With character controllers it slows down way too much after only 30-40.
According to the collision matrix and my own experiments kinematic rigidbodies can only collide with other rigidbodies which means they will go through walls and everything.
Just tested with character controllers on my enemies and it’s still slow as heck and practically unusable for this purpose. It’s looking more and more like you have to make your own collision detection if you’re not using rigidbodies. Which is something I’ve tried and failed at a thousand times when creating my own game engines. Guess I’ll have to give it another try.
Yea, i don’t think the collision matrix has anything to do with it unless you’ve modified it manually. I don’t think a kinetic rigidbody will collide with static/other kinetic rigidbodies colliders physically, though they will generate OnCollisionEnter/Stay/Exit. So when its set as kinematic it is no longer being simulated and can only push against non kinematic rigidbody colliders ( while not being pushed by anything ).
With what you said about making your own collision detection, If your making a 2D game Chipmunk is really a great physics engine and would be pretty easy to set up via plugins. If 3D even though physx is ancient and slow compared to other physics apis when its not accelerated by a GPU I’d probably avoid the headache of trying to sync everything non natively. Just depends on what you need i guess
Have you tried using translation? My enemies are non kinematic rigidbodies and I move them with transform.Translate, and they work as would be expected (colliding with static geometry and whatnot).
Is there a reason you want to use kinematic rigidbodies?
They just behaved very odd in my game now when they weren’t kinematic. WIll try with translation next.
This game is 2d, BDev. But the collision detection is so simple I think Chipmunk will be overkill as well, even though it looked very nice. For 3d Unity’s built in is plenty for me.
Another thing that is bothering me is that I still have to set y-position to 0 every frame even though I have the y-constraint turned on. What’s the point of that constraint if it doesn’t work?
the axial constraints are for simulation. So the object can’t be pushed along specified axes by collisions. It doesnt change the ability to set axes manually through script.
You could use Bounds for a light collision detection system. though some of the properties on it are really performance heavy ( for what they do ) where they shouldnt be. Bounds.SqrDistance is fast though