- Home /
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[i].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
Answer by Spitaris · Dec 18, 2011 at 10:28 AM
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
Thanks for replying. I don't know exactly what you mean. Should I create a new script and then attach it to the player, not altering the camera script?
Thanks again!
You're welcome.
You put this code in the player controller, when you want him to move.
You just need to know the camera and the player, so you can put the script in any Game Object who knows the player and the camera (you can make public variables).
Hey man, I've tried it compiles but I can't play it. It highlights the camera and automatically pauses the game? Any ideas? Thanks!
The code I gave you just transforms the direction to global. Can you give me your controller code please ?
Answer by storm024 · Dec 18, 2011 at 11:42 AM
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!
Unfortunately that doesn't work! The controls become erratic and then the player just falls through the floor! I wish that had have worked though, would have been a great solution! Thanks though.
Answer by pma07pg · Dec 21, 2011 at 06:41 PM
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?
Hum, just send the part you modified. I never seen a game stopping and highligntning an object.
Answer by pma07pg · Dec 22, 2011 at 10:09 PM
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;
Your answer
Follow this Question
Related Questions
Change players state and controls in-game 1 Answer
Camera Follow Player using a path 0 Answers
Player Rotation is snapping 1 Answer
Camera following the player in 3D - in object hirarchy or through scripts? 1 Answer
SideScroller Rotate 1 Answer