x


CharacterController on Moving Surface

The CharacterController needs to get on and off translating and rotating surfaces without parenting, which does not work without messing with the hierarchy. I can get a collided objects hit point, the offset of that from its axis and the position and rotation of the controller. It updates on FixedUpdate(). However, I cannot figure out the proper use or combination of Vector3 or Quaternion or transform.rotation.eulerAngles to get the controller to behave like it is on a moving (translating) object that may be turning, tilting or rotating as well. It would seem to e to be a very useful piece of code for most game style and should probably be integrated wherever it is best (console kept telling me it didn't like where I was putting these vars) as a built in method "RideOnObject". I would post the code I am playing with but it will change ten minutes from now. If I strike it rich I will post the javascript.

edit:I checked the scripts out from answer 694. The last one threw too many errors in the console to even start debugging and rearranging the code. I have set up the first simpler script with appropriate inputs but am looking at the var calculatedMove which I have yet to assign a value to because I am wondering if I can retrieve that value somehow from the CharacterController script or the FPSWalker script and whether the MouseLook value should be incorporated. Or should I write my own move calculation? As well, I noted that when you add a script it automatically goes underneath the ones there and you cannot change order. If they fire off from top to bottom the does the bottom script translation and rotation of the CharacterController override the values from the script higher up the Inspector list?

Thanks for the meat of the answer.I was doing very similar routines but the quaternion versus Vector3 and how to get them to play together flipping from world to local and translating that back to world after updating the tracked local point position of collision was kicking my butt. I now have all that and am digging into how to control the Move. I then assign that value to calculatedMove and I can then test on any number of tagged objects. What's the trick here?

Best Regards and TIA

more ▼

asked Feb 07 '10 at 11:32 PM

Rblain gravatar image

Rblain
132 3 3 8

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

Here is my script I can drop on a CharacterController or select one from the dropdown list in the inspector. I have done rudimentary testing on a rotating platform as I figured that was more of a trick than just a translating platform. To use it tag those surfaces with a "MovingSurface" tag so the OnCharacterColliderHit can find the name of the tag and implement the algorithm if the hitObject tag == "MovingSurface". Thanks to those I stood on the shoulders of to finally get this. Now for coffee.

var myCharacterController : CharacterController;
private var activePlatform : Transform;
private var hit : ControllerColliderHit;
private var activeGlobalPlatformPoint : Vector3;
private var activeLocalPlatformPoint : Vector3;
private var activeGlobalPlatformRotation : Quaternion;
private var activeLocalPlatformRotation : Quaternion;
var tagName : String;
private var moveDirection = Vector3.zero;
private var grounded : boolean = false;

function FixedUpdate () {
    if (tagName != "MovingSurface") 
    {
    	activePlatform = null;
    	lastPlatformVelocity = Vector3.zero;
    }
    if (tagName == "MovingSurface") 
    	{
    	if (grounded) {
    		// We are grounded on a Moving Surface, so recalculate move direction directly from axes
    		moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    		moveDirection = transform.TransformDirection(moveDirection);// Move the controller
    		var controller : CharacterController = GetComponent(CharacterController);
    		var flags = controller.Move(moveDirection * Time.deltaTime);
    		grounded = (flags & CollisionFlags.CollidedBelow) != 0;
    		//Keep moving (?) by getting the spped var from the FPSWalker CC script or whatever you are using 
    		moveDirection *= FPSWalker.speed;

    	}
    var calculatedMovement = moveDirection * Time.deltaTime;
    	// Moving platform support
    	if (activePlatform != null) {
    		var newGlobalPlatformPoint = activePlatform.TransformPoint(activeLocalPlatformPoint);
    		var moveDistance = (newGlobalPlatformPoint - activeGlobalPlatformPoint);
    		transform.position = transform.position + moveDistance;
    		lastPlatformVelocity = (newGlobalPlatformPoint - activeGlobalPlatformPoint) / Time.deltaTime;
    		// If you want to support moving platform rotation as well:
    		var newGlobalPlatformRotation = activePlatform.rotation * activeLocalPlatformRotation;
    		var rotationDiff = newGlobalPlatformRotation * Quaternion.Inverse(activeGlobalPlatformRotation);
    		transform.rotation = rotationDiff * transform.rotation;
    		}
    		else
    		{
    			lastPlatformVelocity = Vector3.zero;
    		}
    		//Controller Move  takes place here 
    		collisionFlags = myCharacterController.Move (calculatedMovement);
    		// Moving platforms support
    	if (activePlatform != null) {
    		activeGlobalPlatformPoint = transform.position;
    		activeLocalPlatformPoint = activePlatform.InverseTransformPoint (transform.position);
    		// If you want to support moving platform rotation as well:
    		activeGlobalPlatformRotation = transform.rotation;
    		activeLocalPlatformRotation = Quaternion.Inverse(activePlatform.rotation) * transform.rotation;
    		}
    }
}

function OnControllerColliderHit (hit : ControllerColliderHit) {
    // Make sure we are really standing on a straight platform
    // Not on the underside of one and not falling down from it either!
    if (hit.moveDirection.y < -0.9 && hit.normal.y > 0.5) {
        activePlatform = hit.collider.transform;
        tagName = hit.collider.tag;
    }
}
more ▼

answered Feb 09 '10 at 12:04 AM

Rblain gravatar image

Rblain
132 3 3 8

It works fabulousy xcept one item. How do I get the CharacterControler to follow the rotation of a merry-go-round for instance. The CC can get on and is dragged around but the view from their camera does not rotate with the platform and looks in the same absolute direction as prior to boarding.

Feb 14 '10 at 01:17 PM Rblain

i'm getting this error:

Assets/CharStickPlatform.js(26,44): BCE0020: An instance of type 'FPSWalker' is required to access non static member 'speed'.

I'll probably have to refer to my own script for moving around but that gives the same error.

What should I do?

Feb 25 '10 at 07:44 PM CracksisT
(comments are locked)
10|3000 characters needed characters left

See Question 694 for several solutions.

more ▼

answered Feb 08 '10 at 05:18 AM

Jaap Kreijkamp gravatar image

Jaap Kreijkamp
6.4k 20 26 70

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1879
x1047
x211
x195
x18

asked: Feb 07 '10 at 11:32 PM

Seen: 2034 times

Last Updated: Feb 08 '10 at 06:27 PM