Here's a youtube of the build before I put the pathing in:
So a while back I was determined to get a Sonic engine working on Unity3D- it was going to be the editor I wanted to learn how to use (maybe still is). At the time, and even now, there still isn't a good Sonic controller for Unity3D, I think one or two have been made privately, but I think we're in dire need of a 3D engine by now, unfortunately, the math/physics just got the best of me- I ported this code to C# later on but I don't know what state it's in so I'm posting my unityscript backup.
Don't expect too much :P but here's what I got working before I had exams:
- Align to ground normal
- Right now it only uses a single vector- but I was told (can't remember who)
that if you use 3 vectors, you can average them and get really smooth transitions
across every normal, instead of the snapping I have here.
- Use the Sonic BGE (cyborg_ar) style raised-wall pathing system.
- Basically if you raise two walls on either side of a path, the vectors
that shoot out on either side of your character will detect them and align
the character to the center, as well as align him to the normal of the ground.
After this I realized I had to get the physics working- that's where I got stuck. Something about dot product of gravity and the ground normal I dunno, but my approach was going to be to say screw-it to the physics engine and handle it all in code with basic newtonian formulas that I could modify during pathing for loops and such. A friend of mine was approaching form a standpoint of guiding the physics engine along, using helper-forces.
Personally I really wanted to do bSplines like Damizean did with Eggen but that's just so beyond me :P
Either way, I just wanted to post this in case someone had tried it, gotten stuck, and gave up before they really had a chance to shine. I had to go to the unity channel for that axis-alignment stuff, because one function worked and another didn't and... whatever.
I would really like to see an open source Sonic engine in Unity3D, I think it's the most approachable IDE for the beginning fangamer. SonicGDK is excellent, I'm really impressed with those guys, and I may have to bite the bullet and learn UDK, but that several gig download and high computing requirement is just overkill for what I wanted. I was happy with basic GL shading and materials, and a light footprint (not to mention Unity has a web plugin, which would make it -real- handy for SAGE).
If it looks like I didn't know what I was doing- you're right. But at least I commented like a mofo
So a while back I was determined to get a Sonic engine working on Unity3D- it was going to be the editor I wanted to learn how to use (maybe still is). At the time, and even now, there still isn't a good Sonic controller for Unity3D, I think one or two have been made privately, but I think we're in dire need of a 3D engine by now, unfortunately, the math/physics just got the best of me- I ported this code to C# later on but I don't know what state it's in so I'm posting my unityscript backup.
Don't expect too much :P but here's what I got working before I had exams:
- Align to ground normal
- Right now it only uses a single vector- but I was told (can't remember who)
that if you use 3 vectors, you can average them and get really smooth transitions
across every normal, instead of the snapping I have here.
- Use the Sonic BGE (cyborg_ar) style raised-wall pathing system.
- Basically if you raise two walls on either side of a path, the vectors
that shoot out on either side of your character will detect them and align
the character to the center, as well as align him to the normal of the ground.
After this I realized I had to get the physics working- that's where I got stuck. Something about dot product of gravity and the ground normal I dunno, but my approach was going to be to say screw-it to the physics engine and handle it all in code with basic newtonian formulas that I could modify during pathing for loops and such. A friend of mine was approaching form a standpoint of guiding the physics engine along, using helper-forces.
Personally I really wanted to do bSplines like Damizean did with Eggen but that's just so beyond me :P
Either way, I just wanted to post this in case someone had tried it, gotten stuck, and gave up before they really had a chance to shine. I had to go to the unity channel for that axis-alignment stuff, because one function worked and another didn't and... whatever.
I would really like to see an open source Sonic engine in Unity3D, I think it's the most approachable IDE for the beginning fangamer. SonicGDK is excellent, I'm really impressed with those guys, and I may have to bite the bullet and learn UDK, but that several gig download and high computing requirement is just overkill for what I wanted. I was happy with basic GL shading and materials, and a light footprint (not to mention Unity has a web plugin, which would make it -real- handy for SAGE).
If it looks like I didn't know what I was doing- you're right. But at least I commented like a mofo
private var controller :CharacterController;
controller = gameObject.GetComponent(CharacterController);
var hit : RaycastHit; // cast a ray down from the player object
var hit_left : RaycastHit; // 2.5D Directional vector for path system
var hit_right : RaycastHit; // 2.5D Directional vector for path system
var direction_vector : Vector3;
var yRot : float; // Internal storage of direction vector because FromToRotation sets alignment axis to angle 0
var playerSpeed : float = 200.0;
var rotSpeed : float = 80.0;
var vector_length : float = 23.0;
var is2D : boolean = false;
var groundRay : Ray;
groundRay = new Ray(transform.position, Vector3.down);
function FixedUpdate()
{
var forward : Vector3 = transform.TransformDirection(Vector3.forward);
var down : Vector3 = transform.TransformDirection(Vector3.down);
var left : Vector3 = transform.TransformDirection(Vector3.left);
var right : Vector3 = transform.TransformDirection(Vector3.right);
// Draw debug vectors to see wall collisions
//~ Debug.DrawRay(transform.position, down*vector_length, Color.green); // Down vector
//~ Debug.DrawRay(transform.position, left*vector_length, Color.green);
//~ Debug.DrawRay(transform.position, right*vector_length, Color.green);
if (Physics.Raycast(transform.position, down, hit)) {
// Keep alignment to ground.
transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal); // Get ground normal and align to it
//transform.rotation = Quaternion.LookRotation(Vector3.forward, hit.normal); // Also works but breaks on the loop
transform.position = hit.point + transform.TransformDirection(Vector3.up*5.0); // Move character 5.0 above the normal hit point
// Begin Path System
if(Physics.Raycast(transform.position, left, hit_left, vector_length) && Physics.Raycast(transform.position, right, hit_right, vector_length)) {
//direction_vector = transform.TransformDirection((hit_left.normal - hit_right.normal)/2.0);
//direction_vector = hit_left.normal - hit_right.normal;
//direction_vector.Normalize();
//direction_vector = hit_left.point - hit_right.point;
//direction_vector.Normalize();
Debug.DrawLine(hit_left.point, transform.position, Color.white);
Debug.DrawLine(hit_right.point, transform.position, Color.white);
direction_vector = Vector3( hit_left.normal.x - hit_right.normal.x, hit_left.normal.y - hit_right.normal.y, hit_left.normal.z - hit_right.normal.z);
direction_vector.Normalize();
//direction_vector = Vector3.Cross(direction_vector, hit.normal);
var midPoint : Vector3 = (hit_left.point + hit_right.point) / 2.0;
transform.Translate(midPoint-transform.position, Space.World);
//direction_vector = transform.TransformDirection(direction_vector);
Debug.DrawRay(transform.position, direction_vector*vector_length, Color.red);
var dirVec : Vector3 = Vector3.Cross(direction_vector, hit.normal);
Debug.DrawRay(transform.position, dirVec*vector_length, Color.blue);
//transform.LookAt(transform.TransformDirection(dirVec));
//transform.LookAt(transform.TransformDirection(direction_vector));
// Programming note: When using transform.TransformDirection(), player gets stuck trying to point down
transform.rotation = Quaternion.LookRotation(dirVec, hit.normal); // Points player in direction for 2D path system
yRot = transform.rotation.eulerAngles.y; // Make sure the last angle the player leaves the path as, is the one he's in in 3D mode, instead of returning to last 3D yRot.
}
else {
// If we don't put this in the else block, then it conflicts with the rotation genrated by 2D detection.
transform.rotation = transform.rotation * Quaternion.AngleAxis(yRot, Vector3.up); // Reapply direction so that we can turn.
}
}
// Note: May need to rewrite the translation step as one single statement so that it doesn't desynch the 2D controls above.
if(Input.GetKey("up")) {
transform.Translate(0.0,0.0, playerSpeed * Time.deltaTime);
}
else if(Input.GetKey("down")) {
transform.Translate(0.0,0.0, -1 * playerSpeed * Time.deltaTime);
}
else {
controller.SimpleMove(Vector3.zero);
}
if(Input.GetKey("left")) {
yRot = yRot + -1*200*Time.deltaTime;
}
if(Input.GetKey("right")) {
yRot = yRot + 200*Time.deltaTime;
}
}
@script RequireComponent(CharacterController)


00
