Sonic and Sega Retro Message Board: Unity3D Ground Alignment & Pathing script Stub - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
Page 1 of 1
    Locked
    Locked Forum

Unity3D Ground Alignment & Pathing script Stub Found this old thing on my HD, hope someone finds it useful.

#1 User is offline Raz 

Posted 27 August 2012 - 01:07 PM

  • Posts: 38
  • Joined: 17-July 09
  • Gender:Male
  • Location:USA
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 :)

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)



#2 User is offline Relick 

Posted 27 August 2012 - 05:36 PM

  • Posts: 197
  • Joined: 20-March 10
  • Gender:Male
  • Location:England
  • Project:C++/DX10 Engine (not sonic related)
  • Wiki edits:5
Nothing really catches my eye except for the thing about smoothing the movement with 3 vectors. Where do you get the other 2 vectors from, a front and back raycast? I've been trying to figure out how to smooth it for a while and this mightjust be it.

#3 User is offline Raz 

Posted 27 August 2012 - 05:49 PM

  • Posts: 38
  • Joined: 17-July 09
  • Gender:Male
  • Location:USA
I would offset the the vectors from the center vector, front and back, and cast straight down. Having 2 more, one on each side, may help stabilize side to side.

#4 User is offline princeofknaves 

Posted 27 August 2012 - 09:05 PM

  • Posts: 16
  • Joined: 11-March 11
  • Gender:Male
  • Location:Detroit, Michigan
  • Project:Entropy Engine, Knuckles The Echidna Game

View PostRelick, on 27 August 2012 - 05:36 PM, said:

Nothing really catches my eye except for the thing about smoothing the movement with 3 vectors. Where do you get the other 2 vectors from, a front and back raycast? I've been trying to figure out how to smooth it for a while and this mightjust be it.

adjacency indices would be my guess I don't know if Unity supports that but is how I would do it.

#5 User is offline Relick 

Posted 28 August 2012 - 01:55 AM

  • Posts: 197
  • Joined: 20-March 10
  • Gender:Male
  • Location:England
  • Project:C++/DX10 Engine (not sonic related)
  • Wiki edits:5

View PostRaz, on 27 August 2012 - 05:49 PM, said:

I would offset the the vectors from the center vector, front and back, and cast straight down. Having 2 more, one on each side, may help stabilize side to side.


So, this then?
Posted Image

(obviously a side view on it, it wouldn't look like this in the actual game :P)

#6 User is offline Raz 

Posted 28 August 2012 - 01:58 AM

  • Posts: 38
  • Joined: 17-July 09
  • Gender:Male
  • Location:USA
Yeah, nice diagram :)

#7 User is offline Relick 

Posted 28 August 2012 - 02:43 AM

  • Posts: 197
  • Joined: 20-March 10
  • Gender:Male
  • Location:England
  • Project:C++/DX10 Engine (not sonic related)
  • Wiki edits:5
Ok thanks, I'll try it out and get back to you.

#8 User is offline princeofknaves 

Posted 28 August 2012 - 02:58 AM

  • Posts: 16
  • Joined: 11-March 11
  • Gender:Male
  • Location:Detroit, Michigan
  • Project:Entropy Engine, Knuckles The Echidna Game
Well the EASIEST way would be to use per vertex normals and the barycentric coordinates as weighting between them that would be accurate and fairly cheap. I've been looking at the unity script reference and can't find any info if vertex normals are even stored just face normals. But if you can find something I can't it would be matter of finding sonic's position on the current triangle (there is a built in function for that) which would give you weights to interpolate the current up angle
This post has been edited by princeofknaves: 28 August 2012 - 02:59 AM

Page 1 of 1
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users