Camera and Controls

I’m writing a four player local multiplayer game for a university assignment. The designers have a made a cyclic level so that you begin and finish in the same position and the characters in the game must run through the round level.
However, I have the issue that once the character has reached the first corner of the level and run around it, when the camera rotates behind the player, the controls remain mapped to the world coordinates. Therefore forward will make the character run right for example instead of forward. What is the best way to combat the issue(apart from level redesign!)? Here is a my camera script.

`
////////////////////////////////////////////////////////////////////

//IMPORTANT! Tag ALL players with “Player” so they are recognized.//

////////////////////////////////////////////////////////////////////

var targets : GameObject;

var currentDistance : float;

var largestDistance : float;

var theCamera : Camera;

var height : float ;

var avgDistance;

var distance = 0.0; // Default Distance

var speed = 1;

var offset : float;

//========================================
function Start()

{

	targets = GameObject.FindGameObjectsWithTag("Player");
   }

function LateUpdate ()

{
    targets = GameObject.FindGameObjectsWithTag("Player"); 

    if (!GameObject.FindWithTag("Player"))

    {

    	return;

    }
    var sum = Vector3(0,0,0);	

    for (n = 0; n < targets.length ; n++)

    {

        sum += targets[n].transform.position;	

    }    

     avgDistance = sum / targets.length;	

     var largestDifference = returnLargestDifference();	

     height = Mathf.Lerp(height,largestDifference,Time.deltaTime * 2 * speed);   	

     theCamera.transform.position.x = avgDistance.x;

     theCamera.transform.position.z = avgDistance.z - 3;

     theCamera.transform.position.y = avgDistance.y + 1;	

     theCamera.transform.LookAt(avgDistance);	     

     if(theCamera.transform.position.z > 78)

     {

     	theCamera.transform.rotation = Quaternion.Euler(0,-65,0);

     	theCamera.transform.position.x = theCamera.transform.position.x + 4;

     	theCamera.transform.position.y =  theCamera.transform.position.y;

     	theCamera.transform.position.z =  theCamera.transform.position.z + 2;

     	}    	     

 }


function returnLargestDifference()
   {	

    currentDistance = 0.0;

    largestDistance = 0.0;


    for(var i = 0; i < targets.length; i++)
        {	
        for(var j = 0; j <  targets.length; j++)
          {
            currentDistance = Vector3.Distance(targets*.transform.position,targets[j].transform.position);*
  •           if(currentDistance > largestDistance)*
    

{

  •               largestDistance = currentDistance;*
    
  •           }*
    
  •       }*
    
  •   }*
    
  •   return largestDistance;*
    
  • }*
    The camera zooms in and out depending on the distance that the players are apart.
    If you need any more of the code I’m using I’ll happily post. Any advice/info would be great as this is really annoying me!
    Cheers, Peter

Hello,

You should take take the local position of the camera, make a Vector3 how you want, and then convert it to the global position.

You can use somthing like :

Transform transCamera = camera.transform;

// We make a Vector3 who is the direction in relation with the camera's rotation
Vector3 vectorLocal = new Vector3(1, 0, 0);
// Then, we convert it from his relation with the camera to a relation with the whole world
Vector3 vectorGlobal = transCamera.TransformDirection(vectorLocal);

// Then you apply it to the player

If I weren’t clear enough, tell me, I will try to explain a bit better.

Hoping I helped you,
Spitaris

well I do believe the answer is not in the code, rather a much simpler solution:

you need to make the player object a child of the camera.

simply enter the scene and drag the player into the camera, tell me if it works!

Hey, my controller code is the third person controller that comes with unity. I’ve only modified it slightly to allow for four players instead of just the one. It’s really long so I didn’t want to post it. If you still want to see it then I could email you it perhaps?

Here is the beginning of the code. The only difference is the enumeration and I’ve removed some of the walk and trot animations etc. No other modifications really!

private var _animation : Animation;
//This is where to add the chest animation
enum CharacterState {
Idle = 0,
Running = 1,
Jumping = 2,
}

enum PlayerControls{

P1 = 1,
P2 = 2,
P3 = 3,
P4 = 4
}

public var playerControls : PlayerControls;

private var _characterState : CharacterState;

// pushing a direction on the controller makes the character run
var runSpeed = 6.0;

var inAirControlAcceleration = 3.0;

// How high do we jump when pressing jump and letting go immediately
var jumpHeight = 0.5;

// The gravity for the character
var gravity = 20.0;
// The gravity in controlled descent mode
var speedSmoothing = 10.0;
var rotateSpeed = 300000.0;
var trotAfterSeconds = 3.0;

var canJump = true;

private var jumpRepeatTime = 0.05;
private var jumpTimeout = 0.15;
private var groundedTimeout = 0.25;

// The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around.
private var lockCameraTimer = 0.0;

// The current move direction in x-z
private var moveDirection = Vector3.zero;
// The current vertical speed
private var verticalSpeed = 0.0;
// The current x-z move speed
private var moveSpeed = 0.0;

// The last collision flags returned from controller.Move
private var collisionFlags : CollisionFlags;

// Are we jumping? (Initiated with jump button and not grounded yet)
private var jumping = false;
private var jumpingReachedApex = false;

// Are we moving backwards (This locks the camera to not do a 180 degree spin)
private var movingBack = false;
// Is the user pressing any keys?
private var isMoving = false;
// When did the user start walking (Used for going into trot after a while)
private var walkTimeStart = 0.0;
// Last time the jump button was clicked down
private var lastJumpButtonTime = -10.0;
// Last time we performed a jump
private var lastJumpTime = -1.0;

// the height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
private var lastJumpStartHeight = 0.0;

private var inAirVelocity = Vector3.zero;

private var lastGroundedTime = 0.0;

private var isControllable = true;

function Awake ()
{

moveDirection = transform.TransformDirection(Vector3.forward);

_animation = GetComponent(Animation);
if(!_animation)
	Debug.Log("The character you would like to control doesn't have animations. Moving her might look weird.");

if(!idleAnimation) {
	_animation = null;
	Debug.Log("No idle animation found. Turning off animations.");
}

if(!runAnimation) {
	_animation = null;
	Debug.Log("No run animation found. Turning off animations.");
}
if(!jumpPoseAnimation && canJump) {
	_animation = null;