Walking on highwire

Hi, I am trying to make a small script so my character can walk on a highwire.
But I have a problem when the character is ON the highwire, I can’t seem to get him positioned in the middle of the wire.

I want the player to be in the middle of the highwire as the picture shows, I have no problems figuring out when he is on the highwire, and I can access the highwires transform.

Can anyone help?

The diagram is clear, but I’m not quite sure if you’ve already written the code and it’s not working as expected, or if you’re asking how to write the code in the first place.

Can you perhaps clarify the question a little?

I haven’t written the code to place him in the middle of the wire, on the pic it is just his happened-to-be landing position.

The code i need should placed the player on the middle of the wire, as the pic shows

One option would be to make the character a child object of the wire while the character is on the wire, and then move the character in local space during that time (e.g. along one of the cardinal axes).

If you want to keep the character in global space though, the same effect can be achieved; you’ll just have to move the character in ‘virtual local space’ or parametric space or something, and then transform the ‘virtual’ position into world space.

(In either case, the details will depend somewhat on how you want the controls to work while the character is on the wire.)

That sounds complicated?

I have made a sample of how my code works:

var charController : CharacterController;

function WalkingOnWire()
{
   var forwardPressed: boolean = Input.GetButton("Forward");
   var backwardPressed: boolean = Input.GetButton("Backward");

   if(forwardPressed  backwardPressed) ; //both pressed, not going anywhere	
   else if(forwardPressed) charController.Move(transform.forward);
   else if(backwardPressed) charController.Move(-transform.forward);
   else ; // nothing is pressed
}

//There is a small invisible box ontop of the wire, it is as long as the wire, so while I am in that box, i will be highWireWalking
function LandedOnWire(wireCollider : Collider)
{

   //the angle between my players facing direction and the wire
   var angleBetween = wireCollider.transform.rotation.eulerAngles.y - transform.rotation.eulerAngles.y;


   //When landing on the vire we have to be sure we are facing the same way as the wire, cannot go left or write on the small wire
   transform.rotation = wireCollider.transform.rotation;		
   if(( angleBetween<270  angleBetween>90) || (angleBetween<-90  angleBetween>-270)){
	transform.Rotate(0,180,0);		
   }

   //Fix the player to the middle of the wire

   //----??????-----
   //----HELP-----
   //----??????-----
}

Each method will be called when needed, all i need is that calculation to fix the player in the middle of the wire =)

Does that code compile? It looks to me like it has syntax errors (and if it does, you’ll probably want to fix that before going any further).

It compiles without a problem for me, you probebly want to make sure you have a input key: “Forward” and “Backward” : p

Naming of input keys isn’t a compilation issue.

Anyway, maybe that compiles in UnityScript (the equivalent code doesn’t compile in C#), so I’ll just assume it does what you intend it to do :slight_smile:

One way to ‘attach’ the player to the wire is to move the player to the closest point on the wire to the player’s current position. This is trivial, and I can show you how to do it if you can provide a little more info.

Specifically, how is the wire oriented and positioned in local space? Is it centered at the transform position and aligned with one of the transform’s local axes? How is its length or extent specified?

  • it is centered at the transform’s position and aligned with the local Z axes
  • Length is specified by sacling

The wire is basiclly just a normal cube

EDIT:
A normal cube made very thin and very long

Ok, I can’t remember off the top of my head if the default Unity cube is 1x1x1 or 2x2x2, but you can check that easily enough. In any case, what you’ll need is the wire’s half-length, or ‘extent’.

First you’ll need a closest-point-on-segment function. Here it is in C# (you can convert it to UnityScript if needed). This will just be typed into the post, so let me know if it doesn’t work as expected or if there are compilation errors:

Vector3 ClosestPointOnSegment(Vector3 p, Vector3 p1, Vector3 p2)
{
    Vector3 diff = p - p1;
    Vector3 direction = p2 - p1;
    float t = Vector3.Dot(diff, direction) / Vector3.Dot(direction, direction);
    t = Mathf.Clamp01(t);
    return p1 + t * direction;
}

To use this function, you’d submit the character’s current position for ‘p’, and the endpoints of the wire for p1 and p2. One way to compute these endpoints is as follows (where ‘transform’ is the transform of the wire object):

Vector3 p1 = transform.position - wireExtent * transform.forward;
Vector3 p2 = transform.position + wireExtent * transform.forward;

That should give you all the information you need to solve the problem, but post back if you have questions.

It works!!!

Thanks alot Jesse Anders ^^

The point it calculated were the position where player should stand on, not the character position, ^^ looks funny when the charater got a wire through him.

Anyway thanks again =)

Right, definitely - if the origin of the player is not roughly between the player’s feet, you’ll have to adjust accordingly :slight_smile: